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.7

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.7
File Size Uploaded
pyturbo_v3-3.0.7.tar.gz 45.4 kB Details

Built distribution (wheel)

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

Total release size: 94.8 kB

Release files / pyturbo_v3-3.0.7.tar.gz

Download URL pyturbo_v3-3.0.7.tar.gz
Size 45.4 kB
Tags Source
SHA-256 checksum
How to use checksums
bda6361d0c2a035adda9dc09f5e62c153e2c946097e8a43ab03fe9ae8557b942
BLAKE2b-256 checksum
How to use checksums
06de5ad77efa91adab55ccbf022f141f3b89d3debea311d858a2690e1e6f6ecb
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.7-py3-none-any.whl

Download URL pyturbo_v3-3.0.7-py3-none-any.whl
Size 49.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c0618858bd6feec7318deee956fe6c79393c1f4efa53d9c7f10ad311f5c55d2c
BLAKE2b-256 checksum
How to use checksums
742aede2536e4f78782ada02e788897758d7247feafc4d9bc5a2d894ea8ab5b8
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

This release

3.0.7 This release

2 release files

3.0.6

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