Pip pyproject.toml:可选依赖组是否可以要求其他可选依赖组?

12

我正在使用最新版本的pip,23.01。我有一个带有依赖项和可选依赖组(也称为“extras”)的pyproject.toml文件。为了避免冗余并更容易管理可选依赖组,我想知道如何让可选依赖组需要其他可选依赖组。

我的pyproject.toml中的可选依赖组在依赖项上存在冗余重叠。我猜它们可以被描述为“分层”。它看起来像这样:

[project]
name = 'my-package'
dependencies = [
    'pandas',
    'numpy>=1.22.0',
    # ...
]

[project.optional-dependencies]
# development dependency groups
test = [
    'my-package[chem]',
    'pytest>=4.6',
    'pytest-cov',
    # ...
    # Redundant overlap with chem and torch dependencies
    'rdkit',
    # ...
    'torch>=1.9',
    # ...
]

# feature dependency groups
chem = [
    'rdkit',
    # ...
    # Redundant overlap with torch dependencies
    'torch>=1.9',
    # ...

]
torch = [
    'torch>=1.9',
    # ...
]

在上面的例子中,pip install .[test] 将包括所有 chemtorch 组的软件包,而 pip install .[chem] 将包括 torch 组的软件包。

通过删除重叠和对另一个组的引用,用户仍然可以通过执行 pip install .[chem,torch] 来获取所需的 chem 软件包,但是我与数据科学家合作,他们可能不会立即意识到 torch 组是 chem 组的要求等。

因此,我想要一个类似于这样的文件:

[project]
name = 'my-package'
dependencies = [
    'pandas',
    'numpy>=1.22.0',
    # ...
]

[project.optional-dependencies]
# development dependency groups
test = [
    'my-package[chem]',
    'pytest>=4.6',
    'pytest-cov',
    # ...
]

# feature dependency groups
chem = [
    'my-package[torch]',
    'rdkit',
    # ...
]
torch = [
    'torch>=1.9',
    # ...
]

这种方法行不通,因为my-package托管在我们的私有pip存储库中,所以像上面的例子一样使用'my-package[chem]'会获取先前构建版本的chem组包。

似乎使用Poetry及其pyproject.toml格式/功能可以实现此目的,但我宁愿不太改变我们的构建系统。这是否可能使用pip?


我会使用Makefile而不是直接调用pip,这通常更好,因为可以在项目之间保持一致性。如果您的所有项目都有make install或install-xx用于xx组,则可以将make install作为整个组织的标准方式。 - Omar
@Omar,我会研究一下Makefiles。这里有一个网页或其他资源可以更详细地描述你的建议吗? - James
1
@sinoroc 抱歉造成困惑!pip包的私有性并不是问题,问题在于它最初是托管在pip存储库中的。如果我将my-package[torch]作为chem组依赖项编写,它将从存储库的最新托管版本安装,而不是安装在pyproject.toml中新指定的torch组。我尝试使用点语法,例如.[torch],希望这样可以解决问题,但显然pip无法在pyproject.toml文件中识别它。很高兴了解到Poetry的差异!我对Poetry还不太熟悉。 - James
你提到的问题非常准确。似乎从未得到解决?是否值得在pip上提出问题? - James
@Omar,感谢您提供的Makefile示例。我以前从未使用过make(除了安装Python)。这为我的这个项目以及其他项目提供了一些思考。 - James
显示剩余6条评论
1个回答

4
也许将这两个依赖组合并成一个值得一试,看看是否像“all”中所示解决了问题。
[project]
name = "foo"
version = "0.1.0"

[project.optional-dependencies]
socks = ["pysocks"]
jwt = ["pyjwt"]
all = ["foo[socks,jwt]"]

这与PDM无关,实际上已经在问题本身中涵盖了。因此,我不确定这个答案对讨论有什么贡献。 - sinoroc
问题本身没有涉及到这一点,想法是将 foo[socks,jwt] 绑定到 all 上,然后解决优先级问题,或者我在这里有什么误解吗? - Omar
啊,我明白了。但是据我理解,问题在另一个层面上。也许是pip中的一个bug?虽然这似乎不太可能。很难说。-- 无论如何,你所展示的符号并不特定于PDM,它是这个规范的一部分,被许多工具实现,而不仅仅是PDM。 - sinoroc
也许更简单一点?all = [".[袜子,JWT]"] - undefined
不行,这会产生一个ValueError错误。必须是pep508格式。 - undefined
显示剩余2条评论

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