Status ofnumpy.distutils and migration advice#

numpy.distutils has been deprecated in NumPy1.23.0. It will be removedfor Python 3.12; for Python <= 3.11 it will not be removed until 2 years afterthe Python 3.12 release (Oct 2025).

Warning

numpy.distutils is only tested withsetuptools<60.0, newerversions may break. SeeInteraction of numpy.distutils with setuptools for details.

Migration advice#

There are several build systems which are good options to migrate to. Assumingyou 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 beusing a well-designed, modern and reliable build system, we recommend:

  1. Meson, and themeson-python build backend

  2. CMake, and thescikit-build-core build backend

If you have modest needs (only simple Cython/C extensions; no need for Fortran,BLAS/LAPACK, nestedsetup.py files, or other features ofnumpy.distutils) and have been happy withnumpy.distutils so far, youcan also consider switching tosetuptools. Note that most functionality ofnumpy.distutils is unlikely to be ported tosetuptools.

Moving to Meson#

SciPy has moved to Meson and meson-python for its 1.9.0 release. Duringthis process, remaining issues with Meson’s Python support andfeature parity withnumpy.distutils were resolved.Note: parity means alarge superset (because Meson is a good general-purpose build system); onlya few BLAS/LAPACK library selection niceties are missing. SciPy uses almostall functionality thatnumpy.distutils offers, so if SciPy has successfullymade a release with Meson as the build system, there should be no blockers leftto migrate, and SciPy will be a good reference for other packages who aremigrating. 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 calledscikit-build-core. Where theolderscikit-build usedsetuptools underneath, the rewrite does not.Like Meson, CMake is a good general-purpose build system.

Moving tosetuptools#

For projects that only usenumpy.distutils for historical reasons, and donot actually use features beyond those thatsetuptools also supports,moving tosetuptools is likely the solution which costs the least effort.To assess that, there are thenumpy.distutils features that arenotpresent insetuptools:

  • Nestedsetup.py files

  • Fortran 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 andSSE2 flags are default)

  • a simple user build config system, seesite.cfg.example

  • SIMD intrinsics support

  • Support for the NumPy-specific.src templating format for.c/.h files

The most widely used feature is nestedsetup.py files. This feature mayperhaps still be ported tosetuptools in the future (it needs a volunteerthough, seegh-18588 forstatus). Projects only using that feature could move tosetuptools afterthat is done. In case a project uses only a couple ofsetup.py files, italso could make sense to simply aggregate all the content of those files into asinglesetup.py file and then move tosetuptools. This involvesdropping allConfiguration instances, and usingExtension instead.E.g.,:

fromdistutils.coreimportsetupfromdistutils.extensionimportExtensionsetup(name='foobar',version='1.0',ext_modules=[Extension('foopkg.foo',['foo.c']),Extension('barpkg.bar',['bar.c']),],)

For more details, see thesetuptools documentation

Interaction ofnumpy.distutils withsetuptools#

It is recommended to usesetuptools<60.0. Newer versions may work, butare not guaranteed to. The reason for this is thatsetuptools 60.0 enableda vendored copy ofdistutils, including backwards incompatible changes thataffect some functionality innumpy.distutils.

If you are using only simple Cython or C extensions with minimal use ofnumpy.distutils functionality beyond nestedsetup.py files (its mostpopular feature, seeConfiguration),then latestsetuptools is likely to continue working. In case of problems,you can also trySETUPTOOLS_USE_DISTUTILS=stdlib to avoid the backwardsincompatible changes insetuptools.

Whatever you do, it is recommended to put an upper bound on yoursetuptoolsbuild requirement inpyproject.toml to avoid future breakage - seeFor downstream package authors.