Skip to main content

PyTurbo V3

Python 3.10 to C99 transpiler with CPython API and DCE.

Optimization method: all you can make to C99; the rest through CPython API.

Author: Suleiman License: Apache 2.0 Copyright 2026 Suleiman

QUICK START

pyturbo transpile hello.py -o hello.c -v

Output:

hello.c              C99 + inline CPython declarations (~5 KB)
hello.h              function prototypes
hello.manifest.json  full analysis report

Compile with any C compiler:

gcc -std=c99 hello.c -lpython3.11 -o hello
./hello

Or MinGW, clang, tcc, MSVC. Any of them works.

PLATFORM SUPPORT

Windows 10 / 11 (64-bit)    full support, recommended
Linux / macOS / Android     .c output only (no --min-dll)

PyTurbo V3 is designed and tested for Windows first. The transpiler itself (analyzer, type inference, codegen, DCE) is platform-independent and produces standard C99. The --min-dll feature (isolated pythonXY.dll + UPX) is Windows-only, because it relies on the PE format and Windows DLL loading rules.

On Linux / macOS / Android: - .c and .h output works - --min-dll is a no-op with a warning - link against system libpythonXY.so - example: gcc -shared -fPIC hello.c -lpython3.11 -o hello.so

To enable transpilation on non-Windows platforms, remove or relax the platform guard in pyturbo.py:

# was:
if sys.platform != "win32":
    _fail_os()

# now:
if sys.platform != "win32":
    import warnings
    warnings.warn(
        "PyTurbo: --min-dll is Windows-only; .c output works everywhere"
    )

This is the only change required for .c output on Linux/macOS/Android.

FEATURES

C99 where possible:

numbers                                -> double
arithmetic                             -> native + - * /
for i in range(n)                      -> for (double i = 0; i < n; i += 1)
+=, -=, *=, ...                        -> native
print(x, y)                            -> printf("%g %g\n", x, y)
numeric function parameters            -> unboxed to double
numeric return values                  -> boxed via PyFloat_FromDouble

CPython API fallback:

strings, lists, tuples, dicts
imports, module calls
classes (via type())
exceptions
lambdas

DCE for Python.h:

reads Python.h from the system
extracts only the used prototypes (~15 of ~1800)
inlines them into the .c file
no #include <Python.h>
no -I flag needed
portable .c

DLL isolation on Windows with --min-dll:

detects the running Python version (310, 311, 312, 313, ...)
finds pythonXY.dll
produces an isolated copy next to the .c file
no Visual Studio required
uses a pure-Python PE parser

Then:

cd pyturbo_dist
gcc hello.c -L. -lpython311 -o hello.exe

Or with MSVC, clang, tcc. Any of them.

COMMANDS

pyturbo transpile <file.py> [-o out.c] [-v] [--min-dll] [--as-extension]
pyturbo analyze   <file.py>
pyturbo infer     <file.py>
pyturbo tokens    <file.py>
pyturbo version
pyturbo help

EXAMPLE

import math

def sum_squares(n):
    total = 0
    for i in range(n):
        total += i * i
    return total

def main():
    r = sum_squares(100)
    print("Result:", r)
    print("Sqrt:", math.sqrt(r))

main()

Generated C (excerpt):

PyObject* py_user_sum_squares(PyObject* py_n) {
    double py_n_v = PyFloat_AsDouble(py_n);
    double py_total = (double)((0L));
    for (double py_i = (double)((0));
         py_i < (double)(py_n_v);
         py_i += (double)((1))) {
        py_total += py_i * py_i;
    }
    return PyFloat_FromDouble(py_total);
}

PyObject* py_user_main(void) {
    PyObject* py_r = py_user_sum_squares(PyLong_FromLong(100L));
    double py_r_v = PyFloat_AsDouble(py_r);
    printf("Result: %g\n", py_r_v);

    PyObject* _m = PyImport_ImportModule("math");
    PyObject* _f = PyObject_GetAttrString(_m, "sqrt");
    PyObject* _t = PyObject_Vectorcall(_f, &py_r, 1, NULL);
    double _t_v = PyFloat_AsDouble(_t);
    printf("Sqrt: %g\n", _t_v);

    Py_INCREF(Py_None);
    return Py_None;
}

