Skip to main content

TurboPython compiler - translates restricted Python-syntax to C++ for ultra-low-latency applications

Project description

TurboPython (TPy)

A compiler that translates Python to C++.

Goals:

  1. Performance — Low-latency compiled output with opt-in constraints for hot paths (e.g. @noalloc). If the goals below conflict, performance wins.
  2. Regular Python compatibility — We aim to compile and run regular Python code whenever possible, with clear diagnostics when a feature is unsupported or when semantics differ from CPython.
  3. Constrained C++ interop — Easy integration with existing C/C++ code, but only through explicitly supported interop shapes and rules (not arbitrary native types/signatures).
  4. Familiar syntax — Keep the language readable for non-programmers and close to regular Python where possible.
  5. Semantic transparency — Warn when TurboPython behavior differs from CPython so differences are explicit during development.
  6. Tooling-friendly — Source files are valid Python, so existing IDEs, linters, type checkers, and LLMs work without special plugins.
  7. Thread safety — Unlike CPython (GIL), TurboPython targets multi-threaded, high-performance environments. The compiler should be thread-safe by default where possible without sacrificing performance, and give the user explicit control where trade-offs exist.

Example

Main differences from CPython:

  • Type annotations required on functions (parameters + return) and class fields; local variables are inferred
  • Int32 for integer literals (overrideable), Int32/Int64 for explicit fixed-width, int = BigInt for arbitrary precision
  • Value types (Int32, bool, str, ...) are copied; reference types (classes, containers) are passed by reference to functions but stored inline in fields and containers. Own[T] transfers ownership (move) at function boundaries
  • No GIL, no refcounting, no GC -- deterministic destruction via RAII
from tpy import Int32

def fib(n: Int32) -> Int32:
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)

for i in range(40):
    print(fib(i))
$ tpy -O fib.py          # compile to C++ and run (optimized)
$ tpy --dump-code fib.py # inspect generated C++

Reference types (classes, list, dict, ...) are passed by reference to functions, but stored inline in class fields and containers. Own[T] marks ownership transfer -- the value is moved, not referenced:

from dataclasses import dataclass
from tpy import Own, Int32

@dataclass
class Event:
    timestamp: Int32
    code: Int32

def make_batch(n: Int32) -> Own[list[Event]]:
    # list comprehension creates a new list; Own means it is moved out to the caller
    return [Event(i, i * 2) for i in range(n)]

batch = make_batch(3)  # batch owns the list (moved, not copied)
for e in batch:
    print(e.timestamp, e.code)

Where TurboPython would silently copy what CPython shares by reference (e.g. storing a parameter into a field or container), the compiler warns and suggests an explicit copy() -- so dual-target code behaves identically under both runtimes.

Source files are valid Python -- your IDE, linter, and type checker work as-is.

Installation

pip install tpy-lang
pip install "tpy-lang[bundled]"   # also installs zig as a bundled C++ compiler

Or as an isolated tool with uv:

uv tool install tpy-lang
uv tool install "tpy-lang[bundled]"

Two commands are installed: tpy (runs programs, drops to a REPL with no args) and tpyc (compile-only; emits .hpp/.cpp).

From source

uv sync                          # in a checkout of the source tree
uv run tpy examples/hello.py

Quick Start

tpy                              # interactive REPL
tpy -c "print(1 + 2)"            # run inline code

Create a hello.py:

def main() -> None:
    print("Hello from TurboPython!")

main()

Then:

tpy hello.py                     # compile and run a file
tpy -O hello.py                  # release build (optimized)
tpy --dump-code hello.py         # inspect generated C++
tpy --cxx list                   # show available C++ compilers
tpy -j4 hello.py                 # parallel compilation (4 jobs)
tpy --install-agent-docs docs/   # install TPy agent docs into your project

tpyc hello.py                    # compile only -- emit .hpp/.cpp into __tpyc__/
tpyc -o out/ hello.py            # compile only, custom output directory

Re-running an unchanged program skips the whole pipeline: after a successful build, tpy records every input (sources, imported modules, compiler and toolchain identity, options) next to the binary and, when nothing changed, executes the binary directly (~100ms startup instead of a rebuild). Anything changed -- a source edit, a new file that shadows an imported module, a compiler upgrade, different flags -- triggers a normal rebuild. --rebuild forces one; it's also the escape hatch for the (ccache-grade) blind spots: system-mode third-party libraries (--pcre2=system etc.) resolve at link time outside the tracked inputs, and compile-affecting environment variables (CPATH, CPLUS_INCLUDE_PATH, LIBRARY_PATH, CCACHE_*) are not part of the key -- after changing either, run once with --rebuild.

A sources.cmake file is generated alongside the C++ output for easy CMake integration. By default, the tpy runtime headers are bundled into the output directory so the result is self-contained and can be committed or copied to another machine. Use --no-bundle-runtime to skip the copy (e.g. during development on the runtime itself).

include(path/to/__tpyc__/myapp.d/sources.cmake)
add_executable(myapp ${TPYC_SOURCES})
target_include_directories(myapp PRIVATE ${TPYC_INCLUDE_DIRS})
target_link_libraries(myapp PRIVATE ${TPYC_LIBRARIES})
set_target_properties(myapp PROPERTIES CXX_STANDARD ${TPYC_CXX_STANDARD})

Coding with an AI agent (recommended)

TurboPython source is valid Python, so coding agents (Claude Code, Cursor, Copilot, ...) and your existing tooling work out of the box. The fastest way to be productive is to hand the agent TPy's rules and exact API surface up front:

tpy --install-agent-docs docs/   # writes TPY_*.md into ./docs and prints a
                                 # snippet to add to your AGENTS.md / CLAUDE.md

This installs four reference files into your project:

  • TPY_FOR_AGENTS.md -- concise Python-to-TPy bootstrap (the delta, ownership rules, idiomatic patterns)
  • TPY_LANGUAGE_FEATURES.md -- full language reference (only Working sections are usable today)
  • TPY_STDLIB_ROADMAP.md -- stdlib coverage (what's available vs missing)
  • TPY_API_REFERENCE.md -- the exact callable API surface, generated from the installed version

Append the printed snippet to your AGENTS.md / CLAUDE.md so the agent reads them before writing TPy code. Re-run after upgrading tpy-lang to refresh.

Dependencies

  • Python 3.12+
  • A C++23 compiler: g++ 13+, clang++ 19+, or zig (auto-detected)

No external C/C++ libraries are required by the runtime.

Development

# Run all tests
uv run pytest

# Run tests for a specific case
uv run pytest -k hello

# View built-in type documentation
uv run tpy --print-types | glow -p

From a source checkout: see docs/ARCHITECTURE.md for the compiler architecture, docs/LANGUAGE_FEATURES.md for the full language reference, and docs/TPY_FOR_AGENTS.md for the agent-facing bootstrap (also installable into your project via tpy --install-agent-docs).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tpy_lang-0.5.0-py3-none-any.whl (6.5 MB view details)

Uploaded Python 3

File details

Details for the file tpy_lang-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: tpy_lang-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 6.5 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tpy_lang-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f5b4d67a00f87f285f17a187a16c95290d2e512aff5c03f29b695b27e9926c28
MD5 ecd6a4240687548dad350d614826ef5e
BLAKE2b-256 602cb454198cebe4bc0744b3327932fda958ddbebfde51aefb426a45cd0f34dd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page