setuptools breaking changes
Every breaking API change we have recorded in setuptools on PyPI: 301 breaking changes in 16 versions. Below are its newest 6 versions, removals and renames first, each with its source.
Newest change October 19, 2026

On this page
84.1.0
- Behavior changed
setuptools.archive_util
Archive members that would be extracted outside the extraction directory now raise UnsafeMember rather than being skipped. Code that relied on silent skipping must catch this exception. github.com - Behavior changed
Wheel.install_as_egg
Entries in namespace_packages.txt are now validated as dotted module names on every platform, so entries that are absolute, drive-qualified or UNC paths are no longer accepted. This path is reached only by the deprecated setup_requires... github.com
84.0.0
- Removed
distutils.compat.consolidate_linker_args
The temporary distutils.compat.consolidate_linker_args shim has been removed. Code importing it will fail. github.com - Removed
setuptools.tests
setuptools.tests was removed in setuptools 84.0.0 pypi.org - Removed
spawn
The MSVC spawn shim for third-party monkeypatches predating the env argument has been removed. github.com - Behavior changed
customize_compiler
customize_compiler now raises AssertionError if CC, CXX, CFLAGS or similar config variables are None, instead of failing later. github.com - Behavior changed
CygwinCCompiler.gcc_version
gcc_version now returns a packaging.version.Version instead of a distutils LooseVersion. Update code that relied on the old type. github.com - Behavior changed
distutils.errors.DistutilsPlatformError
Building with a MACOSX_DEPLOYMENT_TARGET lower than the interpreter's value now raises PlatformError instead of DistutilsPlatformError. Catch the new class if you match the old one. github.com - Behavior changed
distutils.spawn.spawn
distutils.spawn.spawn is now a thin wrapper around subprocess.check_call. It no longer resolves cmd[0] with shutil.which or injects MACOSX_DEPLOYMENT_TARGET. github.com - Behavior changed
UnixCCompiler.runtime_library_dir_option
For GNU ld, runtime_library_dir_option now returns a list of flags instead of a single combined string. github.com - Signature changed
setuptools.command.alias.option_base.boolean_options
Was boolean_options; now boolean_options: list[str]. pypi.org - Signature changed
setuptools.command.alias.option_base.user_options
Was user_options; now user_options: list[tuple[str, str, str]] | list[tuple[str, str | None, str]]. pypi.org
And 23 more in this version.
83.0.0
- Removed
The release now requires Python 3.10 or later. Users on older Python versions must stay on an earlier setuptools release. github.com - Removed
dry_run
The vendored distutils no longer supports dry_run. Code relying on dry_run behavior must be changed. github.com - Behavior changed
FileList
Exclude, global-exclude, recursive-exclude and prune rules now also match non-ASCII file names stored in a different Unicode normalization form, so files previously included in the sdist may now be excluded. github.com
82.0.1
- Signature changed
setuptools.tests.test_setuptools.TestDepends.testModuleExtract
Was def testModuleExtract(self); now def testModuleExtract(self, sample_module). pypi.org - Signature changed
setuptools.tests.test_setuptools.TestDepends.testRequire
Was def testRequire(self); now def testRequire(self, sample_module). pypi.org
82.0.0
- Removed
pkg_resources
pkg_resources is no longer shipped with setuptools. Use importlib.resources and importlib.metadata instead, or pin an older setuptools version if your code relies on it for namespace packages or other behavior. pypi.org - Removed
setuptools.tests.test_namespaces.TestNamespaces.test_packages_in_the_same_namespace_installed_and_cwd
TestNamespaces.test_packages_in_the_same_namespace_installed_and_cwd was removed in setuptools 82.0.0 pypi.org - Removed
setuptools.tests.test_namespaces.TestNamespaces.test_pkg_resources_import
TestNamespaces.test_pkg_resources_import was removed in setuptools 82.0.0 pypi.org
81.0.0
- Removed
setuptools.tests.test_core_metadata.egg_info
setuptools.tests.test_core_metadata.egg_info was removed in setuptools 81.0.0 pypi.org - Removed
setuptools.tests.test_core_metadata.write_requirements
setuptools.tests.test_core_metadata.write_requirements was removed in setuptools 81.0.0 pypi.org - Renamed
setuptools.tests.test_core_metadata.TestParityWithMetadataFromPyPaWheel.test_equivalent_output
Use TestParityWithMetadataFromPyPaWheel.test_pkg_info_roundtrip instead. pypi.org - Signature changed
Some class and function signatures changed as a side effect of removing --dry-run, so derivative code may need compatibility shims to match the expected interface. github.com - Signature changed
setuptools.command.alias.edit_config
Was def edit_config(filename, settings, dry_run=False) -> None; now def edit_config(filename, settings) -> None. pypi.org - Signature changed
setuptools.command.bdist_egg.make_zipfile
Was def make_zipfile(zip_filename: StrPathT, base_dir, verbose: bool = False, dry_run: bool = False, compress=True, mode: _ZipFileMode = 'w') -> StrPathT; now def make_zipfile(zip_filename: StrPathT, base_dir, verbose: bool = False... pypi.org - Signature changed
setuptools.command.egg_info.edit_config
Was def edit_config(filename, settings, dry_run=False) -> None; now def edit_config(filename, settings) -> None. pypi.org - Signature changed
setuptools.command.saveopts.edit_config
Was def edit_config(filename, settings, dry_run=False) -> None; now def edit_config(filename, settings) -> None. pypi.org - Signature changed
setuptools.command.setopt.edit_config
Was def edit_config(filename, settings, dry_run=False) -> None; now def edit_config(filename, settings) -> None. pypi.org - Signature changed
setuptools.tests.test_logging.test_verbosity_level
Was def test_verbosity_level(tmp_path, monkeypatch, flag, expected_level); now def test_verbosity_level(tmp_path, monkeypatch, flags, expected_level). pypi.org
Check your code
These are the changes. To see which of them reach your code, scan a public repository, or have your coding agent call check_code with your manifest or lockfile over MCP. The API reads every change in every version, not only the newest. On Team and up, a fix pull request opens for the changes that reach a connected repository. Nothing merges or deploys.

Put your code on continuous management.
Scan a public repository now, or give your agent one line.
See how out of date your code is.
Tell your agent what changed since it was trained.
claude mcp add --transport http since https://api.since.dev/mcp