Requirements
- clang / clang++ with C++23 support, and
llvm-ar - LLVM development libraries, with
llvm-configon yourPATH. The LLVM backend is always built. - Boehm GC (
libgc,libgccpp) - PCRE (
libpcre) - DParser, built with GC support and installed
$ sudo apt-get install clang-20 llvm-20-dev libgc-dev libpcre3-dev$ sudo dnf install clang llvm-devel gc-devel pcre-develCI runs clang/LLVM 20 on Ubuntu 24.04. The unversioned packages there are LLVM 18, whose coroutine ABI breaks the generator and async tests.
Build from source
The IFA analysis library ships inside the repository under ifa/ and is built automatically. Install DParser first:
# 1. DParser, with garbage-collector support
$ git clone https://github.com/jplevyak/dparser.git
$ cd dparser && sudo make install D_USE_GC=1 && cd ..
# 2. pyc
$ git clone https://github.com/jplevyak/pyc.git
$ cd pyc
$ makemake builds ifa/libifa_gc.a, the runtime, and the pyc binary. pyc itself is built at -O3 -march=native by default. For a debuggable compiler, use make clean && make OPTIMIZE=.
The Makefiles track neither, and stale objects produce failures that look like real bugs.
Put pyc on your PATH
pyc finds its builtin library (__pyc__/, pyc_lib/ and the runtime) next to its own executable, following symlinks. A symlink from the checkout is enough:
$ ln -s "$PWD/pyc" ~/.local/bin/pycYou can also name the directory explicitly with -D <dir> or $PYC_SYSTEM_DIRECTORY.
Your first program
def fib(n):
return n if n < 2 else fib(n - 1) + fib(n - 2)
print(fib(35))$ pyc hello.py # writes ./hello (and keeps hello.py.c)
$ ./hello
9227465pyc reads the file and everything it imports, analyzes the whole program, and writes an executable named after the input. Use -o to choose the name. Imports resolve against the current directory, then pyc_lib/, then $PYTHONPATH.
Run scripts with #!
-x compiles once, caches the binary under ~/.cache/pyc, and runs it. A later run whose sources are all unchanged starts the cached executable in a few milliseconds.
#!/usr/bin/env -S pyc -x
import sys
print("hello", sys.argv[1:])$ chmod +x greet.py
$ ./greet.py a b
hello ['a', 'b']JIT and REPL
$ pyc -j program.py # compile with LLVM and run in-process
$ pyc --repl # interactive, backed by the JITVerify the build
make test runs everything CI runs, on both backends, in about four minutes. When it passes, every end-to-end test matched both its expected output and CPython.
$ make testNext: take the tour.