包与发布
本章讲解Cython项目的打包和发布。好的打包策略能让Cython模块跨平台使用,触达更多用户。
学习路径:包结构 → 跨平台构建 → wheel打包 → 版本管理
核心工具:
- setuptools:Python打包标准
- CI/CD:自动化构建测试
- manylinux:跨Linux发行版兼容
17.1 包结构设计
Section titled “17.1 包结构设计”功能说明:标准Python包目录结构。
mypackage/├── mypackage/│ ├── __init__.py│ ├── core.pyx│ ├── utils.pyx│ └── utils.html # cython -a生成的HTML├── tests/│ ├── test_core.py│ └── test_utils.py├── setup.py├── README.md└── LICENSE说明:
- 内层
mypackage/是源代码目录 - 外层是项目根目录
tests/放置测试代码
功能说明:在__init__.py中导出公共接口。
from mypackage.core import MyClassfrom mypackage.utils import fast_function
__all__ = ["MyClass", "fast_function"]功能说明:版本信息统一管理。
__version__ = "1.0.0"17.2 跨平台构建
Section titled “17.2 跨平台构建”Windows构建
Section titled “Windows构建”功能说明:Windows平台使用MSVC编译器。
from setuptools import setup, Extensionfrom Cython.Build import cythonizeimport sys
if sys.platform == "win32": ext_modules = cythonize([ Extension("mypackage.core", ["mypackage/core.pyx"]), ], compiler_directives={"msvc": True})else: ext_modules = cythonize("mypackage/*.pyx")macOS构建
Section titled “macOS构建”功能说明:macOS使用clang,支持动态库。
# macOS特定配置ext_modules = [ Extension("mypackage.core", ["mypackage/core.pyx"], extra_link_args=["-dynamiclib"], )]Linux构建
Section titled “Linux构建”功能说明:Linux使用gcc,启用-fPIC位置无关代码。
# Linux构建ext_modules = [ Extension("mypackage.core", ["mypackage/core.pyx"], extra_compile_args=["-fPIC"], )]CI/CD集成
Section titled “CI/CD集成”功能说明:GitHub Actions自动构建多平台wheel。
name: Buildon: [push, pull_request]
jobs: build: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: [3.9, "3.10", "3.11"]
steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: pip install cython numpy - name: Build run: python setup.py build_ext --inplace17.3 wheel打包
Section titled “17.3 wheel打包”跳过HTML生成
Section titled “跳过HTML生成”功能说明:wheel中不包含cython -a生成的HTML文件。
from setuptools import setupfrom Cython.Build import cythonizeimport shutil
extensions = [ Extension("mypackage.core", ["mypackage/core.pyx"]),]
setup( name="mypackage", version="1.0.0", ext_modules=cythonize(extensions), cmdclass={"build_ext": shutil.ignore_patterns("*.html")},)预编译wheel
Section titled “预编译wheel”功能说明:构建并上传wheel到PyPI。
# 构建wheelpython -m build wheel
# 上传到PyPItwine upload dist/mypackage-1.0.0-*.whl输出示例:
dist/├── mypackage-1.0.0-cp39-cp39-linux_x86_64.whl├── mypackage-1.0.0-cp39-cp39-macosx_x86_64.whl└── mypackage-1.0.0-cp39-cp39-win_amd64.whl17.4 版本管理
Section titled “17.4 版本管理”功能说明:遵循语义化版本规范。
__version__ = "1.2.3" # 主版本.次版本.修订
# 主版本:不兼容的API变更# 次版本:向后兼容的功能添加# 修订:向后兼容的bug修复API兼容性
Section titled “API兼容性”功能说明:保持向后兼容的API设计。
# 保持向后兼容cpdef int old_function(int x) except -1: # 旧函数保持 return x * 2
cpdef int new_function(int x, int y=1) except -1: # 新函数有默认值参数,调用更便捷 return x * y最佳实践:
- 不删除旧函数,标记为deprecated
- 新函数添加默认参数减少破坏性
- 重大版本才进行不兼容变更
平台构建对比
Section titled “平台构建对比”| 平台 | 编译器 | 特殊配置 |
|---|---|---|
| Windows | msvc | compiler_directives={"msvc": True} |
| macOS | clang | extra_link_args=["-dynamiclib"] |
| Linux | gcc | extra_compile_args=["-fPIC"] |
| 跨平台 | - | CI/CD多平台矩阵 |
- 使用语义化版本(major.minor.patch)
- 跨平台用CI/CD自动化构建
- wheel打包避免包含.html文件
- 保持API向后兼容
- 创建完整的包结构(含__init__.py和多个模块)
- 配置多平台CI/CD(GitHub Actions)
- 构建wheel包并使用twine上传到TestPyPI
- 实现版本管理,导出__version__
- 设计保持向后兼容的API(添加新参数时使用默认值)
- 配置manylinux环境构建兼容多个Linux发行版的wheel