AberSheeran
Aber Sheeran
I know nothing except the fact of my ignorance.

poetry 使用指北

起笔自
所属文集: Python-Package
共计 3471 个字符
落笔于

poetry 满足了我对包管理器的一切愿望,它的野心有点大,向着 Python 界的 npm 一路狂奔。

但这不是贬义词,它是一款比 pipenv 优秀的包管理器——当你适应它之后。

poetry init

就像 npm init 一样,poetry 也需要使用 init 命令创建 pyproject.toml 文件,当然你也可以手动。

这一命令并不会帮助你创建虚拟环境,它仅仅是创建一个 pyproject.toml 用来描述你的项目而已。

poetry env

此命令以及子命令用于处理虚拟环境相关的操作。

如果需要创建的虚拟环境与当前系统默认的 Python 版本不一致,pypoetry 会自动去寻找不同于当前 Python 环境的 Python 解释器位置,如果它找不到,那么就只能手动指定解析器的绝对路径。

在非 Windows 系统上,一般可以通过 which pythonwhich python3.7 一类的命令寻找到自己指定的 Python 版本的位置。

在 Windows 系统中,可以通过环境变量来寻找 Python 的解释器位置。

poetry env use PYTHONPATH

使用 poetry env use PYTHONPATH 命令创建虚拟环境。

# in windows
poetry env use C:\Users\AberS\AppData\Local\Programs\Python\Python38\python.exe

poetry env list

poetry 比 pipenv 要强的是,可以使用 poetry env use PYTHONPATH 为一个项目创建多个不同的虚拟环境。

通过 poetry env list 可以查看当前项目所有的虚拟环境,增加 --full-path 可以看到虚拟环境的完整路径,一般在配置 VSCode、PyCharm 的时候需要使用。

poetry install & update

pipenv installpipenv update 行为完全一致的愚蠢不同的是,poetry 的 install 和 update 真的做到了字面上的意思,install 就是安装所有的依赖,update 就是升级所有依赖,并且 update 真的可以指定一个包做到只更新它。

# 安装**所有的**依赖
# 如果没有虚拟环境,将会自动使用当前 Python 环境安装一个
poetry install
# 仅安装非 development 环境的依赖,一般部署时使用
poetry install --no-dev

poetry add & remove

与 npm 相同,poetry 增加/删除依赖使用 add/remove 命令。

add 命令增加 --dev 选项,可以把库标记为 development,当使用 poetry install --no-dev 时,不会安装它们。

poetry shell & run

与 pipenv 相同,poetry shell 可以在 shell 中激活当前虚拟环境;poetry run 可以直接在当前虚拟环境中运行命令。

poetry build & publish

poetry 是一个全面的包管理器,即可以管理别人,也可以管理自己。

以下是我第一个使用 poetry 发布 pypi 包的项目——websocks 中的配置。

[tool.poetry]
name = "websocks"
version = "0.1.9"
description = "A websocket-based socks5 proxy."
readme = "README.md"
authors = ["abersheeran <[email protected]>"]
license = "MIT"

homepage = "https://github.com/abersheeran/websocks"
repository = "https://github.com/abersheeran/websocks"
documentation = "https://github.com/abersheeran/websocks/wiki"
classifiers=[
    "Programming Language :: Python :: 3.6",
    "Programming Language :: Python :: 3.7",
    "Programming Language :: Python :: Implementation :: CPython",
    "Programming Language :: Python :: Implementation :: PyPy",
]

packages = [
    { include = "websocks" },
]

[tool.poetry.scripts]
websocks =  'websocks.commands:main'

写过 setup.py 的人都会明白以上配置的含义,在此不做赘述。它的意义在于,我们再也不用写该死的 setup.py 了,一个 pyproject.toml 文件即可。

使用 poetry build 可以把项目打包成一个 .whl 文件用于安装。

然后可以使用 poetry publish 发布到 pypi 上,如果你不想执行两条命令,那么可以把 poetry build; poetry publish 合并成一条 poetry publish --build,这将做出同样的行为——先打包,后发布。

poetry config

poetry config 允许配置一些 poetry 的默认行为。

譬如:poetry config virtualenvs.in-project true 可以设置虚拟环境默认安装到项目的 .venv 目录里。

poetry config virtualenvs.create false --local 在部署时先使用这个命令可以使所有的包安装到系统中,而不是虚拟环境里。

使用 PyPi 镜像

由于网络原因,部分地区使用默认的 PyPi 源可能效果不佳。通过在 pyproject.toml 中配置源可以使 poetry 从指定的 PyPi 镜像中拉取代码。注意 default = true 是必须的,否则 poetry 仍然会从默认源拉取哈希值。

[[tool.poetry.source]]
name = "tsinghua"
default = true
url = "https://pypi.tuna.tsinghua.edu.cn/simple"

题外话

我在把 websocks 从 pipenv + setup.py 转移到 poetry 之后,发生了一个问题,docker 的自动构建失败了。

由于 pyproject.toml 是 PEP 标准的一部分,可以直接使用 pip3 install . 去安装整个包。但这个过程中,会自动下载 poetry,既会增加最终镜像的大小,还需要安装一些用来编译 poetry 的依赖包的依赖。就在这里,我使用的 python:3.7-alpine 不负所托的失败了,但我不想增加最终镜像的大小。

于是一番查找之下,我使用了 dephell 把 pyproject.toml 转译成纯净的 setup.py,再使用 docker 的分段构建,只把转译好的 setup.py 保留下来,这么一来,镜像大小比原来还小几百个字节,虽然几百个字节对于现代计算机来说没什么用。😀😀如果有老旧项目需要从各种环境管理、包管理的魔爪下逃脱,建议试试 dephell。

如果你觉得本文值得,不妨赏杯茶
好看易用的命令行
pip 安装与脚本安装