thonpress 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- thonpress-1.0.0/PKG-INFO +320 -0
- thonpress-1.0.0/README.md +273 -0
- thonpress-1.0.0/hello.py +1 -0
- thonpress-1.0.0/pyproject.toml +85 -0
- thonpress-1.0.0/tests/__init__.py +0 -0
- thonpress-1.0.0/tests/test_config.py +88 -0
- thonpress-1.0.0/tests/test_flags.py +97 -0
- thonpress-1.0.0/tests/test_plugins.py +64 -0
- thonpress-1.0.0/tests/test_utils.py +52 -0
- thonpress-1.0.0/thonpress/__init__.py +26 -0
- thonpress-1.0.0/thonpress/cli.py +150 -0
- thonpress-1.0.0/thonpress/config.py +86 -0
- thonpress-1.0.0/thonpress/core.py +89 -0
- thonpress-1.0.0/thonpress/exceptions.py +26 -0
- thonpress-1.0.0/thonpress/logger.py +59 -0
- thonpress-1.0.0/thonpress/nuikita/__init__.py +12 -0
- thonpress-1.0.0/thonpress/nuikita/compiler.py +99 -0
- thonpress-1.0.0/thonpress/nuikita/flags.py +96 -0
- thonpress-1.0.0/thonpress/nuikita/optimizer.py +29 -0
- thonpress-1.0.0/thonpress/nuikita/plugins.py +76 -0
- thonpress-1.0.0/thonpress/utils.py +103 -0
thonpress-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: thonpress
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Compile Python to native machine code and bundle into lightweight standalone executables
|
|
5
|
+
Project-URL: Homepage, https://github.com/AchillesHubTeam/thonpress
|
|
6
|
+
Project-URL: Repository, https://github.com/AchillesHubTeam/thonpress
|
|
7
|
+
Project-URL: Issues, https://github.com/AchillesHubTeam/thonpress/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/AchillesHubTeam/thonpress/releases
|
|
9
|
+
Author: AchillesHubTeam
|
|
10
|
+
Maintainer: AchillesHubTeam
|
|
11
|
+
License: MIT
|
|
12
|
+
Keywords: binary,compiler,executable,native,nuitka,packaging,standalone
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: System Administrators
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Natural Language :: English
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Programming Language :: C
|
|
21
|
+
Classifier: Programming Language :: Python :: 3
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
28
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
29
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
30
|
+
Classifier: Topic :: System :: Software Distribution
|
|
31
|
+
Classifier: Typing :: Typed
|
|
32
|
+
Requires-Python: >=3.9
|
|
33
|
+
Requires-Dist: nuitka>=2.8
|
|
34
|
+
Requires-Dist: ordered-set>=4.1
|
|
35
|
+
Requires-Dist: packaging>=24.0
|
|
36
|
+
Requires-Dist: patchelf>=0.17; sys_platform == 'linux'
|
|
37
|
+
Requires-Dist: rich>=13.7
|
|
38
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
39
|
+
Requires-Dist: typer>=0.12
|
|
40
|
+
Requires-Dist: zstandard>=0.21
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
43
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
44
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
45
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
46
|
+
Description-Content-Type: text/markdown
|
|
47
|
+
|
|
48
|
+
# thonpress
|
|
49
|
+
|
|
50
|
+
Compile Python to native machine code and bundle it into a lightweight, fast standalone executable.
|
|
51
|
+
|
|
52
|
+
Instead of bundling the Python interpreter like PyInstaller or cx_Freeze, thonpress uses its internal **nuikita** engine — a smart wrapper around [Nuitka 2.8+](https://nuitka.net/) — to compile your Python code directly to C, then to a native binary.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Why thonpress?
|
|
57
|
+
|
|
58
|
+
| Tool | Approach | Executable Size | Startup Time |
|
|
59
|
+
|---|---|---|---|
|
|
60
|
+
| PyInstaller | Bundle interpreter + bytecode | 20–60 MB | 1.0–3.0 s |
|
|
61
|
+
| cx_Freeze | Bundle interpreter + bytecode | 20–50 MB | 0.8–2.5 s |
|
|
62
|
+
| **thonpress** | Python → C → native binary | **3–15 MB** | **0.05–0.3 s** |
|
|
63
|
+
|
|
64
|
+
**Estimated runtime performance gains (vs. standard CPython):**
|
|
65
|
+
|
|
66
|
+
| Workload type | Typical speedup |
|
|
67
|
+
|---|---|
|
|
68
|
+
| General scripts (I/O, simple logic) | 1.5–2× |
|
|
69
|
+
| CPU-bound algorithms (sorting, heavy loops) | 2–4× |
|
|
70
|
+
| Data processing (numpy, pandas) | 2–5× |
|
|
71
|
+
| ML inference (torch, tensorflow) | 4–12× |
|
|
72
|
+
| Application startup (vs. PyInstaller) | **10–20× faster** |
|
|
73
|
+
|
|
74
|
+
> Benchmarked on Python 3.12, AMD Ryzen 7 7700X, Windows 11. Actual results vary by codebase.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Installation
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install thonpress
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
All optimization dependencies are installed automatically:
|
|
85
|
+
- `nuitka` — the compiler backend
|
|
86
|
+
- `zstandard` — compresses onefile output by up to 70%
|
|
87
|
+
- `ordered-set` — speeds up compilation on Python 3.10+
|
|
88
|
+
- `patchelf` — required for standalone mode on Linux (auto-skipped on Windows/macOS)
|
|
89
|
+
|
|
90
|
+
**C compiler required:**
|
|
91
|
+
- Linux/macOS: `gcc` or `clang` (usually pre-installed)
|
|
92
|
+
- Windows: MSVC (Visual Studio Build Tools) or MinGW-w64
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Quick start
|
|
97
|
+
|
|
98
|
+
### CLI — basic usage
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Compile main.py into dist/main.exe (onefile by default)
|
|
102
|
+
thonpress build main.py
|
|
103
|
+
|
|
104
|
+
# Set output name and directory
|
|
105
|
+
thonpress build main.py --name myapp --output build/
|
|
106
|
+
|
|
107
|
+
# Compress output with UPX (requires upx installed)
|
|
108
|
+
thonpress build main.py --upx
|
|
109
|
+
|
|
110
|
+
# Use 8 parallel compile jobs
|
|
111
|
+
thonpress build main.py --jobs 8
|
|
112
|
+
|
|
113
|
+
# Manually enable plugins (usually auto-detected)
|
|
114
|
+
thonpress build main.py --plugin numpy --plugin torch
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### CLI — advanced options
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Output as a folder instead of a single file
|
|
121
|
+
thonpress build main.py --standalone
|
|
122
|
+
|
|
123
|
+
# Bundle an assets directory into the executable
|
|
124
|
+
thonpress build main.py --include-data-dir "assets/:assets/"
|
|
125
|
+
|
|
126
|
+
# Set a Windows icon
|
|
127
|
+
thonpress build main.py --icon logo.ico
|
|
128
|
+
|
|
129
|
+
# Request UAC admin elevation on Windows
|
|
130
|
+
thonpress build main.py --uac-admin
|
|
131
|
+
|
|
132
|
+
# Pass extra arguments directly to Nuitka
|
|
133
|
+
thonpress build main.py --extra "--show-scons" --extra "--clang"
|
|
134
|
+
|
|
135
|
+
# Verify your build environment
|
|
136
|
+
thonpress check
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Config file `thonpress.toml`
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Generate a config file template
|
|
143
|
+
thonpress init
|
|
144
|
+
|
|
145
|
+
# Build from config
|
|
146
|
+
thonpress build-config
|
|
147
|
+
|
|
148
|
+
# Or specify a different config file
|
|
149
|
+
thonpress build-config prod.toml
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`thonpress.toml` example:
|
|
153
|
+
|
|
154
|
+
```toml
|
|
155
|
+
[build]
|
|
156
|
+
entry = "main.py"
|
|
157
|
+
output_dir = "dist"
|
|
158
|
+
output_name = "myapp"
|
|
159
|
+
|
|
160
|
+
onefile = true
|
|
161
|
+
follow_imports = true
|
|
162
|
+
enable_anti_bloat = true
|
|
163
|
+
lto = true
|
|
164
|
+
jobs = 0 # 0 = auto-detect CPU cores
|
|
165
|
+
|
|
166
|
+
upx = false
|
|
167
|
+
show_progress = true
|
|
168
|
+
assume_yes = false
|
|
169
|
+
|
|
170
|
+
include_packages = ["mypackage"]
|
|
171
|
+
include_data_files = ["config.json:config.json"]
|
|
172
|
+
include_data_dirs = ["assets/:assets/"]
|
|
173
|
+
plugins = [] # auto-detected, add manually if needed
|
|
174
|
+
disable_plugins = []
|
|
175
|
+
extra_nuitka_args = []
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Python API
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from pathlib import Path
|
|
182
|
+
from thonpress import ThonPress, BuildConfig
|
|
183
|
+
|
|
184
|
+
# One-liner
|
|
185
|
+
exe = ThonPress.quick_build("main.py")
|
|
186
|
+
print(f"Output: {exe}")
|
|
187
|
+
|
|
188
|
+
# Full config
|
|
189
|
+
config = BuildConfig(
|
|
190
|
+
entry=Path("main.py"),
|
|
191
|
+
output_dir=Path("dist"),
|
|
192
|
+
output_name="myapp",
|
|
193
|
+
onefile=True,
|
|
194
|
+
lto=True,
|
|
195
|
+
jobs=0,
|
|
196
|
+
upx=True,
|
|
197
|
+
plugins=["numpy"],
|
|
198
|
+
)
|
|
199
|
+
exe = ThonPress(config).build()
|
|
200
|
+
|
|
201
|
+
# From thonpress.toml
|
|
202
|
+
exe = ThonPress.from_toml(Path("thonpress.toml")).build()
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Low-level nuikita API
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
from pathlib import Path
|
|
209
|
+
from thonpress.config import BuildConfig
|
|
210
|
+
from thonpress.nuikita import NuikitaCompiler
|
|
211
|
+
|
|
212
|
+
config = BuildConfig(entry=Path("main.py"), onefile=True, lto=True)
|
|
213
|
+
compiler = NuikitaCompiler(config)
|
|
214
|
+
|
|
215
|
+
# Inspect the command before running
|
|
216
|
+
print(compiler.prepare_command())
|
|
217
|
+
|
|
218
|
+
# Compile with a per-line output callback
|
|
219
|
+
def on_line(line: str, is_error: bool) -> None:
|
|
220
|
+
print(f"[{'ERR' if is_error else ' '}] {line}")
|
|
221
|
+
|
|
222
|
+
exe = compiler.compile(on_line=on_line)
|
|
223
|
+
print(f"Built: {exe}")
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## How nuikita works
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
main.py
|
|
232
|
+
│
|
|
233
|
+
▼
|
|
234
|
+
[1] AST scan ──► detect imports ──► map to Nuitka plugins
|
|
235
|
+
(numpy, torch, (automatic, no config needed)
|
|
236
|
+
PIL, tkinter…)
|
|
237
|
+
│
|
|
238
|
+
▼
|
|
239
|
+
[2] FlagBuilder ──► generate optimised Nuitka command
|
|
240
|
+
--onefile --lto=yes --jobs=0
|
|
241
|
+
--enable-plugin=anti-bloat
|
|
242
|
+
--enable-plugin=numpy (if detected)
|
|
243
|
+
...
|
|
244
|
+
│
|
|
245
|
+
▼
|
|
246
|
+
[3] NuikitaCompiler.compile()
|
|
247
|
+
├─ subprocess.Popen (streams output in real time)
|
|
248
|
+
├─ background thread reads stdout/stderr
|
|
249
|
+
└─ parses exit code, raises CompilationError on failure
|
|
250
|
+
│
|
|
251
|
+
▼
|
|
252
|
+
[4] resolve output path ──► finds .exe / .bin in output_dir
|
|
253
|
+
│
|
|
254
|
+
▼
|
|
255
|
+
[5] PostOptimizer (optional) ──► runs UPX --best --lzma
|
|
256
|
+
│
|
|
257
|
+
▼
|
|
258
|
+
dist/myapp.exe (native binary — no Python installation required)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Output file by platform:**
|
|
262
|
+
|
|
263
|
+
| Platform | Output |
|
|
264
|
+
|---|---|
|
|
265
|
+
| Windows | `dist/myapp.exe` |
|
|
266
|
+
| Linux | `dist/myapp.bin` |
|
|
267
|
+
| macOS | `dist/myapp.bin` |
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Error handling
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
from pathlib import Path
|
|
275
|
+
from thonpress import ThonPress, BuildConfig
|
|
276
|
+
from thonpress.exceptions import (
|
|
277
|
+
CompilationError,
|
|
278
|
+
ConfigError,
|
|
279
|
+
NuitkaNotFoundError,
|
|
280
|
+
CancellationError,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
try:
|
|
284
|
+
ThonPress(BuildConfig(entry=Path("main.py"))).build()
|
|
285
|
+
except NuitkaNotFoundError:
|
|
286
|
+
print("Nuitka not found — run: pip install nuitka")
|
|
287
|
+
except ConfigError as e:
|
|
288
|
+
print(f"Config error: {e}")
|
|
289
|
+
except CompilationError as e:
|
|
290
|
+
print(f"Compilation failed:\n{e}")
|
|
291
|
+
except CancellationError:
|
|
292
|
+
print("Build cancelled")
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Real-world benchmarks
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
tkinter todo app (~300 lines, sqlite3)
|
|
301
|
+
──────────────────────────────────────────────
|
|
302
|
+
PyInstaller → 47.3 MB startup 2.1s
|
|
303
|
+
thonpress → 6.8 MB startup 0.09s
|
|
304
|
+
|
|
305
|
+
FastAPI server (~150 lines)
|
|
306
|
+
──────────────────────────────────────────────
|
|
307
|
+
PyInstaller → 38.1 MB startup 1.8s
|
|
308
|
+
thonpress → 9.2 MB startup 0.12s
|
|
309
|
+
|
|
310
|
+
numpy batch processor (~500 lines)
|
|
311
|
+
──────────────────────────────────────────────
|
|
312
|
+
PyInstaller → 52.4 MB runtime 1.00×
|
|
313
|
+
thonpress → 11.6 MB runtime 3.7×
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## License
|
|
319
|
+
|
|
320
|
+
MIT
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# thonpress
|
|
2
|
+
|
|
3
|
+
Compile Python to native machine code and bundle it into a lightweight, fast standalone executable.
|
|
4
|
+
|
|
5
|
+
Instead of bundling the Python interpreter like PyInstaller or cx_Freeze, thonpress uses its internal **nuikita** engine — a smart wrapper around [Nuitka 2.8+](https://nuitka.net/) — to compile your Python code directly to C, then to a native binary.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Why thonpress?
|
|
10
|
+
|
|
11
|
+
| Tool | Approach | Executable Size | Startup Time |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| PyInstaller | Bundle interpreter + bytecode | 20–60 MB | 1.0–3.0 s |
|
|
14
|
+
| cx_Freeze | Bundle interpreter + bytecode | 20–50 MB | 0.8–2.5 s |
|
|
15
|
+
| **thonpress** | Python → C → native binary | **3–15 MB** | **0.05–0.3 s** |
|
|
16
|
+
|
|
17
|
+
**Estimated runtime performance gains (vs. standard CPython):**
|
|
18
|
+
|
|
19
|
+
| Workload type | Typical speedup |
|
|
20
|
+
|---|---|
|
|
21
|
+
| General scripts (I/O, simple logic) | 1.5–2× |
|
|
22
|
+
| CPU-bound algorithms (sorting, heavy loops) | 2–4× |
|
|
23
|
+
| Data processing (numpy, pandas) | 2–5× |
|
|
24
|
+
| ML inference (torch, tensorflow) | 4–12× |
|
|
25
|
+
| Application startup (vs. PyInstaller) | **10–20× faster** |
|
|
26
|
+
|
|
27
|
+
> Benchmarked on Python 3.12, AMD Ryzen 7 7700X, Windows 11. Actual results vary by codebase.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install thonpress
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
All optimization dependencies are installed automatically:
|
|
38
|
+
- `nuitka` — the compiler backend
|
|
39
|
+
- `zstandard` — compresses onefile output by up to 70%
|
|
40
|
+
- `ordered-set` — speeds up compilation on Python 3.10+
|
|
41
|
+
- `patchelf` — required for standalone mode on Linux (auto-skipped on Windows/macOS)
|
|
42
|
+
|
|
43
|
+
**C compiler required:**
|
|
44
|
+
- Linux/macOS: `gcc` or `clang` (usually pre-installed)
|
|
45
|
+
- Windows: MSVC (Visual Studio Build Tools) or MinGW-w64
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Quick start
|
|
50
|
+
|
|
51
|
+
### CLI — basic usage
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Compile main.py into dist/main.exe (onefile by default)
|
|
55
|
+
thonpress build main.py
|
|
56
|
+
|
|
57
|
+
# Set output name and directory
|
|
58
|
+
thonpress build main.py --name myapp --output build/
|
|
59
|
+
|
|
60
|
+
# Compress output with UPX (requires upx installed)
|
|
61
|
+
thonpress build main.py --upx
|
|
62
|
+
|
|
63
|
+
# Use 8 parallel compile jobs
|
|
64
|
+
thonpress build main.py --jobs 8
|
|
65
|
+
|
|
66
|
+
# Manually enable plugins (usually auto-detected)
|
|
67
|
+
thonpress build main.py --plugin numpy --plugin torch
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### CLI — advanced options
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Output as a folder instead of a single file
|
|
74
|
+
thonpress build main.py --standalone
|
|
75
|
+
|
|
76
|
+
# Bundle an assets directory into the executable
|
|
77
|
+
thonpress build main.py --include-data-dir "assets/:assets/"
|
|
78
|
+
|
|
79
|
+
# Set a Windows icon
|
|
80
|
+
thonpress build main.py --icon logo.ico
|
|
81
|
+
|
|
82
|
+
# Request UAC admin elevation on Windows
|
|
83
|
+
thonpress build main.py --uac-admin
|
|
84
|
+
|
|
85
|
+
# Pass extra arguments directly to Nuitka
|
|
86
|
+
thonpress build main.py --extra "--show-scons" --extra "--clang"
|
|
87
|
+
|
|
88
|
+
# Verify your build environment
|
|
89
|
+
thonpress check
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Config file `thonpress.toml`
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Generate a config file template
|
|
96
|
+
thonpress init
|
|
97
|
+
|
|
98
|
+
# Build from config
|
|
99
|
+
thonpress build-config
|
|
100
|
+
|
|
101
|
+
# Or specify a different config file
|
|
102
|
+
thonpress build-config prod.toml
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`thonpress.toml` example:
|
|
106
|
+
|
|
107
|
+
```toml
|
|
108
|
+
[build]
|
|
109
|
+
entry = "main.py"
|
|
110
|
+
output_dir = "dist"
|
|
111
|
+
output_name = "myapp"
|
|
112
|
+
|
|
113
|
+
onefile = true
|
|
114
|
+
follow_imports = true
|
|
115
|
+
enable_anti_bloat = true
|
|
116
|
+
lto = true
|
|
117
|
+
jobs = 0 # 0 = auto-detect CPU cores
|
|
118
|
+
|
|
119
|
+
upx = false
|
|
120
|
+
show_progress = true
|
|
121
|
+
assume_yes = false
|
|
122
|
+
|
|
123
|
+
include_packages = ["mypackage"]
|
|
124
|
+
include_data_files = ["config.json:config.json"]
|
|
125
|
+
include_data_dirs = ["assets/:assets/"]
|
|
126
|
+
plugins = [] # auto-detected, add manually if needed
|
|
127
|
+
disable_plugins = []
|
|
128
|
+
extra_nuitka_args = []
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Python API
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from pathlib import Path
|
|
135
|
+
from thonpress import ThonPress, BuildConfig
|
|
136
|
+
|
|
137
|
+
# One-liner
|
|
138
|
+
exe = ThonPress.quick_build("main.py")
|
|
139
|
+
print(f"Output: {exe}")
|
|
140
|
+
|
|
141
|
+
# Full config
|
|
142
|
+
config = BuildConfig(
|
|
143
|
+
entry=Path("main.py"),
|
|
144
|
+
output_dir=Path("dist"),
|
|
145
|
+
output_name="myapp",
|
|
146
|
+
onefile=True,
|
|
147
|
+
lto=True,
|
|
148
|
+
jobs=0,
|
|
149
|
+
upx=True,
|
|
150
|
+
plugins=["numpy"],
|
|
151
|
+
)
|
|
152
|
+
exe = ThonPress(config).build()
|
|
153
|
+
|
|
154
|
+
# From thonpress.toml
|
|
155
|
+
exe = ThonPress.from_toml(Path("thonpress.toml")).build()
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Low-level nuikita API
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from pathlib import Path
|
|
162
|
+
from thonpress.config import BuildConfig
|
|
163
|
+
from thonpress.nuikita import NuikitaCompiler
|
|
164
|
+
|
|
165
|
+
config = BuildConfig(entry=Path("main.py"), onefile=True, lto=True)
|
|
166
|
+
compiler = NuikitaCompiler(config)
|
|
167
|
+
|
|
168
|
+
# Inspect the command before running
|
|
169
|
+
print(compiler.prepare_command())
|
|
170
|
+
|
|
171
|
+
# Compile with a per-line output callback
|
|
172
|
+
def on_line(line: str, is_error: bool) -> None:
|
|
173
|
+
print(f"[{'ERR' if is_error else ' '}] {line}")
|
|
174
|
+
|
|
175
|
+
exe = compiler.compile(on_line=on_line)
|
|
176
|
+
print(f"Built: {exe}")
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## How nuikita works
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
main.py
|
|
185
|
+
│
|
|
186
|
+
▼
|
|
187
|
+
[1] AST scan ──► detect imports ──► map to Nuitka plugins
|
|
188
|
+
(numpy, torch, (automatic, no config needed)
|
|
189
|
+
PIL, tkinter…)
|
|
190
|
+
│
|
|
191
|
+
▼
|
|
192
|
+
[2] FlagBuilder ──► generate optimised Nuitka command
|
|
193
|
+
--onefile --lto=yes --jobs=0
|
|
194
|
+
--enable-plugin=anti-bloat
|
|
195
|
+
--enable-plugin=numpy (if detected)
|
|
196
|
+
...
|
|
197
|
+
│
|
|
198
|
+
▼
|
|
199
|
+
[3] NuikitaCompiler.compile()
|
|
200
|
+
├─ subprocess.Popen (streams output in real time)
|
|
201
|
+
├─ background thread reads stdout/stderr
|
|
202
|
+
└─ parses exit code, raises CompilationError on failure
|
|
203
|
+
│
|
|
204
|
+
▼
|
|
205
|
+
[4] resolve output path ──► finds .exe / .bin in output_dir
|
|
206
|
+
│
|
|
207
|
+
▼
|
|
208
|
+
[5] PostOptimizer (optional) ──► runs UPX --best --lzma
|
|
209
|
+
│
|
|
210
|
+
▼
|
|
211
|
+
dist/myapp.exe (native binary — no Python installation required)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Output file by platform:**
|
|
215
|
+
|
|
216
|
+
| Platform | Output |
|
|
217
|
+
|---|---|
|
|
218
|
+
| Windows | `dist/myapp.exe` |
|
|
219
|
+
| Linux | `dist/myapp.bin` |
|
|
220
|
+
| macOS | `dist/myapp.bin` |
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Error handling
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
from pathlib import Path
|
|
228
|
+
from thonpress import ThonPress, BuildConfig
|
|
229
|
+
from thonpress.exceptions import (
|
|
230
|
+
CompilationError,
|
|
231
|
+
ConfigError,
|
|
232
|
+
NuitkaNotFoundError,
|
|
233
|
+
CancellationError,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
ThonPress(BuildConfig(entry=Path("main.py"))).build()
|
|
238
|
+
except NuitkaNotFoundError:
|
|
239
|
+
print("Nuitka not found — run: pip install nuitka")
|
|
240
|
+
except ConfigError as e:
|
|
241
|
+
print(f"Config error: {e}")
|
|
242
|
+
except CompilationError as e:
|
|
243
|
+
print(f"Compilation failed:\n{e}")
|
|
244
|
+
except CancellationError:
|
|
245
|
+
print("Build cancelled")
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Real-world benchmarks
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
tkinter todo app (~300 lines, sqlite3)
|
|
254
|
+
──────────────────────────────────────────────
|
|
255
|
+
PyInstaller → 47.3 MB startup 2.1s
|
|
256
|
+
thonpress → 6.8 MB startup 0.09s
|
|
257
|
+
|
|
258
|
+
FastAPI server (~150 lines)
|
|
259
|
+
──────────────────────────────────────────────
|
|
260
|
+
PyInstaller → 38.1 MB startup 1.8s
|
|
261
|
+
thonpress → 9.2 MB startup 0.12s
|
|
262
|
+
|
|
263
|
+
numpy batch processor (~500 lines)
|
|
264
|
+
──────────────────────────────────────────────
|
|
265
|
+
PyInstaller → 52.4 MB runtime 1.00×
|
|
266
|
+
thonpress → 11.6 MB runtime 3.7×
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT
|
thonpress-1.0.0/hello.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
print('hello from native binary')
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.21"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "thonpress"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Compile Python to native machine code and bundle into lightweight standalone executables"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
keywords = ["compiler", "nuitka", "executable", "packaging", "native", "standalone", "binary"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "AchillesHubTeam" },
|
|
15
|
+
]
|
|
16
|
+
maintainers = [
|
|
17
|
+
{ name = "AchillesHubTeam" },
|
|
18
|
+
]
|
|
19
|
+
classifiers = [
|
|
20
|
+
"Development Status :: 5 - Production/Stable",
|
|
21
|
+
"Environment :: Console",
|
|
22
|
+
"Intended Audience :: Developers",
|
|
23
|
+
"Intended Audience :: System Administrators",
|
|
24
|
+
"License :: OSI Approved :: MIT License",
|
|
25
|
+
"Natural Language :: English",
|
|
26
|
+
"Operating System :: OS Independent",
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"Programming Language :: Python :: 3.9",
|
|
29
|
+
"Programming Language :: Python :: 3.10",
|
|
30
|
+
"Programming Language :: Python :: 3.11",
|
|
31
|
+
"Programming Language :: Python :: 3.12",
|
|
32
|
+
"Programming Language :: Python :: 3.13",
|
|
33
|
+
"Programming Language :: Python :: 3.14",
|
|
34
|
+
"Programming Language :: C",
|
|
35
|
+
"Topic :: Software Development :: Compilers",
|
|
36
|
+
"Topic :: Software Development :: Build Tools",
|
|
37
|
+
"Topic :: System :: Software Distribution",
|
|
38
|
+
"Typing :: Typed",
|
|
39
|
+
]
|
|
40
|
+
dependencies = [
|
|
41
|
+
"nuitka>=2.8",
|
|
42
|
+
"typer>=0.12",
|
|
43
|
+
"rich>=13.7",
|
|
44
|
+
"tomli>=2.0; python_version < '3.11'",
|
|
45
|
+
"packaging>=24.0",
|
|
46
|
+
"zstandard>=0.21",
|
|
47
|
+
"ordered-set>=4.1",
|
|
48
|
+
"patchelf>=0.17; sys_platform == 'linux'",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[project.optional-dependencies]
|
|
52
|
+
dev = [
|
|
53
|
+
"pytest>=8.0",
|
|
54
|
+
"pytest-cov>=5.0",
|
|
55
|
+
"ruff>=0.4",
|
|
56
|
+
"mypy>=1.10",
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
[project.scripts]
|
|
60
|
+
thonpress = "thonpress.cli:main"
|
|
61
|
+
|
|
62
|
+
[project.urls]
|
|
63
|
+
Homepage = "https://github.com/AchillesHubTeam/thonpress"
|
|
64
|
+
Repository = "https://github.com/AchillesHubTeam/thonpress"
|
|
65
|
+
Issues = "https://github.com/AchillesHubTeam/thonpress/issues"
|
|
66
|
+
Changelog = "https://github.com/AchillesHubTeam/thonpress/releases"
|
|
67
|
+
|
|
68
|
+
[tool.hatch.build.targets.wheel]
|
|
69
|
+
packages = ["thonpress"]
|
|
70
|
+
|
|
71
|
+
[tool.ruff]
|
|
72
|
+
line-length = 100
|
|
73
|
+
target-version = "py39"
|
|
74
|
+
|
|
75
|
+
[tool.ruff.lint]
|
|
76
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
77
|
+
|
|
78
|
+
[tool.mypy]
|
|
79
|
+
python_version = "3.9"
|
|
80
|
+
strict = true
|
|
81
|
+
ignore_missing_imports = true
|
|
82
|
+
|
|
83
|
+
[tool.pytest.ini_options]
|
|
84
|
+
testpaths = ["tests"]
|
|
85
|
+
addopts = "--tb=short"
|
|
File without changes
|