如何在 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 构建系统,然后就有了此文。
为什么迁移?
setuptool 不自带 virtualenv,建立开发环境很麻烦
在 Python 项目中实现四个现代化
现代化配置系统 (no more setup.py)
现代化配置语言 (toml)
现代化打包工具 (poetry)
现代化打包程序 (no more python setup.py sdist and python setup.py bdist_wheel)
为什么到 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 监测也有了
本文为 Blog 上原文稍作修改后的版本。所有修改均以 Blog 原文为准。由于 IPFS 的不可变性,Matters 的副本无法更新。欲查看原文,请参见 Re:Linked 。