# Py2Native A Python-to-native compiler that compiles your proprietary Python files to C via Cython, then links them into a single native executable (or shared library). All libraries are kept as they are (eg plain Python) inside a managed `uv` environment — only your code is compiled. ## Links - [llms-full.txt](llms-full.txt) — complete documentation of the published interfaces (CLI, runtime API, build artifacts, HTTP API) ## Product tiers | Tier | Package | License | Key differences | |------------|-----------------|------------|-----------------------------------------------| | Community | `py2native` | MIT | Full compilation, `uv` embedding, cross-platform | | Pro | `py2nativepro` | Proprietary| JWT license verification, string compression | ## Repository layout ``` py2native/ ├── py2native/ # Open-source compiler (MIT) │ ├── pyproject.toml │ ├── README.md │ └── src/py2native/ │ ├── cli.py # CLI entry point: `py2native build ...` │ ├── build.py # Build orchestrator (glob sources, call compiler/embed/whl) │ ├── compiler.py # Cython invocation, C compilation, linking │ ├── embed.py # --embed: creates uv-managed deployment directory │ ├── whl.py # --wheel: creates PEP 427 wheel with compiled .pyd/.so │ ├── templates.py # Cython bootstrap/header templates (code generation) │ ├── plugin.py # PluginManager: dispatches to platform + pro plugins │ ├── runtime.py # Locates CPython shared library for linking │ ├── pristine.py # Manages pristine Python venv for compilation │ ├── utils.py # Shared utilities (getBuildPath, pythonCall, template) │ ├── winplatform.py # Windows: compiler flags, PE linking, .pyd naming │ ├── linuxplatform.py # Linux: ELF linking, auditwheel repair, .so naming │ └── macplatform.py # macOS: Mach-O linking, .dylib naming │ ├── py2nativetest/ # Test project showing Pro Edition features ├── smoketest.py # Build with smoke test ``` ## Architecture ### Compilation pipeline ``` uv run py2native build main.py *.py [--library] [--embed ] [--wheel ] ``` 1. **Glob sources** — `build.py` expands glob patterns under `--base` 2. **Plugin dispatch** — `pluginManager.extendBuild(args)` runs Pro license checks 3. **Cython → C** — `compiler.py` generates a `bootstrap.pyx` from `templates.py`, invokes Cython (`--embed --shared --embed-modules`), then compiles all `.pyx` files to C 4. **C → objects** — `getCompiler()` (setuptools distutils) compiles `.c` files with platform flags 5. **Link** — `link_shared_object()` for library mode, `link_executable()` for exe mode 6. **Wheel (optional)** — `whl.py` creates a PEP 427 wheel with the compiled `.pyd`/`.so` 7. **Embed (optional)** — `embed.py` creates a `uv`-managed deployment directory ### Library mode (`--library`) Creates a shared library (`.pyd`/`.so`/`.dylib`) instead of an executable. The output wheel contains: - A single compiled shared library (contains all modules) - `__init__.py` — meta-path finder that redirects `import mypkg.submodule` to the shared lib - `__main__.py` — enables `python -m mypkg` Both files are **required**: `__init__.py` bridges Python's import system to the native library; `__main__.py` provides the runnable entry point. ### Plugin system `pluginManager` (`plugin.py`) dynamically loads plugins by module name: | Plugin module | Role | |--------------------|-------------------------------------------| | `py2nativepro` | JWT license verification, string compression, keygen/sign/show CLI commands | | `.winplatform` | Windows-specific compile/link flags | | `.linuxplatform` | Linux-specific compile/link flags, auditwheel repair | | `.macplatform` | macOS-specific compile/link flags | Plugins extend the build through lifecycle hooks: `extendBuildParser()`, `extendBuild()`, `extendCompiler()`, `extendTemplate()`, `getCompileLibArgs()`, `getLinkerArgs()`, `getExecutableName()`, `getRuntimeLibraries()`, `auditWheel()`. ### Pro plugin (`py2nativepro`) The closed-source Pro plugin adds: - **`uv run py2native keygen`** — generates EC P-256 keypair (`private.pem`, `public.pem`) - **`uv run py2native sign`** — signs a JWT payload with the private key → `license.dat` - **`uv run py2native show`** — displays JWT claims (optionally verifies signature against public key) - **`--license`** flag on `build` — requires a valid Pro license (JWT, searched in: CLI flag → `PY2NATIVE_LICENSE` env → `~/.py2native/license.dat`) - **`--public`** flag on `build` — embeds a PEM public key into the compiled binary for runtime JWT verification via the `py2native_runtime` API - **String compression** — sets `CYTHON_COMPRESS_STRINGS=90`, making string literals less readable in the compiled binary License verification at build time: decodes the JWT payload, checks `withRuntimeJwt` and `withStringCompression` claims, and enables corresponding features. ### Runtime API Include a .pxd file (with the same name as the module you are checking the jwt) ```` # .pxd from _p2n_bootstrap cimport _runtime_verify_es256_jwt ```` And in module: ```` # Decode licenseString (JWT) to dict try: # Handle verification with embedded key license = _runtime_verify_es256_jwt(licenseString, issue, aaudience) except NameError: # Handle dummy verification (json.loads) when software is not compiled import base64 import json license = json.loads(base64.b64decode(licenseString.split(".")[1]+"===")) ```` * Your code can verify the license end adapt its operation accordingly ## Notes: * Only the public key is stored in the executable * The elliptic key verification is handled with compiled code in our software (ie no 3rd party libraries) ## CLI reference ``` uv run py2native build [--embed ] [--wheel ] [--library] [--base ] [--no-console] [--license ] [--public ] ... uv run py2native keygen # Pro only uv run py2native sign --private # Pro only uv run py2native show [--public ] # Pro only ``` ## Requirements - CPython 3.11–3.15 (including free-threaded 3.14t & 3.15t) - Platform C compiler/linker (MSVC on Windows, GCC on Linux, Clang on macOS) - Windows 8+, manylinux2014/musl Linux, or macOS - x86-64 or ARM64 CPU - Internet access (downloads Python distributions and libraries) ## Dependencies (open-source core) - `cython >= 3.2.4` — Python-to-C transpiler - `setuptools >= 82.0.1` — provides the distutils C compiler interface - `uv >= 0.11.8` — package manager for the embedded environment - `auditwheel >= 6.6.0` (Linux only) — repairs wheels for manylinux compliance ## Known constraints - No modules with identical names across source files - Monkey-patching is still possible (third-party libraries remain as Python source) - LGPL libraries remain replaceable by the end user (compliance) - `__init__.py` is skipped during compilation (it's a namespace marker, not compilable code) - In library mode, `__main__.py` is excluded from sources (it's generated by the wheel builder)