How libraries work
There is no prebuilt runtime library to link against. import math resolves at compile time to pyc_lib/math.py, which is analysed and compiled along with the rest of the program. A function you never call is never emitted, and a library function is specialized for the types your program passes it, exactly like your own code.
The built-in types themselves (str, list, dict, set, exceptions, generators) are also Python, in __pyc__/, on top of a small C runtime.
Real or raise
a function either computes CPython's answer, or it raises the exception CPython would raise for something it cannot do. A stub that returns a plausible made-up value is a silent wrong answer, and silent wrong answers are bugs.
A name that doesn't exist yet is a compile error, never a wrong result.
Modules today
| Module | Status | Covers |
|---|---|---|
math | partial | pi, e, tau, inf; sqrt, exp, log/log2/log10, pow, hypot, fabs, fmod, floor, ceil, trig and hyperbolic functions, radians, degrees Bound straight to libc, so results match CPython's C-backed math. |
random | complete | seed, random, getrandbits, uniform, randrange, randint, choice, shuffle, sample, triangular True MT19937 with CPython’s seeding, so seeded programs match CPython draw for draw. |
collections | partial | deque, defaultdict |
heapq | complete | heappush, heappop, heapreplace, heappushpop, heapify Mirrors CPython's heapq.py. |
itertools | partial | count, product |
functools | partial | reduce |
copy | complete | copy, deepcopy |
re | partial | compile, match, fullmatch, search; classes, groups, alternation, greedy and lazy quantifiers, anchors A backtracking engine written in Python. findall, sub and split are not implemented yet. |
fnmatch | complete | fnmatch, fnmatchcase, filter |
string | complete | ascii_* constants, digits, punctuation, whitespace, printable, capwords |
struct | partial | pack, unpack, unpack_from, calcsize for the integer formats |
array | partial | array with typecode; tobytes/frombytes for integer typecodes |
hashlib | partial | md5 (RFC 1321) The other algorithms raise NotImplementedError. |
colorsys | complete | rgb/yiq/hls/hsv conversions Ported from CPython's colorsys.py. |
getopt | complete | getopt, gnu_getopt, GetoptError Ported from CPython's getopt.py. |
io | partial | StringIO, BytesIO |
sys | partial | argv, exit, maxsize, stdin/stdout/stderr, version, platform, setrecursionlimit |
os | partial | listdir, walk, getcwd, chdir, mkdir, remove, rename, stat, system, path |
time | partial | time, sleep |
socket | partial | socket (bind, listen, accept, recv, send, setsockopt), gethostname |
select | partial | select |
serial | partial | The pyserial API surface Opening a port raises SerialException, as pyserial does for a port it cannot open. |
“Complete” means the commonly used surface of the module is implemented with CPython's behaviour, not that every name in CPython's module exists.
Next up
These are the modules that real programs reach for most often and that pyc does not have yet. Each one is a self-contained contribution.
dataclasses
The idiomatic record type. A natural fit: fields and their types are fixed per class.
enum
Enumerations compile to integers with names, with no run-time cost.
typing
Accept annotations, and in strict mode check them against what inference found.
itertools (complete)
chain, islice, permutations, combinations, groupby, accumulate, zip_longest.
functools (complete)
partial, lru_cache, cache, cmp_to_key, total_ordering.
collections (complete)
Counter, OrderedDict, namedtuple.
re (complete)
findall, finditer, sub, split, named groups, flags.
bisect
Small, pure Python, widely used.
json
Serialization of typed records, and parsing into a declared shape.
asyncio
A CPython-compatible front end for the event loop async/await already compiles to.
pathlib / os.path
Modern file-system access.
statistics, fractions, decimal
Numeric work beyond math.
hashlib (complete)
sha1 and the sha2 family.
unittest
Test the compiled program with the same tests that run under CPython.
Writing a module
A module is a Python file in pyc_lib/. Write it in plain Python wherever possible. Porting CPython's own pure-Python implementation is often the right start. Where you need the C library, bind a function with __pyc_c_call__:
pi = 3.141592653589793
def sqrt(x): return __pyc_c_call__(float, "sqrt", float, x)
def floor(x): ... # returns int, as in CPython 3Then:
- Add tests under
tests/. The harness compares every test's output with CPython's, on both backends. - Check the module under
--strict. It should compile without any accommodation, so that strict programs can use it. - Run
make test.
The runtime guide, RUNTIME.md, has recipes for adding new runtime support.