With the impending deprecation and scheduled removal of distutils
in Python 3.12, as a developer I’m faced with the challenge of transitioning my codebase to use setuptools
. For those not yet familiar, distutils
has been a fundamental part of Python for distributing and installing Python packages. However, its functionalities are now being absorbed and extended by setuptools
, which is an enhanced alternative. This transition is crucial not only to avoid unexpected breakdowns but to make use of better tools offering more functionalities.
I noticed when reviewing PEP 632, the official migration advice wasn’t very detailed, leaving me and possibly many other developers in a bit of a scramble to understand the exact steps needed to migrate smoothly. So I decided to figure it out myself and share what worked for me.
Understanding the Migration
Initially, I examined the recommendations provided by PEP 632. For example, distutils.ccompiler
and distutils.core.Distribution
are suggested to be replaced with their setuptools
counterparts. One frequent usage in my projects was import distutils.command
which according to the PEP implies that import setuptools.command
should be a drop-in replacement.
However, there were other common modules like distutils.core.setup
and distutils.core.Extension
, commonly used in setup scripts, which weren’t explicitly covered in the PEP. After some trial and error and referring to the setuptools documentation, I realized setuptools
provides similar functionality but needs to be handled slightly differently.
Migrating to setuptools
Here’s a basic outline and some examples of how I migrated common distutils
usages to setuptools
:
- Setup Script (
setup.py
):
Originally, a typical distutils
setup script might look like this:
from distutils.core import setup, Extension module1 = Extension('demo', sources=['demo.c']) setup(name='PackageName', version='1.0', description='This is a demo package', ext_modules=[module1])
Convert this to use setuptools like so:
from setuptools import setup, Extension module1 = Extension('demo', sources=['demo.c']) setup(name='PackageName', version='1.0', description='This is a demo package', ext_modules=[module1])
Notice how the change is minimal: the import statement simply switches from distutils.core
to setuptools
.
- Extension Building:
If you’re using distutils
to build C extensions, switching to setuptools
is straightforward as shown above.
- Commands:
If relying on something like distutils.command.build
, change this to setuptools.command.build
.
- Other utilities:
Some utilities like distutils.util.get_platform()
will have other recommended replacements such as using Python’s built-in platform
module directly.
Is setuptools
part of the Standard Library?
setuptools
is not part of the Python standard library. It is a third-party package that must be installed separately. Usually, it comes installed with Python distributions like Anaconda or if you’re using virtual environments. If not, it can be easily installed using pip:
pip install setuptools
As for usage, yes, in modern Python dependency and package management practices, direct interaction with setup.py
scripts is being replaced with declarative configurations in setup.cfg
or pyproject.toml
files and using build systems like build
or tox
. However, many projects still include setup.py
for backward compatibility or specific workflows.
By understanding these changes and adapting your codebase accordingly, you’ll be better prepared for Python’s future versions and more aligned with the evolving best practices in Python project setup and distribution. Transitioning to setuptools
not only addresses the upcoming removal of distutils
but also opens up more sophisticated packaging and distribution capabilities that setuptools
provides.
Leave a Reply