Python诗歌 - 如何安装可选依赖?

48

Python的诗歌依赖管理器允许通过命令指定可选依赖项:

$ poetry add --optional redis

导致这个配置:

[tool.poetry.dependencies]
python = "^3.8"
redis = {version="^3.4.1", optional=true}

但是如何实际安装它们?文档似乎暗示:

$ poetry install -E redis

但那只会抛出一个错误:

Installing dependencies from lock file

[ValueError]
Extra [redis] is not specified.

你的 pyproject.toml 文件中是否也有一个 [tool.poetry.extras] 部分来定义额外的组?因为 -E 标签所期望的不是原始包名称,而是这个部分的定义。 - Arne
@Arne 谢谢,确实是这样的!这个规范有点奇怪:你需要在依赖项部分指定 optional=true 的包,并在额外部分指定 group=['package']。能否将您的评论添加为答案? - Granitosaurus
当然,我也会尝试解释为什么是这样的,即使文档描述得不是很详细。 - Arne
5个回答

53
如果您想在安装过程中使用-E标志,请根据文档中的描述,在pyproject.toml中添加tool.poetry.extras组。
[tool.poetry.extras]
caching = ["redis"]

关键字是你在使用poetry install -E时使用的单词,其值是一个包列表,这些包在添加时被标记为--optional。目前不支持将可选包作为特定组的一部分添加,因此您必须手动维护pyproject.toml文件中的此部分。
这个额外的抽象层背后的原因是extra-installs通常指一些可选功能(在这种情况下是缓存),它们通过安装一个或多个依赖项(在这种情况下只有redis)来启用。 poetry在这里只是简单地模仿了setuptools的extra-installs定义,这可能解释了为什么它的文档如此保守。

6
如果你遇到了“未指定 Extra”错误,你需要先运行poetry update - Sachin Raja
2
有没有一种简短的方式来安装所有额外的内容? - Stefan Falk
@StefanFalk 不,除非软件包维护者明确创建了类似于 [all] 的额外内容。甚至仅仅列出所有可用的额外内容也不是那么容易的事情:https://github.com/pypa/pip/issues/4824 - Arne
1
对于那些遇到“未指定Extra”错误的人,如果您不想同时更新所有依赖项,只需运行poetry lock --no-update即可更新锁文件。 - samGbos
6
从版本1.2开始,poetry install --all-extras命令将安装所有附加组件(参考@StefanFalk的问题)。 - abb

35

我想要强调的是,你不仅需要手动添加这个额外部分,而且你的可选依赖项不能在开发部分中。

以下是一个无法正常工作的代码示例:

[tool.poetry]
name = "yolo"
version = "1.0.0"
description = ""
authors = []

[tool.poetry.dependencies]
python = "2.7"
Django = "*"

[tool.poetry.dev-dependencies]
pytest = "*"
ipdb = {version = "*", optional = true}

[tool.poetry.extras]
dev_tools = ["ipdb"]

但这样一定会成功:

[tool.poetry]
name = "yolo"
version = "1.0.0"
description = ""
authors = []

[tool.poetry.dependencies]
python = "2.7"
Django = "*"
ipdb = {version = "*", optional = true}

[tool.poetry.dev-dependencies]
pytest = "*"

[tool.poetry.extras]
dev_tools = ["ipdb"]

谢谢!这在“poetry”文档中有记录吗?我找不到它,一直在苦苦寻找为什么我的额外组件无法安装,直到我找到了你的答案。 - blthayer
正是我的想法,诗歌在文档中的额外内容方面有些枯燥,所以我花了相当长的时间来弄清楚它们。 - Drachenfels
@Drachenfels 我不明白...如果你把它放在[tool.poetry.dependencies]里,它不是总会被安装吗? - rjurney
作为应用程序/库维护者,将“dev-dependencies不能成为extras的一部分”视为常识似乎是有道理的,因为dev dependencies从未成为_distribution_的一部分。您讨论的可能是不同的dev-setups,就poetry而言,只有一个单数dev-all。 - Arne
Jfc,我不是说你做错了,我只是想说我能理解为什么诗歌作者们对这种用例视而不见(当我写下我的答案时,我也是如此)。这是用户遇到的问题,所以至少应该有文档记录。 - Arne

9

现在这是可能的(使用Poetry版本1.2; 甚至较早版本),使用"extras"组:

poetry add redis --group=extras

它将出现在该部分。
[tool.poetry.group.extras.dependencies]

相较于[tool.poetry.extras][tool.poetry.extras.dependencies],这也是较新的样式。

查看文档。有趣的是,这仍然遵循较旧的样式[tool.poetry.extras],并未显示使用poetry add,但上述结果是我得到的。


6

Up-voted Drachenfels's answer.

Dev dependency不能是可选的,否则无论你如何通过extras进行调整或使用poetry install -E重试,它都将无法安装。

这听起来像一个bug但不知何故是设计如此,

...我不想添加这个。在打包项目时,额外选项将在分布式元数据中引用,但开发依赖关系不会,在包含额外选项的情况下会导致崩溃。

— 一位维护者在 Poetry PR#606 评论中总结。有关详细上下文,请参见此处:https://github.com/python-poetry/poetry/pull/606#issuecomment-437943927


我想说,我可以接受可选的dev-dependency无法实现这一事实。但是,至少Poetry应该在我有这样的配置时警告我。如果是这样,我就不会长时间困惑,阅读帮助手册的每个角落而找不到有用的信息了。


我发现有些人陷入了这个问题 (Is poetry ignoring extras or pyproject.toml is misconfigured?)但他们的问题已关闭,并标记为重复并重新链接到这个问题。因此,我决定在这里回答并提供有关此问题的更多详细信息。


我也遇到过这个问题,使用pip安装package[extra]时,它倾向于安装"正确"版本的extra,并且我安装的许多包都以这种方式使用它,所以我总是优先选择安装packageextra。我猜测poetry应该能够正确解决这个问题,但是当我输入poetry add package[extra]时,我希望它将两者都视为必需的。 - David Waterworth

0
我曾经遇到过类似的问题,似乎从1.4.2版本开始,我们可以使用可选的“groups”。我首先将可选组添加到“pyproject.toml”文件中:
[tool.poetry.group.optionalgroup]
optional = true

[tool.poetry.group.optionalgroup.dependencies]

然后,将所需的包添加到该组中:
poetry add optionalpackage --group optionalgroup

然后使用这个命令进行安装。
poetry install --with optionalgroup

请在诗歌文档中查看有关可选组的更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接