CodeWalk

Python打包完整流程:setuptools/wheel/pyproject.toml详解

作者:苦行僧 · 2026-05-30 12:55

请说明现代Python打包的完整流程和核心文件pyproject.toml的配置项。解释sdist(源码分发包)和wheel(预编译分发包)的区别,以及pure Python wheel和platform wheel的差异。如何用setuptools配置C扩展编译、console_scripts入口点、extras_require可选依赖?setup.cfgsetup.py在当前生态中的位置是什么?

回答

苦行僧

pyproject.toml配置(PEP 621推荐方式):

[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "mypackage"
version = "1.0.0"
description = "A useful package"
requires-python = ">=3.9"
dependencies = [
    "requests>=2.28",
    "numpy"
]

[project.optional-dependencies]
dev = ["pytest>=7", "black"]
ml = ["torch", "transformers"]

[project.scripts]
mycli = "mypackage.cli:main"  # console_scripts入口点

[tool.setuptools.packages.find]
where = ["src"]
include = ["mypackage*"]

sdist vs wheel: | 特性 | sdist (.tar.gz) | wheel (.whl) | |------|------------------|---------------| | 内容 | 源码+setup.py | 预构建的安装格式 | | 安装速度 | 慢(需编译) | 快(直接解压复制) | | C扩展 | 需目标机编译 | 预编译(platform wheel) | | 纯Python | 无需编译 | pure Python wheel(无平台标记) |

C扩展配置

# setup.py(仍需C扩展场景)
from setuptools import setup, Extension

setup(
    ext_modules=[
        Extension('mypackage._fast', ['src/_fast.c'],
                  libraries=['m'],  # 链接math库
                  define_macros=[('VERSION', '1.0')])
    ]
)

build流程

python -m build  # 生成dist/下的sdist和wheel
pip install dist/*.whl

setup.cfg vs setup.py

  • setup.py:仍需要(声明式方式通过setup.cfg)或作为构建入口
  • setup.cfg:声明式配置,逐渐被pyproject.toml替代
  • 现代推荐:纯声明式pyproject.toml,仅必要场景保留setup.py
  • 向后兼容:pip install -e .仍支持setup.py