The distutils module[1] has for a long time recommended using thesetuptools package[2] instead. Setuptools has recently integrated acomplete copy of distutils and is no longer dependent on the standardlibrary[3]. Pip has been silently replacing distutils withsetuptools when installing packages for a long time already, and thedistutils documentation has stated that it is being phased out since2014 (or earlier). It is time to remove it from the standard library.
distutils[1] is a largely undocumented and unmaintained collectionof utilities for packaging and distributing Python packages, includingcompilation of native extension modules. It defines a configurationformat that describes a Python distribution and provides the tools toconvert a directory of source code into a source distribution, andsome forms of binary distribution. Because of its place in thestandard library, many updates can only be released with a majorrelease, and users cannot rely on particular fixes being available.
setuptools[2] is a better documented and well maintained enhancementbased on distutils. While it provides very similar functionality, itis much better able to support users on earlier Python releases, andcan respond to bug reports more quickly. A number of platform-specificenhancements already exist in setuptools that have not been added todistutils, and there is been a long-standing recommendation in thedistutils documentation to prefer setuptools.
Historically, setuptools has extended distutils using subclassing andmonkeypatching, but has now taken a copy of the underlying code.[3]As a result, the second last major dependency on distutils is gone andthere is no need to keep it in the standard library.
The final dependency on distutils is CPython itself, which uses it tobuild native extension modules in the standard library (except onWindows). Because this is a CPython build-time dependency, it ispossible to continue to use distutils for this specific case withoutit being part of the standard library.
Deprecation and removal will make it obvious that issues should befixed in the setuptools project, and will reduce a source of bugreports and unnecessary test maintenance. It will also help promotethe development of alternative build backends, which can now besupported more easily thanks toPEP 517.
In Python 3.10 and 3.11, distutils will be formally marked asdeprecated. All known issues will be closed at this time.importdistutils will raise a deprecation warning. New issues thatwould be considered release blocking may still be fixed, but supportfor new tools or platforms will not be added.
During Python 3.10 and 3.11, uses of distutils within the standardlibrary may change to use alternative APIs.
In Python 3.12, distutils will no longer be installed bymakeinstall or any of the first-party distribution. Third-partyredistributors should no longer include distutils in their bundles orrepositories.
This PEP makes no specification on migrating the parts of the CPythonbuild process that currently use distutils. Depending oncontributions, this migration may occur at any time.
After Python 3.12 is started and when the CPython build process nolonger depends on distutils being in the standard library, the entireLib/distutils directory andLib/test/test_distutils.py filewill be removed from the repository.
Other references to distutils will be cleaned up. As of Python 3.9’sinitial release, the following modules have references in code orcomments:
The following Tools in CPython also refer to distutils. Note that noneof these are installed with CPython:
As the distutils code is already included in setuptools, there is noneed to republish it in any other form. Those who require access tothe functionality should use setuptools or an alternative buildbackend.
Code that imports distutils will no longer work from Python 3.12.
The suggested migration path is to use the equivalent (though notidentical) imports from setuptools (see[5]), or to migrate to analternative build backend (seePEP 517).
Code already exists in setuptools to transparently switchsetup.pyfiles using distutils onto their equivalents, and so most workingbuild scripts are already known to work with setuptools. Such scriptsmay need to update their import statements. Consult the setuptoolsdocumentation for specific migration advice.[5]
Some projects use alternate sets of patches over distutils, notably,numpy.distutils.[6] Projects that we know are doing this have beeninformed.
Many build scripts use custom commands or narrowly scoped patches. Asthese packages are already subject to setuptools overriding distutils,we expect minimal disruption as a result of distutils being removed.Scripts may still need to be updated to avoid importing distutils.
setuptools version 48 includes the complete copy of distutils, and assuch is no longer dependent on the standard library’s copy. Mostimplementation issues they have faced are due to the continuingexistence of distutils in the standard library, and so removal willimprove the stability of their implementation.
There is not yet a reference implementation for the removal ofdistutils from the standard library, nor is there an implementationfor CPython’s native module builds without relying on the standardlibrary copy of distutils.
Note
This section suggests some alternative replacements for popularfunctionality that is being formally deprecated with this PEP. Itis current at time of writing, but is not kept up to date.
For these modules or types,setuptools is the best substitute:
distutils.ccompilerdistutils.cmd.Commanddistutils.commanddistutils.configdistutils.core.Distributiondistutils.errorsFor these modules or types, use the standards-defined Python PackagingAuthority packages specified:
distutils.version — use thepackaging packageFor these modules or functions, use the standard library module shown:
distutils.fancy_getopt — use theargparse moduledistutils.spawn.find_executable — use theshutil.which functiondistutils.spawn.spawn — use thesubprocess.run functiondistutils.sysconfig — use thesysconfig moduledistutils.util.get_platform — use theplatform moduleFor these functions, and any others not mentioned here, you will needto reimplement the functionality yourself. The legacy documentationcan be found athttps://docs.python.org/3.9/distutils/apiref.html
distutils.dir_util.create_treedistutils.util.change_rootdistutils.util.strtoboolThe primary concern with this approach is that distutils mostfrequently breaks because of platform differences, which means thatwithout maintenance, it will stop working out-of-sync with anyPython release. This makes it impossible for libraries to reliablydetect when they will stop working.
In contrast, this PEP proposes a concrete date, known well in advance,when distutils will stop working, and commits to not breaking the APIbefore that time. This gives maintainers a predictable schedule,ensures any breakage occurs at a point where users will already beexpecting changed behavior, and provides a reliable detectionmechanism (specifically, thatimportdistutils raises).
Finally, as long as distutils remains in the standard library in anyform, it will interfere with third-party packages that provide shimsor replacements, including setuptools. Completely removing thepackage at a known version makes it possible for third-parties tosafely use a substitute.
This suggestion assumes that there exists a volunteer to maintainwhatever is left, which is not true. It also implies that anybodyknows which functionality should remain, which as seen in thediscussions is not at all clear.
Most helper functions in distutils already have supported (andimproved) alternatives, often in the standard library, and there islittle that can be done to the legacy versions without breakingcompatibility. (And any break requiring maintainers to update theircode is essentially equivalent to requiring them to import a differentfunction.)
The last point from the previous section also applies here.
This document is placed in the public domain or under theCC0-1.0-Universal license, whichever is more permissive.
Source:https://github.com/python/peps/blob/main/peps/pep-0632.rst
Last modified:2025-02-01 08:55:40 GMT