Runtime Library (pythonlib)
The runtime library provides Python-compatible implementations of standard library modules.
Naming Convention: All function names use camelCase to feel native in TypeScript. For example, Python’s zip_longest becomes zipLongest, and lru_cache becomes lruCache. See ADR-0011 for the complete naming rationale.
Installation
npm install pythonlibImport Architecture
pythonlib uses subpath exports for clean, tree-shakeable imports:
// Builtins from main exportimport { range, enumerate, zip, len, sorted } from "pythonlib"
// Module functions from subpathsimport { chain, combinations } from "pythonlib/itertools"import { Counter, defaultdict } from "pythonlib/collections"import { partial, reduce } from "pythonlib/functools"See ADR-0009 for the architectural rationale.
Builtins (pythonlib)
The main export provides Python’s built-in functions:
import { range, enumerate, zip, len, sum, min, max, sorted, reversed } from "pythonlib"
// Iterationfor (const i of range(10)) {}for (const [i, v] of enumerate(items)) {}for (const [a, b] of zip(list1, list2)) {}
// Built-inslen([1, 2, 3]) // 3sum([1, 2, 3]) // 6min([1, 2, 3]) // 1max([1, 2, 3]) // 3sorted([3, 1, 2]) // [1, 2, 3]reversed([1, 2, 3]) // [3, 2, 1]itertools (pythonlib/itertools)
Iterator building blocks:
import { combinations, permutations, product, chain, groupby, zipLongest, accumulate} from "pythonlib/itertools"
// Combinations & Permutationscombinations([1, 2, 3], 2)// -> [[1,2], [1,3], [2,3]]
permutations([1, 2, 3], 2)// -> [[1,2], [1,3], [2,1], [2,3], [3,1], [3,2]]
// Cartesian productproduct([1, 2], ["a", "b"])// -> [[1,"a"], [1,"b"], [2,"a"], [2,"b"]]
// Chainingchain([1, 2], [3, 4])// -> [1, 2, 3, 4]
// Groupinggroupby([1, 1, 2, 2, 3])// -> [[1, [1,1]], [2, [2,2]], [3, [3]]]
// Zip with fillzipLongest([1, 2, 3], ["a", "b"], { fillvalue: "-" })// -> [[1,"a"], [2,"b"], [3,"-"]]
// Accumulateaccumulate([1, 2, 3, 4, 5])// -> [1, 3, 6, 10, 15]functools (pythonlib/functools)
Higher-order functions:
import { partial, reduce, lruCache, attrGetter, itemGetter } from "pythonlib/functools"
// Partial applicationconst add = (a: number, b: number) => a + bconst add5 = partial(add, 5)add5(3) // -> 8
// Reducereduce((a, b) => a + b, [1, 2, 3, 4, 5])// -> 15
// LRU Cacheconst expensive = lruCache((n: number) => { console.log(`Computing ${n}`) return n * 2})expensive(5) // logs "Computing 5", returns 10expensive(5) // returns 10 (cached, no log)
// Cache infoexpensive.cacheInfo()// -> { hits: 1, misses: 1, maxsize: 128, currsize: 1 }
// Attribute/Item gettersconst getName = attrGetter("name")getName({ name: "John" }) // -> "John"
const getSecond = itemGetter(1)getSecond([10, 20, 30]) // -> 20collections (pythonlib/collections)
Specialized container types:
import { Counter, defaultdict, deque } from "pythonlib/collections"
// Counterconst counter = new Counter("mississippi")counter.get("i") // -> 4counter.get("s") // -> 4counter.mostCommon(2) // -> [["i", 4], ["s", 4]]
// defaultdictconst dd = defaultdict(() => [])dd.get("key").push(1)dd.get("key").push(2)dd.get("key") // -> [1, 2]
// deque (double-ended queue)const d = new deque([1, 2, 3])d.appendLeft(0) // [0, 1, 2, 3]d.append(4) // [0, 1, 2, 3, 4]d.popLeft() // -> 0d.pop() // -> 4datetime (pythonlib/datetime)
Date and time handling:
import { datetime, date, time, timedelta } from "pythonlib/datetime"
const now = datetime.now()now.strftime("%Y-%m-%d %H:%M:%S") // -> "2024-01-15 14:30:45"
const d = new date(2024, 1, 15)const t = new time(14, 30, 45)
// Timedeltaconst delta = new timedelta({ days: 7, hours: 3 })delta.totalSeconds() // -> 615600re (pythonlib/re)
Python-style regex with named groups:
import { search, findAll, split, sub } from "pythonlib/re"
// Searchconst m = search("(?P<name>\\w+)@(?P<domain>\\w+)", "user@example")m?.group("name") // -> "user"m?.group("domain") // -> "example"
// Find allfindAll("\\d+", "a1b2c3") // -> ["1", "2", "3"]
// Splitsplit("[,;]", "a,b;c") // -> ["a", "b", "c"]
// Substitutesub("\\d", "X", "a1b2c3") // -> "aXbXcX"math (pythonlib/math)
Mathematical functions:
import { sqrt, factorial, gcd, lcm, sin, log, pi, e } from "pythonlib/math"
sqrt(16) // -> 4factorial(5) // -> 120gcd(12, 8) // -> 4lcm(4, 6) // -> 12sin(pi / 2) // -> 1log(e) // -> 1random (pythonlib/random)
Random number generation:
import { randInt, choice, shuffle, sample, uniform } from "pythonlib/random"
randInt(1, 10) // Random integer 1-10choice(["a", "b"]) // Random elementshuffle([1, 2, 3]) // Shuffle in placesample([1, 2, 3], 2) // Random sampleuniform(0, 1) // Random float 0-1json (pythonlib/json)
JSON handling (Python-style API):
import { dumps, loads } from "pythonlib/json"
dumps({ a: 1 }) // -> '{"a":1}'loads('{"a":1}') // -> { a: 1 }string (pythonlib/string)
String constants and utilities:
import { asciiLowercase, asciiUppercase, digits, punctuation, capWords, Template} from "pythonlib/string"
asciiLowercase // "abcdefghijklmnopqrstuvwxyz"asciiUppercase // "ABCDEFGHIJKLMNOPQRSTUVWXYZ"digits // "0123456789"punctuation // "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
capWords("hello world") // "Hello World"
// Template stringsconst t = new Template("Hello, $name!")t.substitute({ name: "World" }) // "Hello, World!"