C EXTENSIONS

PyTurbo output is already a valid C extension. It only lacks the module boilerplate. You can add it manually, or (once --as-extension is implemented) let PyTurbo emit it.

Manual boilerplate (~20 lines):

static PyMethodDef module_methods[] = {
    {"sum_squares", py_user_sum_squares, METH_O, NULL},
    {"main",        py_user_main,        METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef module_def = {
    PyModuleDef_HEAD_INIT,
    "hello",
    NULL,
    -1,
    module_methods
};

PyMODINIT_FUNC PyInit_hello(void) {
    return PyModule_Create(&module_def);
}

Build as an extension:

gcc -shared -fPIC hello.c -lpython3.11 -o hello.so
# or on Windows:
gcc -shared hello.c -L. -lpython311 -o hello.pyd

Import:

python -c "import hello; hello.sum_squares(100)"

What this gives you:

.c size        ~5 KB        (Cython: ~500 KB)
.so size       ~50 KB       (Cython: ~1 MB)
dependencies   0            (Cython: 3)
Python.h       not needed   (Cython: #include <Python.h>)
-I flag        not needed   (Cython: needed)
build time     seconds      (Cython: minutes)
input          .py          (Cython: .pyx)

Limitations compared to Cython:

NumPy          not supported
C++            not supported
cdef class     not supported (classes are built at runtime)
attribute specialization   not supported
object-heavy speed          ~1x (Cython: 2-10x)
ecosystem      none         (Cython: 18 years)

So: PyTurbo is a lightweight alternative to Cython for small, numeric, pure-Python extensions - not a general replacement.

SPEED

Realistic speedup range over CPython: 6x to 50x.

50x     upper bound: fully numeric hot path
6x      lower bound: mixed numeric + object code
~1x     object-heavy code (same as CPython)
<1x     worst case: print(object) in loop, m.f(x) in loop

The 50x figure applies only to numeric code that fully passes try_pure_c99. On object-heavy code PyTurbo emits generic CPython API calls and may be slower than CPython due to repeated ImportModule / GetAttrString.

This is not a bug; it is the boundary of the model: "all you can to C99, the rest through CPython API".

SIZE COMPARISON

feature                PyTurbo V3   Cython       Nuitka
---------------------  -----------  -----------  -----------
input                  .py          .pyx         .py
annotations            not needed   needed       not needed
output                 .c           .c           .c / .exe
.c size                ~5 KB        ~500 KB      ~1 MB
binary                 ~50 KB       ~1 MB        ~5 MB
dependencies           0 (CPython)  3            5
Python.h               inlined      #include     #include
DLL DCE (Windows)      copy + UPX   no           no
works on Android       .c only      no           no
speed (numeric)        ~50x         ~50x         ~1.3x
speed (objects)        ~1x          2-10x        1.3x

PYTURBO VS CYTHON

Cython requires .pyx syntax with cdef, cpdef. PyTurbo accepts pure Python and infers types automatically.

Cython: full plate armor: .pyx, cdef, cpdef broadsword: #include <Python.h> (~1800 prototypes) castle: ~3 MB package, 150,000 lines 500 contributors 18 years old

PyTurbo: t-shirt: pure .py scalpel: inline Python.h (~15 prototypes) laptop: 34 KB, ~3200 lines 1 author brand new

Both produce fast C. Both are peers in the same category. Different eras, different styles.

Where PyTurbo wins:

input is pure .py (no .pyx)
.c is ~100x smaller
no #include <Python.h>
no -I flag
0 dependencies
build time: seconds
Windows distribution with isolated UPX-compressed DLL
.c output works on Linux / macOS / Android

Where Cython wins:

NumPy integration
C++ integration
cdef class (real C types)
attribute / method specialization
object-heavy speed (2-10x)
production ecosystem (18 years, 500 contributors)

PYTURBO VS NUITKA

Nuitka compiles for packaging (.exe). PyTurbo focuses on generating minimal C with DCE.

Nuitka pulls in the full Python runtime. PyTurbo removes unused declarations and inlines only the needed ~15 prototypes directly into the .c file.

DCE

Cython and Nuitka both require #include <Python.h> and pull in all ~1800 prototypes.

PyTurbo removes unused declarations and inlines only the needed ~15 prototypes directly into the .c file.

On Windows with --min-dll, PyTurbo also isolates pythonXY.dll next to the .c file, so the .exe loads our copy first (Windows side-by-side rule).

No Visual Studio required. Uses a pure-Python PE parser.

Note: the PE parser (pe_parser.py) is Windows-only by design. It reads PE files, not ELF. It is not needed for .c output; it is only used by --min-dll.

WHY PYTURBO

Not a new category. A minimal implementation in an existing category.

Category: Python-to-C transpilers. Peers: Cython, Nuitka.

PyTurbo is the best when you want:

pure Python input, no annotations
tiny .c (5 KB)
no -I flag
no #include <Python.h>
0 dependencies
small C extensions (~50 KB .so)
minimal Windows distribution (isolated DLL + UPX)
.c output on Linux / macOS / Android
fast build cycle (seconds)

Cython is the best when you want:

numpy integration
C++ integration
maximum speed with annotations
cdef class
production ecosystem

Nuitka is the best when you want:

.exe packaging
full Python compatibility
no annotations needed

HONEST LIMITATIONS

Windows is the primary platform.
    --min-dll, pe_parser.py, dll_decreaser.py, embed.py
    are Windows-only. The transpiler core is portable,
    but pyturbo.py currently blocks non-Windows at startup.
    Remove the platform guard to enable .c output elsewhere.

No NumPy.
    PyTurbo does not understand ndarray, memoryview, or
    buffer protocols. numpy calls go through CPython API.

No C++.
    PyTurbo emits C99 only.

Classes are dynamic.
    class Foo: is built at runtime via PyType_Type.
    It is not a real C type.

Object-heavy code is not faster.
    print(obj), m.f(x), obj.attr in loops may be slower
    than CPython due to repeated ImportModule / GetAttrString.

Half of Python syntax is not implemented.
    Missing: with, try, raise, lambda, yield, await,
    decorators, f-strings, match. These are not C99
    limitations - they are unimplemented in codegen.py.

DCE reads Python.h from the system.
    It is needed at transpile time, not at compile time.
    Without it, PyTurbo falls back to a hardcoded set
    of ~80 prototypes.

--as-extension is not implemented yet.
    Output is a standalone .exe (with main()).
    To build a C extension, add the module boilerplate
    manually (see C EXTENSIONS section).

LICENSE

Apache License 2.0. See LICENSE.txt.

Metadata

Release files for pyturbo-v3 3.0.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyturbo-v3 3.0.6
File Size Uploaded
pyturbo_v3-3.0.6.tar.gz 44.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyturbo-v3 3.0.6
File Interpreter ABI Platform
pyturbo_v3-3.0.6-py3-none-any.whl Python 3 none any Details

Total release size: 93.9 kB

Release files / pyturbo_v3-3.0.6.tar.gz

Download URL pyturbo_v3-3.0.6.tar.gz
Size 44.9 kB
Tags Source
SHA-256 checksum
How to use checksums
64b191ed577454a34bc4951f91f3fa25ae88c5b0d96518a62e2fd226ec6ba0ff
BLAKE2b-256 checksum
How to use checksums
b7ecf64c99fbb4f384de01c213651739b59f0b8c99d6efb26a4ce632b9417918
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.13

Release files / pyturbo_v3-3.0.6-py3-none-any.whl

Download URL pyturbo_v3-3.0.6-py3-none-any.whl
Size 49.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
067f41e5147fc25899c6bb7e717a480a9dd60baebf6e8c7461dd02410eba9365
BLAKE2b-256 checksum
How to use checksums
29ff4b2a6447bbcd0486bc8fc9c76f76cf05abf2fce20fe9fca151dbf01f04d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.13

Release history Release notifications | RSS feed

3.1.1

2 release files

3.1.0

2 release files

3.0.9

2 release files

3.0.8

2 release files

3.0.7

2 release files

This release

3.0.6 This release

2 release files

3.0.5

2 release files

3.0.4

2 release files

3.0.3

2 release files

3.0.2

2 release files

3.0.1

2 release files

3.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page