Information on using distutils module

distutils is the primary way of building and distributing Python packages. For more information about distutils, see distutils — Building and installing Python modules in the official Python documentation.

Writing a module

You can use the typical layout for a Python package or module as follows:
README
LICENSE
setup.py
requirements.txt
src/
    module.py
    module.c
include/
    module.h
docs/
    conf.py
    index.rst
tests/
    test_module.py
The setup.py is the makefile equivalent for Python modules and it is often invoked through the following commands:
python3 setup.py build
builds the package, but does not install it.
python3 setup.py sdist
builds a source distributable tape archived file of the package and contains all the source of your modules.
python3 setup.py bdist
builds a binary distributable tape archived file of the package and contains only object files of your compiled code.
python3 setup.py install
installs the package to <python install location>/lib/site-packages/<your package here>.
python3 setup.py check
checks the package for correctness.
For setting up your C/C++ compiler, see Using IBM C/C++ compilers with IBM Open Enterprise SDK for Python 3.11.
Note: If you use a dynamic library for Python packages, you should ensure that all .so or .dll files are found in your LIBPATH.

Troubleshooting

For more information about errors using distutils, see Errors when using distutils.

Examples

A simple setup.py for a pure Python module is as follows:
from distutils.core import setup, Extension
setup(name='example',
   version='1.0',
   description='An example package for distutils',
   author='John Doe',
   author_email='john.doe@ibm.com',
   url='https://www.ibm.com',
   packages=["ibm_example"],
   )
The corresponding file layout would be as follows:
example/
   setup.py
   ibm_example/
      __init__.py
If you want to add a C source file to the module, you can do it with the following lines:
from distutils.core import setup, Extension
setup(name='example',
   version='1.0',
   description='An example package for distutils',
   author='John Doe',
   author_email='john.doe@ibm.com',
   url='https://www.ibm.com',
   packages=["ibm_example"],
   ext_modules=[Extension('foo', ['src/foo1.c', 'src/foo2.c'], include_dirs=['include'])]
   )
The file layout would be as follows:
example/
    setup.py
ibm_example/
    __init__.py
include/
    foo.h
src/
    foo1.c
    foo2.c
Note: You can also add C++ files in an analogous manner. Make sure that you use the appropriate file extensions, since this is how Python determines which compiler to invoke for the source files. If you include several modules that are specified with different extensions, a separate shared library is produced per extension.
A setup.py example with an explicit side-deck is as follows:
from distutils.core import setup, Extension
setup(name='example',
   version='1.0',
   description='An example package for distutils',
   author='John Doe',
   author_email='john.doe@ibm.com',
   url='https://www.ibm.com',
   packages=["ibm_example"],
   ext_modules=[Extension('foo', ['src/foo1.c', 'src/foo2.c'], include_dirs=['include'], extra_compile_args=['/usr/lib/example.x'])]
   )
If your module requires the use of dll or .so files, distutils automatically attempts to find them. When the side-deck is in a non-standard location, you should modify your setup.py to include the side-deck with extra_compile_args as shown above.

Best practice

When writing modules for Python, you should consider external dependencies, which can be located in non-typical locations, or in locations that are platform-dependent. To alleviate the non-typical locations issue, you can create a setup.cfg file that allows you to specify values at installation time. For more information on setup.cfg files, see Writing the Setup Configuration File. For more information on how to extend Python with C or C++, see Python/C API Reference Manual.