使用Poetry打包Python项目为wheel
起因
目前维护这两个Python轮子:
之前一直使用的是setup.py
进行打包,不过11月份更新NJUlogin时发现这样的一个提示:
********************************************************************************
With Python 2.7 end-of-life, support for building universal wheels
(i.e., wheels that support both Python 2 and Python 3)
is being obviated.
Please discontinue using this option, or if you still need it,
file an issue with pypa/setuptools describing your use case.
By 2025-Aug-30, you need to update your project and remove deprecated calls
or your builds will no longer be supported.
********************************************************************************
因此决定使用新的pyproject.toml
的方式进行打包。当时临时学了Poetry并给NJUlogin做了适配,今天更新mijia-api想顺便也做一个适配,结果发现忘了怎么用,还是写个博客记录一下吧。看来之后也多多用Poetry来管理依赖了。
Poetry
Poetry官网上对自身的定位是:Python packaging and dependency management made easy。用起来有点像npm
(如果你对nodejs有一定了解的话),也是通过命令行修改管理依赖的文件。
不过poetry有点太长了,从现在开始你就叫pop
吧。
alias pop='poetry'
Set-Alias pop poetry
安装
直接查看文档吧:https://python-poetry.org/docs/#installation
我这里用的是pipx进行安装
初始化已有项目
pop init
得到下述pyproject.toml
文件
[tool.poetry]
name = "mijiaapi"
version = "0.0.0"
description = "A Python API for Xiaomi Mijia"
authors = ["Do1e <dpj.email@qq.com>"]
license = "GPLv3"
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
不过因为我的包里面包含大写字母,需要把[tool.poetry]
下面的name
改了的同时,再额外手动加一个packages
项,另外再把setup.py
中的一些其他配置加上来:
2c2
< name = "mijiaapi"
---
> name = "mijiaAPI"
7a8,17
> homepage = "https://github.com/Do1e/mijia-api"
> repository = "https://github.com/Do1e/mijia-api"
> packages = [
> {include = "mijiaAPI"}
> ]
> classifiers = [
> "Programming Language :: Python :: 3",
> "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
> "Operating System :: OS Independent",
> ]
新建Peotry虚拟环境并安装依赖
默认会在~/.cache/pypoetry
里创建虚拟环境,可以使用pop config
进行修改,详见文档这里,我个人更习惯放在项目目录中:
# 配置虚拟环境放在项目目录中
pop config virtualenvs.in-project true
# 新建并使用虚拟环境
pop env use python
# 如果是在conda环境中使用就不需要了,会直接使用已有conda环境
source .venv/bin/activate
之后便可以从requirements.txt
中将依赖一个一个安装上了,下面这个命令会将依赖写入pyproject.toml
文件中并生成poetry.lock
:
pop add requests qrcode
Peotry的一大优势就是能够以树状形式展示依赖:
pop show --tree
# qrcode 8.0 QR Code image generator
# └── colorama *
# requests 2.32.3 Python HTTP for Humans.
# ├── certifi >=2017.4.17
# ├── charset-normalizer >=2,<4
# ├── idna >=2.5,<4
# └── urllib3 >=1.21.1,<3
至此,可以将原来的setup.py
删除了。
打包并发布
版本可以使用poetry-dynamic-versioning动态指定,不用每次修改pyproject.toml
指定版本号。
git tag v1.3.0
pop self add "poetry-dynamic-versioning[plugin]"
pop dynamic-versioning enable
此时就可以简单地使用一行命令构建了:
pop build
不像twine使用~/.pypirc
保存pypi的token,Poetry需要额外进行配置:
pop config pypi-token.pypi pypi-xxxxxx
然后就可以发布了!
pop publish