Last active
February 9, 2025 22:05
-
-
Save juancarlospaco/683b44c83876a1e79b55803c936e8052 to your computer and use it in GitHub Desktop.
setup.py with post-install compilation of Cython and Go.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
# | |
# | |
# To generate DEB package from Python Package: | |
# sudo pip3 install stdeb | |
# python3 setup.py --verbose --command-packages=stdeb.command bdist_deb | |
# | |
# | |
# To generate RPM package from Python Package: | |
# sudo apt-get install rpm | |
# python3 setup.py bdist_rpm --verbose --fix-python --binary-only | |
# | |
# | |
# To generate EXE MS Windows from Python Package (from MS Windows only): | |
# python3 setup.py bdist_wininst --verbose | |
# | |
# | |
# To generate PKGBUILD ArchLinux from Python Package (from PyPI only): | |
# sudo pip3 install git+https://github.com/bluepeppers/pip2arch.git | |
# pip2arch.py PackageNameHere | |
# | |
# | |
# To Upload to PyPI by executing: | |
# sudo pip install --upgrade pip setuptools wheel virtualenv | |
# python3 setup.py bdist_egg bdist_wheel --universal sdist --formats=zip upload --sign | |
# | |
# | |
# How to check if your modules are Cythonizable ?: | |
# cython -3 --verbose --no-docstrings your_module.py # Pure Python,needs a *.pxd | |
# cython -3 --verbose --no-docstrings your_module.pyx # Cython Syntax,dont need *.px | |
# cythonize --in-place your_module.c | |
"""Generic Setup.py. | |
ALL THE CONFIG LIVES IN SETUP.CFG,PLEASE EDIT THERE,KEEP IT SIMPLE AND CLEAN.""" | |
import atexit | |
from setuptools import setup | |
############################################################################## | |
# EDIT HERE | |
MODULES2CYTHONIZE = ("example/somemodule.py", # Put here modules you want to Speed Up. | |
"example/othermodule.py", | |
"example/slowmodule.py", | |
"example/example.py") | |
############################################################################## | |
# Dont touch below | |
def post_install_cythonize(): | |
"""Compile *.PY to *.SO with Cython,delete *.PYC,*.C,*.PY if sucessful.""" | |
import sys | |
import os | |
from pathlib import Path | |
from shutil import which, rmtree | |
from subprocess import run | |
try: | |
from site import getsitepackages | |
site_packages = getsitepackages()[0] | |
except (ImportError, Exception): | |
from distutils.sysconfig import get_python_lib | |
site_packages = get_python_lib() | |
gcc, cythoniz = which("gcc"), which("cythonize") | |
if gcc and cythoniz and site_packages and sys.platform.startswith("linux"): | |
for py_file in [(Path(site_packages) / f) for f in MODULES2CYTHONIZE]: | |
if py_file.is_file() and os.access(py_file, os.W_OK): | |
comand = f"{cythoniz} -3 --inplace --force {py_file}" | |
try: | |
run(comand, shell=True, timeout=99, check=True) | |
except Exception as error: | |
print(error) | |
else: | |
print(f"CREATED Binary file: {py_file.with_suffix('.so')}") | |
if py_file.with_suffix(".c").is_file(): | |
py_file.with_suffix(".c").unlink() # is C Obfuscated. | |
if py_file.is_file(): | |
print(f"DELETED unused file: {py_file}") | |
py_file.unlink() # Because *.SO exist and is faster. | |
rmtree(py_file.parent / "__pycache__", ignore_errors=True) | |
else: | |
print("GCC & Cython not found, install GCC & Cython for Speed up.") | |
atexit.register(post_install_cythonize) | |
setup() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
# | |
# | |
# To generate DEB package from Python Package: | |
# sudo pip3 install stdeb | |
# python3 setup.py --verbose --command-packages=stdeb.command bdist_deb | |
# | |
# | |
# To generate RPM package from Python Package: | |
# sudo apt-get install rpm | |
# python3 setup.py bdist_rpm --verbose --fix-python --binary-only | |
# | |
# | |
# To generate EXE MS Windows from Python Package (from MS Windows only): | |
# python3 setup.py bdist_wininst --verbose | |
# | |
# | |
# To generate PKGBUILD ArchLinux from Python Package (from PyPI only): | |
# sudo pip3 install git+https://github.com/bluepeppers/pip2arch.git | |
# pip2arch.py PackageNameHere | |
# | |
# | |
# To Upload to PyPI by executing: | |
# sudo pip install --upgrade pip setuptools wheel virtualenv | |
# python3 setup.py bdist_egg bdist_wheel --universal sdist --formats=zip upload --sign | |
# | |
# | |
# How to check if your modules are Cythonizable ?: | |
# cython -3 --verbose --no-docstrings your_module.py # Pure Python,needs a *.pxd | |
# cython -3 --verbose --no-docstrings your_module.pyx # Cython Syntax,dont need *.px | |
# cythonize --in-place your_module.c | |
"""Generic Setup.py. | |
ALL THE CONFIG LIVES IN SETUP.CFG,PLEASE EDIT THERE,KEEP IT SIMPLE AND CLEAN.""" | |
import atexit | |
from setuptools import setup | |
############################################################################## | |
# EDIT HERE | |
MODULES2CYTHONIZE = ("example/somemodule.py", # Put here Python or Go files. | |
"example/othermodule.py", | |
"example/slowmodule.py", | |
"example/example.py") | |
############################################################################## | |
# Dont touch below | |
def post_install_compilation(): | |
"""Compile *.PY to *.SO with Cython,Compile Go to Binary using Go.""" | |
import sys | |
import os | |
from pathlib import Path | |
from shutil import which, rmtree | |
from subprocess import run | |
try: | |
from site import getsitepackages | |
site_packages = getsitepackages()[0] | |
except (ImportError, Exception): | |
from distutils.sysconfig import get_python_lib | |
site_packages = get_python_lib() | |
gcc, cythoniz, go = which("gcc"), which("cythonize"), which("go") | |
if gcc and go and cythoniz and site_packages: | |
is_linux = sys.platform.startswith("linux") | |
for fyle in [(Path(site_packages) / f) for f in MODULES2COMPILEE]: | |
is_writable = os.access(py_file, os.W_OK) | |
is_go = fyle.endswith(".go") | |
# PYTHON | |
if fyle.is_file() and is_writable: | |
comand = f"{cythoniz} -3 --inplace --force {fyle}" | |
try: | |
run(comand, shell=True, timeout=99, check=True) | |
except Exception as error: | |
print(error) | |
else: | |
print(f"CREATED Binary file: {fyle.with_suffix('.so')}") | |
if fyle.with_suffix(".c").is_file(): | |
fyle.with_suffix(".c").unlink() # is C Obfuscated. | |
if fyle.is_file(): | |
print(f"DELETED unused file: {fyle}") | |
fyle.unlink() # Because *.SO exist and is faster. | |
rmtree(fyle.parent / "__pycache__", ignore_errors=True) | |
# GO | |
if fyle.is_file() and is_writable and is_go: | |
comand = f"{go} build {fyle}" | |
try: | |
run(comand, shell=True, timeout=99, check=True) | |
except Exception as error: | |
print(error) | |
else: | |
print(f"CREATED Binary file: {fyle.with_suffix('')}") | |
if fyle.with_suffix(".c").is_file(): | |
py_file.with_suffix(".c").unlink() # is C Obfuscated. | |
if fyle.is_file(): | |
print(f"DELETED unused file: {fyle}") | |
fyle.unlink() # Because *.SO exist and is faster. | |
else: | |
print("GCC,Cython & Go not found, install GCC,Cython & Go.") | |
if which("go"): | |
atexit.register(post_install_compilation) | |
setup() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Now with the PEP 517 build standard being solidified, this post-install cythonization stopped working with the isolated build environments.
Most of my configuration was in
setup.cfg
, and I wanted to use setuptools "Development Mode" but still distribute cythonized code. Mysetup.cfg
file looks like this:pyproject.toml
I was able to reuse some code and came up with a new solution:
When using the build utility from pypa, run the command:
This will build both the wheel and the tarball forms of your package. The tarball will contain your python code, and will be cythonized when you install it.
You can install the tarball with this command
Since wheels dont support post-install commands, the wheel will contain your cythonized code.
The best thing about this is it still supports the setuptools "Development Mode"