如何在 2024 年初始化一个 Python 项目
(迁移到 11ty 之后的头一篇文章!)
最近 Python 的 breaking change 还挺多的:
- Python 3.11 或者 Python 3.12 的时候,许多发行版都根据 PEP 668 配置了
EXTERNALLY-MANAGED
,从而阻止用户使pip
在非 virtualenv 中安装包。本来打算用pip install
的用户也就会遇到一些externally-managed-environment
之类的报错。 - Python 3.12 在去年十月发布了,最大的改变大概就是从标准库移除了
distutils
包。许多在打包流程中用到distutils
的开发者或许也遇到了一些问题。
跟这些都无关,我在维护某个项目的某一天,突然灵光一闪,Eureka!,于是向天空大吼一声:我受够 setup.py
啦!然后就把项目迁移到了使用 Poetry 构建系统,然后就有了此文。
为什么迁移?
setup.py
太难写,现在这个setup.py
甚至还是从youtube-dl
项目抄来的setuptool
不自带 virtualenv,建立开发环境很麻烦- 在 Python 项目中实现四个现代化
- 现代化配置系统 (no more
setup.py
) - 现代化配置语言 (toml)
- 现代化打包工具 (poetry)
- 现代化打包程序 (no more
python setup.py sdist
andpython setup.py bdist_wheel
)
- 现代化配置系统 (no more
为什么到 Poetry?
其实 setuptools 依然是最受欢迎的打包工具,但 Poetry 是第二名!Python 官方的打包文档就有推荐一些打包工具。各位也可以选择其它自己喜欢的来使用,不过本文以 Poetry 为主。
Poetry 也可以只作为依赖管理工具,配置方法是在 [tool.poetry]
设置 package-mode=false
。
步骤
写一个 pyproject.toml
在新时代 Python 打包系统中,各种配置都放在 pyproject.toml
。无论是包的信息、依赖的信息,还有 yapf、pylint、pytest 等各种各样工具的信息都在这里了。
setup.py
和依赖信息都可以参考这个例子搬进 pyproject.toml
。如果是迁移一个已经有 setup.py
的项目,这一步大概就是最复杂的一步。
环境配置和打包
poetry install
会初始化项目配置和安装依赖。poetry build
会在dist
文件夹中生成sdist
及wheel
打包结果。poetry shell
可以启动利用环境内 Python 的 shell,大概相当于pipenv shell
。poetry run
可以使用利用环境内 Python 的 shell 执行命令,大概相当于pipenv run
。
在 pyproject.toml
加入其它工具的配置
很多开发者(尤其是 JavaScript 开发者)都不喜欢项目根目录堆积着大量不同的配置文件,而 Python 生态就正在支持整合不同工具的配置到统一的文件中。许多 Python 工具都加入了读取 pyproject.toml
中配置的支持,例如:
通过 GitHub Actions 利用可信发布 (Trusted Publishing) 发布到 PyPI
(这点和 Poetry 倒没有什么关系。)
Python 包最后大多要发布到 PyPI。如果是托管在 GitHub 上的项目,PyPI 提供了一个 action 来方便地把完成打包(并且放置在 dist/
)的包发布到 PyPI。为了使用 Trusted Publishing 功能,也需要在 PyPI 配置发布来源。
成果
迁移前:
- 各种配置分开:包元数据在
setup.py
、依赖在Pipfile
、格式化配置在setup.cfg
、linting 配置在.pylintrc
等 - 构建命令是
python setup.py sdist
等等 - 开发用 virtualenv 由 Pipenv 管理
- 各种配置都写在
pyprojtect.toml
:包元数据、依赖、格式化及单元测试工具配置 - 能够区分 dependencies 和 devDependencies
- 构建命令是
poetry build
- 开发用 virtualenv 也由 Poetry 管理
- coverage 监测也有了