Status of numpy.distutils
and migration advice#
numpy.distutils
has been deprecated in NumPy 1.23.0
. It will be removed
for Python 3.12; for Python <= 3.11 it will not be removed until 2 years after
the Python 3.12 release (Oct 2025).
Warning
numpy.distutils
is only tested with setuptools < 60.0
, newer
versions may break. See Interaction of numpy.distutils with setuptools for details.
Migration advice#
There are several build systems which are good options to migrate to. Assuming you have compiled code in your package (if not, you have several good options, e.g. the build backends offered by Poetry, Hatch or PDM) and you want to be using a well-designed, modern and reliable build system, we recommend:
Meson, and the meson-python build backend
CMake, and the scikit-build-core build backend
If you have modest needs (only simple Cython/C extensions; no need for Fortran,
BLAS/LAPACK, nested setup.py
files, or other features of
numpy.distutils
) and have been happy with numpy.distutils
so far, you
can also consider switching to setuptools
. Note that most functionality of
numpy.distutils
is unlikely to be ported to setuptools
.
Moving to Meson#
SciPy has moved to Meson and meson-python for its 1.9.0 release. During
this process, remaining issues with Meson’s Python support and
feature parity with numpy.distutils
were resolved. Note: parity means a
large superset (because Meson is a good general-purpose build system); only
a few BLAS/LAPACK library selection niceties are missing. SciPy uses almost
all functionality that numpy.distutils
offers, so if SciPy has successfully
made a release with Meson as the build system, there should be no blockers left
to migrate, and SciPy will be a good reference for other packages who are
migrating. For more details about the SciPy migration, see:
NumPy will migrate to Meson for the 1.26 release.
Moving to CMake / scikit-build#
The next generation of scikit-build is called scikit-build-core. Where the
older scikit-build
used setuptools
underneath, the rewrite does not.
Like Meson, CMake is a good general-purpose build system.
Moving to setuptools
#
For projects that only use numpy.distutils
for historical reasons, and do
not actually use features beyond those that setuptools
also supports,
moving to setuptools
is likely the solution which costs the least effort.
To assess that, there are the numpy.distutils
features that are not
present in setuptools
:
Nested
setup.py
filesFortran build support
BLAS/LAPACK library support (OpenBLAS, MKL, ATLAS, Netlib LAPACK/BLAS, BLIS, 64-bit ILP interface, etc.)
Support for a few other scientific libraries, like FFTW and UMFPACK
Better MinGW support
Per-compiler build flag customization (e.g. -O3 and SSE2 flags are default)
a simple user build config system, see site.cfg.example
SIMD intrinsics support
The most widely used feature is nested setup.py
files. This feature may
perhaps still be ported to setuptools
in the future (it needs a volunteer
though, see gh-18588 for
status). Projects only using that feature could move to setuptools
after
that is done. In case a project uses only a couple of setup.py
files, it
also could make sense to simply aggregate all the content of those files into a
single setup.py
file and then move to setuptools
. This involves
dropping all Configuration
instances, and using Extension
instead.
E.g.,:
from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
version='1.0',
ext_modules=[
Extension('foopkg.foo', ['foo.c']),
Extension('barpkg.bar', ['bar.c']),
],
)
For more details, see the setuptools documentation
Interaction of numpy.distutils
with setuptools
#
It is recommended to use setuptools < 60.0
. Newer versions may work, but
are not guaranteed to. The reason for this is that setuptools
60.0 enabled
a vendored copy of distutils
, including backwards incompatible changes that
affect some functionality in numpy.distutils
.
If you are using only simple Cython or C extensions with minimal use of
numpy.distutils
functionality beyond nested setup.py
files (its most
popular feature, see Configuration
),
then latest setuptools
is likely to continue working. In case of problems,
you can also try SETUPTOOLS_USE_DISTUTILS=stdlib
to avoid the backwards
incompatible changes in setuptools
.
Whatever you do, it is recommended to put an upper bound on your setuptools
build requirement in pyproject.toml
to avoid future breakage - see
For downstream package authors.