Quick fix
# One-liner: install setuptools (most common, seconds to fix)
pip install setuptools
In a venv, install inside the venv; for system Python use sudo pip install setuptools or the system package manager.
What you will run into
After moving to Python 3.12+ (incl. 3.13/3.14), running old tools, activating a fresh venv, or importing a new interpreter in PyCharm fails with ModuleNotFoundError: No module named 'distutils'.
Most common in old projects/toolchains: legacy setup.py, old libraries depending on distutils, and fresh venvs that no longer include setuptools by default (since 3.12, venv ships only pip, no setuptools).
Why this happens
Python 3.12 removed distutils from the standard library (deprecated for years before that).
Also, since 3.12 a fresh venv installs only pip by default, no setuptools, and distutils' shim happens to be provided by setuptools — import distutils actually maps to setuptools/_distutils.
The error's essence: "no setuptools in the environment, therefore no distutils shim."
| Environment | import distutils |
|---|---|
| System Python (Ubuntu preinstalls setuptools) | ✅ Works (measured: loads the setuptools/_distutils shim) |
| Clean venv (3.12+ ships only pip) | ❌ ModuleNotFoundError (measured reproduction) |
distutils was removed from the standard library in 3.12, but the real mechanism is the "shim": import distutils is actually provided by setuptools' _distutils (setuptools installs a distutils replacement).
Since 3.12, fresh venvs ship with pip only — no setuptools — so "import distutils fails" really means "the environment has no setuptools, hence no shim".
System Python does not fail because distros preinstall setuptools.
Deterministic takeaway: on ModuleNotFoundError: No module named distutils, first check for setuptools (pip show setuptools);
two correct paths — install setuptools (pip install setuptools, shim returns) or migrate to packaging/stdlib alternatives (sysconfig, tomllib); legacy projects should not pin setuptools out of requirements (it is also a build dependency);
fixed diagnostic: the same import works on system Python but fails in a fresh venv = missing setuptools, not a code problem.
Step by step
1. Install setuptools — Required
pip install setuptools
After install, import distutils works again (via the setuptools/_distutils shim).
2. Also upgrade pip/setuptools — Required
python -m ensurepip --upgrade && pip install --upgrade setuptools pip
Old pip (e.g. PyCharm's bundled 20.3.4) is poorly compatible with 3.12+ and often breaks at the same time.
3. System package manager (only for old Python versions) — Required
sudo apt install python3-distutils
Note this package usually only goes up to Python 3.11; distros may not provide it for 3.12+, prefer option 1.
4. Long-term fix (legacy project migration) — Required
Convert old setup.py to pyproject.toml + setuptools.build_meta (PEP 517) and remove direct distutils imports from code. Installing setuptools as a transition lets you move fast, but distutils is EOL and won't come back.
How to confirm it works
Import restored (measured output shape):
After pip install setuptools inside the venv → import distutils works, exit 0 (measured)
Load path becomes the venv's setuptools/_distutils/__init__.py (measured)Other environments
| Environment | Notes |
|---|---|
| Clean venv (3.12+) | Ships only pip 25.x, no setuptools → error (measured) |
| System Python | Ubuntu preinstalls setuptools 78.1.1; fine |
| PyCharm bundled pip | Old pip poorly compatible; upgrade it too |
| apt python3-distutils | Only up to Python 3.11 |
| Long term | Migrate to pyproject.toml (PEP 517) |
Symptom
After switching to Python 3.12+ (including 3.13/3.14), running legacy tools, activating a fresh virtualenv, or adding a new interpreter in PyCharm fails with:
ModuleNotFoundError: No module named 'distutils'
Most common in legacy projects/toolchains: old setup.py files using from distutils.core import setup, old libraries depending on distutils, and fresh venvs (since 3.12 a venv ships pip only, no setuptools).
Cause
Python 3.12 removed distutils from the standard library (deprecated for years). In addition, since 3.12 fresh venvs only include pip, no setuptools — and the distutils replacement (shim) is provided by setuptools: import distutils actually maps to setuptools/_distutils. So the error effectively means "no setuptools in this environment, hence no distutils shim".
Solution
In recommended order:
- Install setuptools (most common, instant fix):
pip install setuptools. After thatimport distutilsworks again via thesetuptools/_distutilsshim. Install inside the venv when using one; usesudo pip install setuptoolsor your system package manager for system Pythons. - Also upgrade pip/setuptools:
python -m ensurepip --upgrade && pip install --upgrade setuptools pip— old pip versions (e.g. PyCharm's bundled 20.3.4) are poorly compatible with 3.12+ and often fail together. - System package manager (Debian/Ubuntu, older Pythons only):
sudo apt install python3-distutils. Note this package usually only exists up to Python 3.11; 3.12+ distros may not provide it — prefer option 1. - Long-term fix (legacy project migration): convert old setup.py to
pyproject.toml+ setuptools.build_meta (PEP 517) and remove direct distutils imports. Installing setuptools is a fine stopgap, but distutils is EOL and will not come back.
Verification Evidence
- Local repro (2026-08-29, WSL Ubuntu, Python 3.14.4 / pip 25.1.1):
- System Python: Ubuntu ships setuptools 78.1.1,
import distutilsworks, loading/usr/lib/python3/dist-packages/setuptools/_distutils/__init__.py(shim active); - Fresh venv (3.12+ ships pip 25.1.1 only, no setuptools):
import distutils→ full reproduction ofModuleNotFoundError: No module named 'distutils', exit 1; - Fix: after
pip install setuptoolsinside the venv,import distutilsworks again, loading the venv'ssetuptools/_distutils/__init__.py, exit 0; - Conclusion matches the source article, with a correction: setuptools does not "depend on" distutils — it provides a distutils shim; the
python3-distutilsapt package only exists for older Pythons, so on 3.12+ preferpip install setuptools.
Evidence details kept locally (2026-08-29)
Applicable tools (2)
This problem is linked from the tool pages below — reachable from either side.
pythonpipSource & evidence
← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk