---
title: "setuptools Breaking Changes on PyPI | Since.dev"
description: "What each setuptools release removed, renamed or changed: 301 breaking changes in 16 versions on PyPI, each with its source."
canonical_url: https://since.dev/packages/pypi/setuptools
last_updated: 2026-10-19
---

# 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

## 84.1.0

2 breaking changes, first published October 19, 2026.

- **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](https://github.com/pypa/setuptools/blob/v84.1.0/NEWS.rst)
- **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](https://github.com/pypa/setuptools/blob/v84.1.0/NEWS.rst)

## 84.0.0

33 breaking changes, first published August 8, 2026.

- **Removed** `distutils.compat.consolidate_linker_args`  

The temporary distutils.compat.consolidate_linker_args shim has been removed. Code importing it will fail. [github.com](https://github.com/pypa/setuptools/blob/v84.0.0/NEWS.rst)
- **Removed** `setuptools.tests`  

setuptools.tests was removed in setuptools 84.0.0 [pypi.org](https://pypi.org/project/setuptools/84.0.0/)
- **Removed** `spawn`  

The MSVC spawn shim for third-party monkeypatches predating the env argument has been removed. [github.com](https://github.com/pypa/setuptools/blob/v84.0.0/NEWS.rst)
- **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](https://github.com/pypa/setuptools/blob/v84.0.0/NEWS.rst)
- **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](https://github.com/pypa/setuptools/blob/v84.0.0/NEWS.rst)
- **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](https://github.com/pypa/setuptools/blob/v84.0.0/NEWS.rst)
- **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](https://github.com/pypa/setuptools/blob/v84.0.0/NEWS.rst)
- **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](https://github.com/pypa/setuptools/blob/v84.0.0/NEWS.rst)
- **Signature changed** `setuptools.command.alias.option_base.boolean_options`  

Was boolean_options; now boolean_options: list\[str\]. [pypi.org](https://pypi.org/project/setuptools/84.0.0/)
- **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](https://pypi.org/project/setuptools/84.0.0/)

And 23 more in this version.

## 83.0.0

3 breaking changes, first published July 4, 2026.

- **Removed**  

The release now requires Python 3.10 or later. Users on older Python versions must stay on an earlier setuptools release. [github.com](https://github.com/pypa/setuptools/blob/v83.0.0/NEWS.rst)
- **Removed** `dry_run`  

The vendored distutils no longer supports dry_run. Code relying on dry_run behavior must be changed. [github.com](https://github.com/pypa/setuptools/blob/v83.0.0/NEWS.rst)
- **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](https://github.com/pypa/setuptools/blob/v83.0.0/NEWS.rst)

## 82.0.1

2 breaking changes, first published March 9, 2026.

- **Signature changed** `setuptools.tests.test_setuptools.TestDepends.testModuleExtract`  

Was def testModuleExtract(self); now def testModuleExtract(self, sample_module). [pypi.org](https://pypi.org/project/setuptools/82.0.1/)
- **Signature changed** `setuptools.tests.test_setuptools.TestDepends.testRequire`  

Was def testRequire(self); now def testRequire(self, sample_module). [pypi.org](https://pypi.org/project/setuptools/82.0.1/)

## 82.0.0

3 breaking changes, first published February 8, 2026.

- **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](https://pypi.org/project/setuptools/82.0.0/)
- **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](https://pypi.org/project/setuptools/82.0.0/)
- **Removed** `setuptools.tests.test_namespaces.TestNamespaces.test_pkg_resources_import`  

TestNamespaces.test_pkg_resources_import was removed in setuptools 82.0.0 [pypi.org](https://pypi.org/project/setuptools/82.0.0/)

## 81.0.0

10 breaking changes, first published February 6, 2026.

- **Removed** `setuptools.tests.test_core_metadata.egg_info`  

setuptools.tests.test_core_metadata.egg_info was removed in setuptools 81.0.0 [pypi.org](https://pypi.org/project/setuptools/81.0.0/)
- **Removed** `setuptools.tests.test_core_metadata.write_requirements`  

setuptools.tests.test_core_metadata.write_requirements was removed in setuptools 81.0.0 [pypi.org](https://pypi.org/project/setuptools/81.0.0/)
- **Renamed** `setuptools.tests.test_core_metadata.TestParityWithMetadataFromPyPaWheel.test_equivalent_output`  

Use TestParityWithMetadataFromPyPaWheel.test_pkg_info_roundtrip instead. [pypi.org](https://pypi.org/project/setuptools/81.0.0/)
- **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](https://github.com/pypa/setuptools/blob/v81.0.0/NEWS.rst)
- **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](https://pypi.org/project/setuptools/81.0.0/)
- **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](https://pypi.org/project/setuptools/81.0.0/)
- **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](https://pypi.org/project/setuptools/81.0.0/)
- **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](https://pypi.org/project/setuptools/81.0.0/)
- **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](https://pypi.org/project/setuptools/81.0.0/)
- **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](https://pypi.org/project/setuptools/81.0.0/)

## Check your code

These are the changes. To see which of them reach your code, [scan a public repository](https://since.dev/scan.md), or have your coding agent call `check_code` with your manifest or lockfile over [MCP](https://since.dev/docs.md#mcp). [The API](https://since.dev/docs.md#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.

[Scan a repository](https://since.dev/scan.md). Any public GitHub repository. No sign-in.

### Tell your agent what changed since it was trained.

`claude mcp add --transport http since https://api.since.dev/mcp`

---

Every page on this site as Markdown: https://since.dev/sitemap.md. For agents: https://since.dev/llms.txt.
