python 3.12 彻底移除 distutils,必须将所有 distutils 相关导入(如 setup、looseversion、build_ext)替换为 setuptools 或 packaging 对应模块,并确保 pyproject.toml 存在且 setuptools≥69.0。

distutils 在 Python 3.12 中是物理删除,不是弃用——没有警告、没有 stub、没有回退路径。你看到 ModuleNotFoundError: No module named 'distutils',就说明某处代码或依赖包正试图 import 它,必须改,不能绕。
setup.py 里还写着 from distutils.core import setup 怎么办
这行代码本身已失效,但直接删掉也不行,因为 setup() 的行为逻辑已由 setuptools 接管。你需要两步动作:
- 把
from distutils.core import setup替换为from setuptools import setup - 确保项目根目录存在
pyproject.toml,哪怕最简也得有:[build-system] requires = ["setuptools>=69.0", "wheel"] build-backend = "setuptools.build_meta"
- 如果项目没
pyproject.toml,pip 会尝试 fallback 到setup.py,但 Python 3.12 下这个 fallback 链已经断裂,结果就是卡在Preparing metadata (setup.py)不动
依赖包还在用 from distutils.version import LooseVersion
这类调用常见于旧科学计算库(如 APLpy、<code>pyregion)的 __init__.py 或版本检查逻辑中,不报错也可能静默失效。
- 替换为
from packaging.version import parse,然后用parse("1.2.3") > parse("1.2a1")做比较 -
LooseVersion和StrictVersion都已无对应物,别试图找“兼容版”;packaging.version是唯一受支持的现代方案 - 注意:
packaging不在标准库,需确保环境里装了packaging包(新版setuptools会自动带,但裸环境要手动补)
自定义构建命令继承了 distutils.command.build_ext
这是最容易被忽略的崩溃点——类定义看着正常,构造时才炸,错误可能是 AttributeError: module 'distutils' has no attribute 'command' 或更隐蔽的 ImportError。
- 把
from distutils.command.build_ext import build_ext改成from setuptools.command.build_ext import build_ext - 继承写法从
class MyBuildExt(distutils.command.build_ext.build_ext)改为class MyBuildExt(setuptools.command.build_ext.build_ext) - 不要只改 import,必须同步改继承路径;旧版
setuptools 仍会 fallback 到 <code>distutils,所以setuptools>=69.0是硬门槛
pip install -r requirements.txt 卡住不动或报错
这不是网络问题,是 pip 在 3.12 下无法协调缺失的构建入口。典型表现是终端停在 Preparing metadata (setup.py),CPU 占用低,几小时没反应。
- 先运行
python -m ensurepip --upgrade,确保 pip 自身不退化 - 确认
pip --version≥ 24.1(2024 年后发布),老 pip(如 22.x)会因调用已删的pkgutil.ImpImporter直接崩溃 - 加
-v参数重试:pip install -v -r requirements.txt,真实错误(比如No module named 'distutils.cmd')通常藏在 verbose 日志末尾 - Docker 构建失败?在
FROM python:3.12-slim后立刻补上:RUN pip install --upgrade pip setuptools wheel
import distutils,而是你没意识到的依赖链下游:某个 setup.py 文件、某个 __init__.py 里的版本检查、甚至 IDE 初始化时偷偷读取的元数据。只要有一处没清理干净,就可能在打包、安装、甚至 import 时突然崩。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











