Skip to content

Instantly share code, notes, and snippets.

@datavudeja
Forked from juancarlospaco/setup.py
Created February 9, 2025 22:05
Show Gist options
  • Save datavudeja/81436d9a7db97497264edf7042ca3d07 to your computer and use it in GitHub Desktop.
Save datavudeja/81436d9a7db97497264edf7042ca3d07 to your computer and use it in GitHub Desktop.
setup.py with post-install compilation of Cython and Go.
#!/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()
#!/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