我很难理解和使用pip
和setuptools
实现Python打包的一些细节。
假设我有三个项目,A
和B
C
每个项目都是自己的包,并托管在自己的代码存储库中。它们也相互依赖,即A
由B
导入,B
由C
导入。每个包都有一组直接依赖关系(即直接导入其他包)和一组间接依赖关系(即由直接依赖的包导入的包)。这些依赖项是图形,而不是树。
对于包A
,setup.py 是否应该只包含直接依赖的包?包装B
相同?当我pip install C
时,我注意到安装了B
,但没有A
。我想这是因为A
是C
的间接依赖。
我不太喜欢在每个包中存储pip freeze
的想法(不灵活且冲突隐约可见),但似乎pip
不会递归地解析依赖关系图(见这里)。snakebasket
项目试图解决这个问题,但现在已经过时了;依赖项链接选项已被弃用。
处理此问题的正确和推荐方法是什么?
附录我忘了提到没有一个软件包(A
,B
,C
)可以通过官方的PyPi存储库获得,而是存在于私有的Github存储库中。因此,例如B
的 setup.py 包含
install_requires=(
…,
A==1.0.0,
…,
)
dependency_links=[
f"https://{github_token}@github.com/repo/A/archive/v1.0.0.tar.gz#egg=A-1.0.0",
],
并且C
包含类似的包B
设置。
如何在
setup.py
中指定递归依赖关系?
不要。
处理此问题的正确和推荐方法是什么?
setup.py
应在install_requires=[...]
下列出直接依赖项。不要列出传递依赖项。并且不要在此处固定依赖项(但在某些情况下,您可能希望指定上限或下限以确保收集兼容版本)。
当我
pip install C
时,我注意到安装了B
,但没有A
.
然后B
没有正确指定对A
的依赖关系。 再次检查B
的元数据。
确实,pip 有时无法正确解析依赖树,并且自 2013 年以来一直存在一个悬而未决的问题,但您不会在简单的 C -> B -> A 依赖关系图中看到它,仅在一些更病理的情况下。
查看我的项目johnnydep
以呈现 dep 树并指出包元数据中缺少"分支"的位置。
对于包 A,
setup.py
是否应该只包含直接依赖的包?
是的。关注点分离:每个包都应该列出它需要的依赖项。子包应该照顾好自己。
当我
pip install C
时,我注意到安装了 B,但没有安装了 A。
你能举个例子吗?我有不同的经历。
似乎 pip 不会递归地解析依赖关系图(见这里)。
2015年的答案已经过时了。pip install
和pip download
以递归方式安装和下载依赖项。