【问题标题】:can I make a virtualenv into an egg我可以把一个 virtualenv 变成一个鸡蛋吗
【发布时间】:2017-03-03 03:02:31
【问题描述】:

我可以使用 setuptools 制作一个 python 蛋:python setup.py bdist_egg。理论上,我应该能够为每个安装了 setup.py 文件的软件包执行此操作。是否可以将整个virtualenv虚拟python环境封装成一个python egg?

【问题讨论】:

  • 你的项目的文件结构布局是怎样的?

标签: python virtualenv egg


【解决方案1】:

我特别需要将任意数量的 Python 包打包成一个.egg,因为我使用的系统只接受鸡蛋,每个鸡蛋都需要单独列出,当所需的包裹数量发生变化时,这变得非常笨拙。

.egg 文件只是一个 .zip,其中包含一个名为 EGG-INFO 的元数据文件夹在其名称中的版本号。您基本上可以cd lib/python-x.y/site-packages,然后zip -r spaghetti-0.0.1.egg 将内容压缩到 spaghetti-0.0.1.egg 文件中,但您确实需要元数据

如果您很幸运并且没有使用入口点或其他此类高级功能的软件包,您可以在site-packages 中创建一个名为EGG-INFO 的目录,其中包含以下文件:

dependency_links.txt
entry_points.txt
not-zip-safe
PKG-INFO
requires.txt
top_level.txt

除了包含以下内容的PKG-INFO之外的所有

Metadata-Version: 1.1
Name: spaghetti
Version: 0.0.1

and top_level.txt 包含您的 virtualenv 中的 all 顶级包名称,每行一个,即如果您已安装命名空间包 zope.componentsqlalchemy,你的top_level.txt应该有

zope
sqlalchemy

当然,事情并不总是这么简单。对于 Python 2.7 上的命名空间包(zope.component 就是这种情况),有一些神奇的 .pth 条目。对于这些,您需要在包中创建空的__init__.pys,或者在EGG-INFO/namespace_packages.txt 中列出它们;对于zope.componentzope 是一个没有__init__.py 的命名空间包,所以EGG-INFO 应该有namespace_packages.txt 一行zope。然而,Python 3 中的命名空间打包应该可以在没有这个中间步骤的情况下按原样工作。

同样,如果你需要使用入口点,你需要将所有包的 egg 信息中的 entrypoints.txt 连接到你 egg 的 entrypoints.txt 中。

更正:你不能以这种方式做入口点,无论如何也不能没有任何严重的黑客攻击。分发名称(在本例中为 spaghetti)将用于所有入口点,而不是包名称。没有直接的方法可以规避这一点。


最后,wheel 确实可以被认为是优于egg 的格式,但它们不兼容,如果您可以您应该使用wheel 来打包虚拟环境。但是,如果一个系统特别希望有一个旧的.egg 文件格式的文件,它就不能使用wheel。此外,.egg 有时不需要安装,它可以从PYTHON_PATH 直接使用...

【讨论】:

    【解决方案2】:

    你不应该这样做有几个原因

    即使您能够做到这一点,它也不会像您期望的那样工作。如果用户已经在你的 egg 中安装了其中一个包,它们会发生冲突,因为 python egg 不会添加额外的命名空间。

    另外,蟒蛇蛋也快要消失了。如果你想创建一个二进制发行版,你应该使用较新的 python wheels

    如果您的项目有依赖项,只需在 setup.py 中声明这些依赖项,pip 就会处理安装它们。如果你有一些 PyPi 上不存在的依赖项,或者你需要一个非常特定的旧版本的包,只需将这些包作为子包包含在你的包中。

    /my_package
        __init__.py
        /libs
            __init__.py
            /non_pypi_package
            /legacy_package 
    

    然后在您的代码中,而不是将它们导入为

    import non_pypy_package
    

    你会使用

    from my_package.libs import non_pypi_package
    

    【讨论】:

    • 我使用鸡蛋的方式我能够存储一个编译的 C/Fortran 包,它是 python 包的依赖项。有没有办法我仍然可以做到这一点?
    • 您可以使用setup 函数的package_data 参数来实现。如果您提供有关项目结构的更多信息,我可以添加确切的命令以包含它们。
    • 我不确定如何以您描述的方式使用 package_data。之前的答案没有那么乐观:stackoverflow.com/a/14159430/3474956。看起来没有任何现代的等价于蟒蛇蛋。
    • 车轮在现代相当于鸡蛋。
    猜你喜欢
    • 2014-03-18
    • 2011-09-02
    • 2018-09-17
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    • 2014-03-01
    • 2011-02-27
    相关资源
    最近更新 更多