pip:为啥有时安装为鸡蛋,有时安装为文件

Posted

技术标签:

【中文标题】pip:为啥有时安装为鸡蛋,有时安装为文件【英文标题】:pip: Why sometimes installed as egg, sometimes installed as filespip:为什么有时安装为鸡蛋,有时安装为文件 【发布时间】:2015-03-13 22:28:24 【问题描述】:

在哪里可以强制 pip 安装为“flat”而不是“egg”。

对我来说,这似乎是随机的。有时它安装为鸡蛋,有时安装为平面。

pip help install 仅显示一个选项--egg,它强制安装鸡蛋。但我找不到--flat 选项。

这些包来自一个自己的 pypiserver,并像这样上传:

python setup.py sdist upload -r internal

安装过程中 pip 的输出:

Best match: foo-client 2015.2
Downloading https://installserver:40443/pypi/packages/foo_client-2015.2.tar.gz
Processing foo_client-2015.2.tar.gz
Writing /home/bar_eins_daad/tmp/easy_install-z20B7b/foo_client-2015.2/setup.cfg
Running foo_client-2015.2/setup.py -q bdist_egg --dist-dir /home/bar_eins_daad/tmp/easy_install-z20B7b/foo_client-2015.2/egg-dist-tmp-GO1snX

我不知道为什么在这里使用bdist_egg。它会强制创建 egg 安装吗?

setup.py 确实使用 setuptools 而不是 distutils

我们的 pypiserver 上的包是这样的:

tar -tzf packages/foo_client-2015.3.tar.gz

内容:

foo_client-2015.2/
foo_client-2015.2/foo_client.egg-info/
foo_client-2015.2/foo_client.egg-info/SOURCES.txt
foo_client-2015.2/foo_client.egg-info/top_level.txt
foo_client-2015.2/foo_client.egg-info/dependency_links.txt
foo_client-2015.2/foo_client.egg-info/PKG-INFO
foo_client-2015.2/setup.cfg
foo_client-2015.2/PKG-INFO
foo_client-2015.2/foo_client/
foo_client-2015.2/foo_client/models.py
...

背景

如果安装了 zipped egg,pip 似乎有时会多次安装软件包。

更新

我发现包在什么情况下被安装为 egg:如果它是通过python setup.py develop 安装的(它是一个 install_requires 依赖项)。

如果我使用pip install foo_client,它会被平装(我想要的方式)。

更新2

非常丑陋的部分:如果安装了egg,则安装的旧版本不会被删除。

版本:pip 1.5.6

【问题讨论】:

您能详细说明一下吗?例如,--egg 选项用于使 pip 安装一个鸡蛋(二进制)发行版(如果可用),而不是从源代码安装(默认)。你能给我们一些展示差异的示例包吗? 是否没有公开可用的软件包表现出这种行为? 那么您肯定可以从那些说明您所谈论的行为的包中找到一个包。这与提供包裹的服务器无关。 install_requires 确实将要求安装为鸡蛋。它不会删除其他版本,因为现在安装的只是一个安装依赖项。在任何情况下,您都可以在安装完成后再次删除它们。 我的错误,我很抱歉。我被 setup_requires 搞混了。 install_requires 应该导致安装鸡蛋,pip 仍然会正确安装。 【参考方案1】:

如果您是包的作者,则可以在setup.py 中使用标志zip_safe=False

setup(
    name = "HelloWorld",
    ...
    zip_safe = False,
)

如果您是用户,想要改进包,可以通过pip install -e foo_package 安装。选项 -e--editable 以可编辑模式(即 setuptools “开发模式”)安装项目,而不是压缩。它创建一个从源到site-packages 的链接并编译.../bin 脚本,但它不会将源复制到“站点包”中。这些软件包无法自动更新。这就是为什么它不是作为安装包的常用方式的主要原因,而只是用于那些需要定制或修复的包。

编辑:Django 是一个典型的框架,它的应用程序需要zip_safe=False,因为它们不是纯 Python,但它们还包含带有 html、css、i18n 资源等的模板。您的问题与 Django 相关吗?

【讨论】:

很遗憾,我不是包的作者。我现在找到了解决方案。见***.com/questions/27964960/… 当您编写自己的包时,这对于控制 *.egg 文件夹的创建实际上非常有用。谢谢! 谢谢,我刚刚修复了一个 django 包:-D【参考方案2】:

我遇到了与@guettli 相同的问题,并通过先解压缩并提取存档然后运行来解决它:

pip -e install /srv/mypkg-1.1.0

其中 /srv/mypkg-1.1.0/ 是项目/包的***目录,其中包含 setup.py 文件。

mypkg-1.1.0 安装在 site-packages 中,mypkg.py 列在 [virtualenv]/bin 中

注意:'-e' 标志是可选的。

谢谢

【讨论】:

自从发布以来,我已经学会了 'pip install' 和 '-e',可编辑选项;以“开发者模式”安装软件包。在项目目录中创建 /srv/mypkg-1.1.0/mypkg.egg-info 目录。无需每次都构建包即可编辑源代码。 不推荐用于生产安装。因此,根据我的原始帖子,我不确定从 tarball 还是从平面文件安装是否会有所不同,因为我第一次安装它时,我的 tarball 位于 /tmp 中,并且据我所知,egg-info 目录可能已经在那里创建。我必须测试才能确认。【参考方案3】:

Some docs说:

为了获得最佳性能,最好将 Python 包安装为 zip 文件。

您可以将 zip_safe 参数的 True 或 False 值传递给 setup() 函数,也可以省略它。如果你省略它,bdist_egg 命令将分析您的项目的内容,看看它是否可以检测到 任何会阻止它在 zipfile 中工作的条件。

所以这可能没问题,除非……你的情况不好。我的项目尝试读取文件,但由于压缩而失败。

值得注意的是,这只发生在python setup.py install,而不是pip install . @guettli 的修复工作正常,但我把它放在setup.cfg

[easy_install]
zip_ok = False

【讨论】:

【参考方案4】:

我遇到了这个 egg-only 安装问题,结果我未能在我的包的根目录中添加 __init__.py。这让我发疯了:

pip install .

...但这会失败:

mkdir /tmp/piptest
cd /tmp/piptest
git clone $OLDPWD .
pip install .

使用diff -r . $OLDPWD 很难注意到差异,因为有很多未提交的 pyc 文件和开发工具脚本。

这可能不是这个 OP 的答案,但我希望它可以帮助像我一样在谷歌上“只安装鸡蛋”的人。

【讨论】:

为我的包添加一个子文件夹(和一个__init__.py,必要吗?)是我的答案。谢谢 我很高兴它帮助了你,@BrianPeterson。但老实说,我对 Google 引导我提出的问题给出了这样的答案,因为在几年后的某个时候,我会再次需要它。【参考方案5】:

这并不能解决为什么我有时会得到带拉链的鸡蛋,有时却没有的问题。但它有帮助。

您可以在~/.distutils.cfg 中使用它来避免安装压缩鸡蛋:

[easy_install]
zip_ok = False

【讨论】:

以上是关于pip:为啥有时安装为鸡蛋,有时安装为文件的主要内容,如果未能解决你的问题,请参考以下文章

composer 使用组件安装程序将 jquery 插件安装为组件

Tomcat 安装为服务后台自动启用

如何将 keycloak 安装为服务,使其自动启动?

Autojump安装为oh-my-zsh插件

将 MsiPackage 安装为 /passive(WIX 工具集)

如何防止 setuptools 将包安装为 .egg