It can be somewhat intricate to create a Python package for distribution for others to use, especially when the Python package uses C++ code. This repository attempts to provide a minimal working example.
If using Linux or macOS, run the following scripts in sequence:
build_dist.sh
install.sh
and then run the script script.py
using python3 script.py
.
If using Windows, look at the commands in the scripts above.
The folder egpkg_package
contains all the files and folders necessary to
build the package.
The following Python modules need to be installed:
Cython
numpy
wheel
setuptools
as well as a C++ compiler.
If you want to run the tests, pytest
will also need to be installed.
Alternatively, one can navigate to the egpkg_package
folder
and run the command:
python3 -m build
This will create a folder dist
in egpkg_package
which contains
.whl
file and a .tar.gz
file which can be used to distribute the package
for others to use.
(By the way, this is the main command in build_dist.sh
)
Note: It seems that it is necessary to be connected to the internet,
because Python seems to create a virtual environment and install numpy
and
other packages in this environment before compiling the package.
This package contains two functions:
timesTwo
: pure Python function, multiplies an argument by 2.timesThree
: C++ implementation, multiplies an argument by 3 (double).
build_dist.sh
: builds the files used to install and share the package.buildinplace.sh
: builds the package, which can be used locally.cleanup.sh
: deletes files and folders to return the theegpkg_package
directory to the state it was in beforebuild_dist.sh
.install.sh
: afterbuild_dist.sh
is run, will installegpkg
using the.whl
file.install_from_targz.sh
: afterbuild_dist.sh
is run, will installegpkg
using the.tar.gz
file.runtests.sh
: runs simple tests oftimesTwo
andtimesThree
usingpytest
. This script essentially callsbuildinplace.sh
, which does not install the package.replace.sh
: allows one to easily change from 'egpkg' to 'mypackage' (or any other string); useful when using this package as a starting point.script.py
: A simple script which can be run, afteregpkg
is installed, to check that the functionstimesTwo
andtimesThree
work.uninstall.sh
: uninstalls the package, if it has been built and installed.show_uninstalled.sh
: shows the package has been uninstalled.
egpkg/src/
: containsfunc.py
which containstimesTwo
function.egpkg/cppsrc/
: containscppfunc.h
andcppfunc.cpp
, which contains thecpp_timesThree
function, andcppmethods.pyx
which wraps the C++ code into the Python functionstimesThree
.
This package can be used as a starting point.
- In
setup.py
, change all instances ofegpkg
to whatever package name you want. - Change the subdirectory
egpkg_package/egpkg/
to the name of the package you wish. - Change the directory
egpkg_package
to another name (any you wish). - Include any C++ code in the folder
cppsrc
; follow the example ofcppmethods.pyx
.
The hardest part was to get the .whl
file to be successfully built, and for the
package to be installed from the .whl
file so that the (C++ function) timesThree
could be called.
Built with some help from the official documents, some help from ChatGPT, and some trial and error.
There are also several other GitHub repos out there which aim to provide a MWE; while I am sure they worked when originally created, all the ones tried now (May 2023) seem to not (completely) work. I expect that eventually this code will stop working. Hopefully by that stage the official Python packaging website will provide up-to-date MWEs.
This package was built using Python 3.11 on a (silicon-processor) Apple Macbook Air.