如何让 pip 递归搜索目录中的包和依赖项?

Posted

技术标签:

【中文标题】如何让 pip 递归搜索目录中的包和依赖项?【英文标题】:How to have pip recurisvely search directories for packages and dependencies? 【发布时间】:2018-08-28 13:25:25 【问题描述】:

pip 是否能够递归搜索文件系统路径并安装包及其依赖项?例如,给定以下文件结构(文件未显示)pip install packageA -f C:\packages\ 不起作用。

C:\packages\
C:\packages\packageA\
C:\packages\packageA\1.0.0
C:\packages\packageA\1.0.1

C:\packages\packageB\
C:\packages\packageB\2.2.1
C:\packages\packageB\2.2.4

另外,这些包可以是带有 setup.py 文件的纯源代码吗?或者它们是否需要像***或 zip 文件这样的二进制文件。最后,有没有办法解决依赖关系?例如,如果 packageA 需要某个版本的 packageB,pip 可以从我的文件夹中获取该版本的 packageB 吗?我是否需要 html 文件来指示事物的位置和内容?

我知道我可以将 pip 直接指向本地路径 (pip install C:\packages\packageA\1.0.0),但我希望它的功能就像包在 PyPI 中可用一样。例如,如果用户键入 pip install packageBpip install requirements.txt 并且该需求文件包含本地存在但 PyPI 中不存在的包,则它可以正常工作。 (我可以在配置文件中设置本地包存储路径,这样 pip 命令就不需要 -f 参数了)

基本上,我想使用没有网络服务器的文件系统复制 PyPI 功能(安全性不允许我们运行)。任何见解将不胜感激。

【问题讨论】:

【参考方案1】:

我想通了。我使用了一个名为 pip2pi 的包。这个包有一个叫做 dir2pi 的命令。我创建了一个包含 tar.gz 文件的目录。每个 tar.gz 文件都是使用 this layout 创建的 Python 包。为了识别版本,我添加了一个连字符,然后使用语义版本控制。

目录如下所示:

C:\packages\package_a-1.0.8.tar.gz
C:\packages\package_a-1.1.0.tar.gz
C:\packages\package_b-2.0.0.tar.gz
C:\packages\package_c-1.0.5.tar.gz

然后我跑了,dir2pi C:\packages -S。这创建了必要的 HTML 文件和文件夹布局。在文件夹的根目录下,创建了一个名为 simple 的文件夹。 simple 这个名字似乎是 PEP 503 的东西。在 simple 内部,文件夹结构如下所示:

C:\packages\simple\index.html

C:\packages\simple\package_a
C:\packages\simple\package_a\index.html
C:\packages\simple\package_a\package_a-1.0.8.tar.gz
C:\packages\simple\package_a\package_a-1.1.1.tar.gz

C:\packages\simple\package_b
C:\packages\simple\package_b\index.html
C:\packages\simple\package_b\package_b-2.0.0.tar.gz

C:\packages\simple\package_c
C:\packages\simple\package_c\index.html
C:\packages\simple\package_c\package_c-1.0.5.tar.gz

这显然是符合 pip 的文件/文件夹布局。

每个 index.html 文件都包含指向其相邻文件和文件夹的链接。例如,C:\packages\simple\index.html 如下所示:

<html><head><title>Simple Index</title><meta name='api-version' value='2' /></head><body>
<a href='package_a/'>package_a</a><br />
<a href='package_b/'>package_b</a><br />
<a href='package_c/'>package_c</a><br />
</body></html>

C:\packages\simple\package_a\index.html 看起来像这样:

<a href='package_a-1.0.8.tar.gz'>package_a-1.0.8.tar.gz</a><br />
<a href='package_a-1.1.1.tar.gz'>package_a-1.1.1.tar.gz</a><br />

现在有了正确的 HTML 文件和文件夹结构,我告诉 pip 在 C:\packages\simple 文件夹中查找包。我通过编辑 pip.ini 文件(位置因系统而异)并添加以下行来做到这一点:

[global]
extra-index-url = file:///c:/packages/simple

或者,我也可以将此文件夹作为参数传递给 pip,如下所示:

pip install --index-url=file:///c:/packages/simple package_a==1.1.1

【讨论】:

这听起来更好,但是如果我的 packages/ 文件夹包含许多子文件夹和子文件夹怎么办?那么 pip2pi 不能给出正确的 simple/ 文件夹。【参考方案2】:

pip 是否能够递归搜索...?

没有。一个平面目录或一个预先生成的列出子目录中文件的 html 文件。

另外,这些包可以是带有 setup.py 文件的纯源代码吗?

是的。 pip 可以安装源码发行版、鸡蛋和***。

最后,有没有办法解决依赖关系?

是的,但它们必须是可访问的。也就是说,一个类似 PyPI 的服务器(不一定是 PyPI)、一个平面目录或一个 html 文件。

PS。为了防止 pip 在 PyPI 中查看包,请使用选项 --no-index

【讨论】:

以上是关于如何让 pip 递归搜索目录中的包和依赖项?的主要内容,如果未能解决你的问题,请参考以下文章

如何`pip install` 一个具有 Git 依赖项的包?

pip:带你认识一个 Python 开发工作流程中的重要工具

如何识别哪些 npm 包只是对等依赖项?

pip 需求文件中的可选依赖项

Python setup.py:如何让 find_packages() 识别子目录中的包

Python 3基础教程11-如何利用pip命令安装包和模块