Setuptools

raw JSON →
82.0.1 verified Tue May 12 auth: no python install: verified quickstart: stale

Setuptools is Python's original and most established build backend for packaging, distributing, and installing Python packages, with full support for C/C++ extension modules, entry points, and PEP 517/660 editable installs. Current version is 82.0.1 (released Feb 2026). The project ships frequently — multiple major versions per month — and has a history of disruptive but well-warned breaking changes. Requires Python >=3.9 as of v75.4.0.

pip install setuptools
error error: command 'gcc' failed: No such file or directory
cause Setuptools requires a C/C++ compiler to build native extensions for some Python packages, which is missing from the system's PATH.
fix
Install the appropriate build tools for your operating system (e.g., sudo apt-get install build-essential on Debian/Ubuntu, xcode-select --install on macOS, Visual C++ build tools on Windows).
error ERROR: Package 'setuptools' requires a different Python: 3.8.10 not in '>=3.9'
cause The version of setuptools being installed or used requires Python 3.9 or newer, but the current Python environment is older than 3.9.
fix
Upgrade Python to version 3.9 or newer, or switch to a Python environment (e.g., virtualenv) that uses Python 3.9 or newer.
error error: The 'install_requires' parameter must be a string or list of strings (got set) in setup.cfg
cause The `install_requires` field in `setup.cfg` or `setup.py` is incorrectly formatted, typically specified as a Python set instead of a list of strings or a multi-line string.
fix
Modify install_requires in setup.cfg (or setup.py) to be a list of strings (e.g., install_requires = python_package_name >= X.Y.Z) or a multi-line string format.
error ModuleNotFoundError: No module named 'distutils.cmd'
cause The `distutils` package was removed from the Python standard library in Python 3.12+, causing older `setup.py` scripts or packages that directly import from it to fail.
fix
Update the setup.py script to import setup from setuptools (e.g., from setuptools import setup) and replace direct distutils imports with their setuptools.distutils equivalents.
breaking pkg_resources was fully removed in setuptools 81.0.0 (released Feb 8 2026). Any code or dependency doing 'import pkg_resources' will raise ModuleNotFoundError on setuptools >= 81.
fix Replace all pkg_resources usage with importlib.metadata (version, entry_points, etc.) and importlib.resources. For transitive dependencies you cannot control, pin 'setuptools<81' as a temporary workaround.
breaking setup.cfg keys using hyphens (e.g. 'description-file', 'long-description') raise InvalidConfigError in setuptools >= 78. This was a deprecation since 2021 that became an error in v78.
fix Replace all hyphenated keys in setup.cfg with their underscore equivalents (e.g. 'description_file', 'long_description'). The v78.0.1 reversal was itself reverted; the enforcement stands in current releases.
breaking project.license as a TOML table (e.g. license = {text = 'MIT'}) is deprecated as of setuptools 77 in favour of a plain SPDX string (license = 'MIT'). The table form will eventually be rejected.
fix Use a plain SPDX expression string: 'license = "MIT"' in pyproject.toml [project]. If you still need to support Python 3.8 builds (max setuptools 75.3.x), keep the table form and suppress the warning temporarily.
deprecated Running 'python setup.py install', 'python setup.py develop', 'python setup.py test', and other direct setup.py CLI invocations are deprecated and being removed incrementally. 'setup.py develop' now defers to pip internally.
fix Use 'pip install .' for installation, 'pip install -e .' for editable installs, 'python -m build' for building distributions, and a dedicated test runner (pytest) instead of 'setup.py test'.
breaking Python 3.8 support was dropped in setuptools 75.4.0. The last version supporting Python 3.8 is 75.3.x (actively maintained as a security-only branch).
fix If you must build on Python 3.8, pin 'setuptools<75.4' or use the 75.3.x maintenance branch. Otherwise upgrade to Python >=3.9.
gotcha Do NOT add 'wheel' to build-system.requires in pyproject.toml. This was historically recommended but is now unnecessary and actively discouraged by the official docs.
fix Use only 'requires = ["setuptools"]' in [build-system]. The build frontend (pip, build) handles wheel generation separately.
gotcha Static analysis tools (mypy, pyright, pylint) may not work correctly when setuptools uses an import-hook-based editable install (the default). This is a known limitation of the compat editable mode.
fix Pass '--config-settings editable_mode=compat' when running 'pip install -e .' to use a symlink/pth-file approach instead of the import hook.
pip install "setuptools>=61.0"
python os / libc variant status wheel install import disk
3.10 alpine (musl) "setuptools>=61.0" - - 0.81s 18.7M
3.10 alpine (musl) setuptools - - 0.81s 18.7M
3.10 slim (glibc) "setuptools>=61.0" - - 0.52s 19M
3.10 slim (glibc) setuptools - - 0.55s 19M
3.11 alpine (musl) "setuptools>=61.0" - - 1.02s 20.9M
3.11 alpine (musl) setuptools - - 1.03s 20.9M
3.11 slim (glibc) "setuptools>=61.0" - - 0.80s 21M
3.11 slim (glibc) setuptools - - 0.80s 21M
3.12 alpine (musl) "setuptools>=61.0" - - 0.51s 20.4M
3.12 alpine (musl) setuptools - - 0.48s 20.4M
3.12 slim (glibc) "setuptools>=61.0" - - 0.51s 21M
3.12 slim (glibc) setuptools - - 0.52s 21M
3.13 alpine (musl) "setuptools>=61.0" - - 0.47s 20.0M
3.13 alpine (musl) setuptools - - 0.47s 20.0M
3.13 slim (glibc) "setuptools>=61.0" - - 0.47s 20M
3.13 slim (glibc) setuptools - - 0.47s 20M
3.9 alpine (musl) "setuptools>=61.0" - - 0.83s 18.3M
3.9 alpine (musl) setuptools - - 0.85s 18.3M
3.9 slim (glibc) "setuptools>=61.0" - - 0.66s 19M
3.9 slim (glibc) setuptools - - 0.69s 19M

Minimal modern pyproject.toml-based package layout and programmatic setup.py usage. Run 'python -m build' from the project root to produce sdist + wheel in dist/.

# pyproject.toml (place in your project root — no setup.py needed)
# [build-system]
# requires = ["setuptools>=61"]
# build-backend = "setuptools.build_meta"
#
# [project]
# name = "mypackage"
# version = "0.1.0"
# description = "My package"
# requires-python = ">=3.9"
# license = "MIT"            # PEP 639 SPDX string (setuptools >= 77)
# dependencies = ["requests>=2.25"]
#
# [project.scripts]
# my-cli = "mypackage.cli:main"

# --- Programmatic use (setup.py, still valid as config file) ---
from setuptools import setup, find_packages

setup(
    name="mypackage",
    version="0.1.0",
    packages=find_packages(where="src"),
    package_dir={"": "src"},
    python_requires=">=3.9",
    install_requires=["requests>=2.25"],
)

# --- Runtime metadata (replaces pkg_resources) ---
from importlib.metadata import version, entry_points

pkg_version = version("mypackage")
eps = entry_points(group="console_scripts")