如何在setup.py中指定递归依赖关系?

3
我在使用 pipsetuptools 进行 Python 打包时遇到了一些困难,需要理解和实现一些细节。
假设我有三个项目,ABC,每个项目都是自己的包并托管在自己的代码库中。它们还相互依赖,即 AB 导入,而 BC 导入。每个包都有一组 直接 依赖项(即直接导入的其他包)和一组 间接 依赖项(即由直接依赖包导入的包)。这些依赖关系是一个图,而不是树形结构。
对于包 A setup.py 应该只包含直接依赖的包吗?对于包 B 也是一样吗?当我安装 C 时,我注意到 B 被安装了,但是没有安装 A。我想这是因为 AC 的间接依赖。
我不太喜欢在每个软件包中存储 pip freeze 的想法(缺乏灵活性且存在冲突),但看起来 pip 无法递归解析依赖关系图(请参见此处)。snakebasket项目试图解决这个问题,但现在已经过时。dependency-links选项已被弃用。
正确和推荐的处理方式是什么? 补充说明:我忘了提到这些软件包(ABC)都不在官方的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 的设置。

2个回答

0
对于包A,setup.py文件是否只应包含直接依赖的包?
是的。关注点分离:每个包都应列出其所需的依赖项。子包应自行处理。
当我使用pip install C时,我注意到B被安装了,但A没有被安装。你能举个例子吗?我的经验不同。
看起来pip不会递归解析依赖图(请参见here)。2015年的答案已经过时了。pip installpip download会递归地安装和下载依赖项。

抱歉,我应该提到这些包存在私有仓库中。请参见上面的附录 - Jens

0
如何在setup.py中指定递归依赖项?
不要这样做。
那么正确和推荐的处理方式是什么? setup.py应该在install_requires=[...]下列出直接依赖项。不要列出传递性依赖项。也不要在此处固定依赖项(尽管在某些情况下,您可能希望指定上限或下限以确保收集兼容版本)。
当我使用pip install C时,我注意到B被安装了,但没有安装A
那么B没有正确指定对A的依赖关系。再次检查B的元数据。
虽然pip有时无法正确解析依赖树,并且自2013年以来存在开放问题,但您不会在简单的C -> B -> A依赖图中看到它,只有在某些更病态的情况下才会出现。

请查看我的项目johnnydep,以渲染依赖树并指示包元数据中缺少“分支”的位置。


抱歉,我应该提到这些包存在私有仓库中。请参见上面的附录 - Jens
1
是的,那是需要包含的重要信息!dependency_links 已经被废弃了一段时间了。最好的方法是将包托管到软件包索引中-不一定是 PyPI,它可以是私有索引-而不是尝试直接从 Github 依赖(这不能满足 简单存储库 API,因此在使用 pip 时无法正常工作)。 - wim
是的,那篇文章仍然有效。我建议使用devpi-server - wim
另外还有一个问题:能否在setup.py中指定私有索引?我知道 pip -i 可以工作,或者在 ~/.pip/pip.conf 中添加 index-url这里)。但是,我认为将我的私有索引服务器指定为 setup.py 的一部分会更有意义(我认为 dependency_links 处理了这个问题)。此外,您对 这种方法 有什么看法? - Jens
1
不,这是不可能的。用户必须选择使用非标准索引而不是包。如果您可以在setup.py元数据中添加从某个随机网站获取依赖项的选项,那么黑客就会轻松地分发恶意代码。 - wim
显示剩余2条评论

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