ModuleNotFoundError: No module named distutils.msvccompiler in Python 3.12+
Upgrade setuptools and pip with python -m pip install --upgrade setuptools pip, or install pre-compiled binary wheels (.whl) to avoid building legacy C extensions with removed distutils.
Root Cause Analysis
This error occurs when Python 3.12+ tries to install or build a legacy C-extension package whose setup.py attempts to import distutils.msvccompiler, but the standard library distutils module was permanently removed in Python 3.12 (PEP 632).
Removal of distutils in Python 3.12 (PEP 632)
distutils was the original package build tool introduced in Python 1.6 (over 20 years ago). Over time, it was superseded by setuptools, wheel, and modern PEP 517/518 build backends. Python 3.10 marked distutils as deprecated, and Python 3.12 removed the entire distutils package from the standard library.
On Windows, older setup.py files specifically attempted to import distutils.msvccompiler to locate Microsoft Visual C++ Build Tools. In Python 3.12, running pip install on such unmaintained packages raises ModuleNotFoundError: No module named 'distutils.msvccompiler'.
Common Triggers
- Legacy Packages on PyPI Without Wheels: Older Python libraries whose authors have not released pre-compiled wheels for Python 3.12.
- Outdated
setuptoolsin Virtual Environment: Using old versions of virtualenv that bundled legacysetuptools(< 65.0). - Direct Invocations of
python setup.py install: Running legacy setup scripts directly instead of modernpip install ..
Reproduction Code (MCVE)
# In Python 3.12+, distutils is removed from the standard library
raise ModuleNotFoundError("No module named 'distutils.msvccompiler'")
Solution 1: Upgrade `setuptools` and `pip` in Active Environment
Modern versions of setuptools include their own internal MSVC compiler integrations that replace distutils.
import sys
import subprocess
# Upgrade build tools to modern setuptools/wheel
upgrade_cmd = f'{sys.executable} -m pip install --upgrade pip setuptools wheel'
print(f'Recommended upgrade command:\n{upgrade_cmd}')
Solution 2: Migrate to Modern `pyproject.toml` Build Specification
Use pyproject.toml with setuptools.build_meta to declare standard PEP 517 build dependencies.
pyproject_content = '''
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-package"
version = "1.0.0"
'''
print('Modern pyproject.toml configuration:')
print(pyproject_content.strip())
Note de reproductibilité
La reproductibilité de cette erreur dépend de la version de l'interpréteur Python (Python 3.12 ou supérieur), du système d'exploitation Windows et de la présence d'outils de compilation C (MSVC Build Tools).
Workaround for Legacy Unmaintained Packages
If an abandoned package strictly requires distutils and cannot be upgraded, you can install the standalone setuptools compatibility shim by setting SETUPTOOLS_USE_DISTUTILS=stdlib before Python 3.12, or use a Python 3.11 virtual environment for that specific legacy workload.
Contrasting with related errors:
ModuleNotFoundError: No module named 'distutils.msvccompiler': Module removed in Python 3.12.Microsoft Visual C++ 14.0 or greater is required: The compiler module was found, but MSVC Build Tools are not installed on Windows.