How to package python projects

# 引言

最近学习python时遇到了需要把项目打包的问题。百度搜到的方法是使用setuptools,但是在使用过程中发现它提示了"SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.

没想到setuptools已经被淘汰了,于是想到python应该和php和java相同,有社区制定规范和标准。于是找到了pep (opens new window)pypa (opens new window)。pep是"Python Enhancement Proposal"的缩写,负责语言方面的提案。pypa则是"The Python Packaging Authority"的缩写,负责打包规范。

在介绍新的打包流程之前,先回顾一下setuptools的缺陷,它为什么会被淘汰。

# setuptools

pep-517 (opens new window)pep-518 (opens new window)中总结了setuptools存在的问题。

517中提出了以下3点:

  1. 功能缺失,如构建时和运行时依赖声明不一致、自动配置、版本号管理重复。
  2. 扩展困难,成本高。
  3. 兼容性差,难以使用其他包管理工具,因为它是社区标准。

setuptools在迭代过程中试图解决1和2,517提案则是要解决3。

518中提出了setuptools的一个问题,即难以在不执行setup.py文件的情况下了解其依赖关系,这导致了一个循环依赖问题,因为要运行文件以了解其依赖关系,但不能运行文件以了解其依赖关系。

# 解决方案

517和518提出了一套新的配置文件,即pyproject.toml,实现了项目元数据和构建工具配置的分离,跨构建工具的兼容性,依赖项声明的一致性,构建系统插件支持。

# 打包流程

# 配置pyproject.toml

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [
  { name="Example Author", email="author@example.com" },
]
description = "A small example package"
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]

[project.urls]
"Homepage" = "https://github.com/pypa/sampleproject"
"Bug Tracker" = "https://github.com/pypa/sampleproject/issues"

# 安装build

pip install --upgrade build

如果需要指定安装目录,可以使用--target参数。

pip install --upgrade build --target D:/Python/Lib/site-packages

# 打包

执行以下命令默认会在dist目录下生成whl和tar.gz文件。

python -m build

更加详细的步骤可以参考官网 (opens new window)

# 本地安装

pip install xxx.whl --target D:/Python/Lib/site-packages