pip:为什么有时安装为egg,有时安装为文件?

15

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

对我来说,它似乎是随机的。有时候会安装为 egg,有时候会安装为 flat。

pip help install 只显示了一个选项 --egg,它强制进行 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

content:

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
...

背景

如果安装了压缩的egg包,pip有时会多次安装软件包。

更新

我发现一个条件,即软件包通过python setup.py develop安装为egg包(它是一个install_requires依赖项)。

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

更新2

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

版本:pip 1.5.6


1
是否根本没有公开可用的软件包展示这种行为? - Martijn Pieters
1
那么,你肯定可以在这些包中找到一个展示你所说的行为的例子。这与提供包的服务器无关。 - Martijn Pieters
1
install_requires确实会将要求安装为egg。它不会删除其他版本,因为现在安装的只是安装依赖项。无论如何,您都可以在安装完成后再次删除它们。 - Martijn Pieters
@MartijnPieters 我想要将Python包安装为平面文件而不是egg文件。无论包是通过pip直接安装还是通过python setup develop安装,都不应该有影响。 - guettli
1
我的错误,我道歉。我把 setup_requiresinstall_requires 搞混了。install_requires 不应该导致安装 egg 包, pip 会正确地安装这些依赖项。 - Martijn Pieters
显示剩余9条评论
5个回答

7

这并没有解决为什么有时我收到的是压缩的蛋,有时不是的问题。但它会有所帮助。

您可以在~/.distutils.cfg中使用此方法来避免安装压缩的蛋:

[easy_install]
zip_ok = False

6

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

直接使用格式要求进行翻译。
setup(
    name = "HelloWorld",
    ...
    zip_safe = False,
)

如果您是想要改进软件包的用户,则可以通过pip install -e foo_package安装它。选项-e--editable以可编辑模式(即setuptools "develop mode")安装项目,而不是压缩。它会在源代码和site-packages之间创建链接,并编译.../bin脚本,但不会将源代码复制到"site-packages"中。这些软件包无法自动更新。这就是为什么它不是安装软件包的常规方式,而仅用于需要定制或修复的软件包的主要原因。

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


很遗憾,我不是这个包的作者。但我现在找到了一个解决方案。请参考https://dev59.com/AV4c5IYBdhLWcg3wY5qW#29127158 - guettli
这实际上非常有用,当你编写自己的软件包时,可以控制*.egg文件夹的创建。谢谢! - Ulises Rosas-Puchuri
谢谢,我刚刚修复了一个 Django 包 :-D - am70

2

我遇到了一个只安装鸡蛋的问题,结果发现我没有将包根目录下的__init__.py添加到git中。这让我很疯狂,因为这个命令可以正常工作:

pip install .

...但是这样会失败:

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

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

这可能不是此问题的答案,但我希望它能帮助像我一样通过Google搜索“pip仅安装egg”的人。


1
为我的包添加一个子文件夹(并在其中加入一个__init__.py文件,是否必要?)是我的答案。谢谢。 - Brian Peterson
我很高兴它能帮到你,@BrianPeterson。但说实话,我会在Google搜索到的问题上提供这样的答案,因为未来几年的某个时候,我可能还需要它。 - Bruno Bronosky

1
我和@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目录是否已经在那里创建。我需要进行测试以确认。 - consmith2

0

一些文档 表示:

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

并且

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

因此,除非... 在你的情况下不行。我的项目尝试读取文件,由于压缩而失败了。

值得注意的是,这只发生在 python setup.py install 而不是 pip install . @guettli 的修复方法很好用,但我将其放在了 setup.cfg 中:

[easy_install]
zip_ok = False

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