跳转到主要内容

将Python包发行版作为egg安装的配方

项目描述

egg安装recipe是zc.recipe.egg的一个定制版本,允许默认安装依赖脚本。这使用了James Gardner从http://pypi.python.org/pypi/pylons_sandbox提供的代码来执行依赖脚本安装。

待办事项

  • 某种方式来冻结使用的egg版本。这包括记录哪些版本被动态选择,然后要求在后续运行中使用记录的版本。

变更历史

0.3 (2009-03-31)

  • 与zc.buildout 1.2.1兼容的更新

0.2 (2008-05-25)

  • 移除对virtualenv的虚假依赖。

0.1 (2008-02-29)

  • zc.recipe.egg 1.0.0 的分支,默认情况下会安装依赖脚本。在配方中使用 "dependent_scripts = false" 来关闭此行为。

详细文档

作为egg安装的发行版

repoze.recipe.egg:eggs 配方可用于安装各种类型的 distutils 分发为 eggs。它包含多个选项

eggs

要安装的 eggs 列表,以一个或多个 setuptools 需求字符串的形式给出。每个字符串必须在单独的一行上。

find-links

搜索分布的 URL、文件或目录列表。

index

索引服务器的 URL 或几乎任何其他有效 URL。:)

如果没有指定,则使用 Python 包索引,http://cheeseshop.python.org/pypi。您可以使用此选项指定一个替代索引。如果您使用链接选项,并且链接指向所需的分布,则索引可以是任何东西,并且将被很大程度上忽略。在下面的示例中,我们将仅指向我们的链接服务器上的一个空目录。这将使我们的示例运行得稍微快一点。

python

从该部分获取 Python 可执行文件名称。如果没有指定,则使用 buildout python 选项。Python 可执行文件位于命名部分的 executable 选项中。

我们有一个包含许多分布的链接服务器

>>> print get(link_server),
<html><body>
<a href="demo-0.1-py2.3.egg">demo-0.1-py2.3.egg</a><br>
<a href="demo-0.2-py2.3.egg">demo-0.2-py2.3.egg</a><br>
<a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br>
<a href="demo-0.4c1-py2.3.egg">demo-0.4c1-py2.3.egg</a><br>
<a href="demoneeded-1.0.zip">demoneeded-1.0.zip</a><br>
<a href="demoneeded-1.1.zip">demoneeded-1.1.zip</a><br>
<a href="demoneeded-1.2c1.zip">demoneeded-1.2c1.zip</a><br>
<a href="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
<a href="index/">index/</a><br>
<a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
</body></html>

我们有一个示例 buildout。让我们更新其配置文件以安装演示包。

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = repoze.recipe.egg:eggs
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)s/index
... """ % dict(server=link_server))

在这个例子中,我们将范围限制在 0.3 之前的版本。我们还指定了使用 find-links 选项查找分布的位置。

让我们运行 buildout

>>> import os
>>> print system(buildout),
Installing demo.
Getting distribution for 'demo<0.3'.
Got demo 0.2.
Getting distribution for 'demoneeded'.
Got demoneeded 1.2c1.

现在,如果我们查看 buildout eggs 目录

>>> ls(sample_buildout, 'eggs')
-  demo-0.2-py2.3.egg
-  demoneeded-1.2c1-py2.3.egg
-  setuptools-0.6-py2.3.egg
-  zc.buildout-1.0-py2.3.egg

我们看到我们得到了一个满足要求的 demo eggs,以及 demo 所需的 demoneeded eggs。(我们还在 develop-eggs 目录中看到了该配方的 eggs 链接。这个 eggs 链接实际上是作为示例 buildout 设置的一部分创建的。通常,当使用该配方时,您将获得常规的 eggs 安装。)

脚本生成

demo eggs 定义了一个脚本,但我们没有安装它

>>> ls(sample_buildout, 'bin')
-  buildout

如果您想安装 eggs 提供的脚本,则应使用 scripts 配方

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = repoze.recipe.egg:scripts
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)s/index
... """ % dict(server=link_server))
>>> print system(buildout),
Uninstalling demo.
Installing demo.
Generated script '/sample-buildout/bin/demo'.

现在我们还可以看到 dmo 脚本定义的脚本

>>> ls(sample_buildout, 'bin')
-  buildout
-  demo

scripts 配方定义了一些附加选项

entry-points

形式为 name=module#attrs 的入口点标识符列表,name 是脚本名称,module 是模块名称,而 attrs 是模块中的(可能带点的)对象名称。此选项在处理未声明入口点的分布时很有用,例如未针对 setuptools 编写的分布。

scripts

控制哪些脚本被生成。值应该是零个或多个标记的列表。每个标记要么是名称,要么是名称后跟一个 '=' 和新名称。仅生成命名的脚本。如果没有给出标记,则禁用脚本生成。如果没有提供此选项,则将生成命名 eggs 定义的脚本。

interpreter

生成一个允许访问具有基于已安装 eggs 设置的路径的 Python 解释器的脚本的名称。

extra-paths

在生成的脚本中包含的额外路径。

initialization

指定一些 Python 初始化代码。这是非常有限的。特别是,请注意,从提供的代码中删除了前导空格。

arguments

以 Python 源的形式指定传递给入口点的参数。

让我们添加一个解释器选项

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = repoze.recipe.egg
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)s/index
... interpreter = py-demo
... """ % dict(server=link_server))

请注意,我们在配方规范中省略了入口点名称。我们之所以能够这样做,是因为 scripts 配方是 repoze.recipe.egg eggs 的默认入口点。

>>> print system(buildout),
Uninstalling demo.
Installing demo.
Generated script '/sample-buildout/bin/demo'.
Generated interpreter '/sample-buildout/bin/py-demo'.

现在我们还获得了一个py-demo脚本,该脚本可以为我们提供一个带有demo路径及其依赖的eggs的Python提示符。这对于调试和测试非常有用。

>>> ls(sample_buildout, 'bin')
-  buildout
-  demo
-  py-demo

如果我们运行demo脚本,它会打印出一些最小数据

>>> print system(join(sample_buildout, 'bin', 'demo')),
2 2

它打印出的值恰好是已安装模块中定义的值。

我们还可以运行py-demo脚本。这里我们只打印出反映eggs的路径中的位

>>> print system(join(sample_buildout, 'bin', 'py-demo'),
... """import os, sys
... for p in sys.path:
...     if 'demo' in p:
...         print os.path.basename(p)
...
... """).replace('>>> ', '').replace('... ', ''),
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
demo-0.2-py2.4.egg
demoneeded-1.2c1-py2.4.egg

egg更新

配方通常获取满足指定条件的最新分布。如果buildout在非最新模式或离线模式,则不会这样做。为了了解它是如何工作的,我们将从demo中移除限制并以非最新模式运行buildout

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = repoze.recipe.egg
... find-links = %(server)s
... index = %(server)s/index
... """ % dict(server=link_server))

并运行buildout

>>> print system(buildout+' -N'),
Uninstalling demo.
Installing demo.
Generated script '/sample-buildout/bin/demo'.

请注意,我们已经移除了eggs选项,eggs默认为部分名称。因为我们移除了eggs选项,所以demo被重新安装。

我们还将以离线模式运行buildout

>>> print system(buildout+' -o'),
Updating demo.

我们没有为demo获取更新

>>> ls(sample_buildout, 'eggs')
-  demo-0.2-py2.3.egg
-  demoneeded-1.2c1-py2.3.egg
-  setuptools-0.6-py2.3.egg
-  zc.buildout-1.0-py2.3.egg

如果我们以默认的在线和最新模式运行buildout,我们将为demo获取更新

>>> print system(buildout),
Updating demo.
Getting distribution for 'demo'.
Got demo 0.4c1.
Generated script '/sample-buildout/bin/demo'.

然后我们将得到一个新的demo egg

>>> ls(sample_buildout, 'eggs')
-  demo-0.2-py2.3.egg
-  demo-0.4c1-py2.3.egg
-  demoneeded-1.2c1-py2.3.egg
-  setuptools-0.6-py2.4.egg
-  zc.buildout-1.0-py2.4.egg

脚本也已更新

>>> print system(join(sample_buildout, 'bin', 'demo')),
4 2

控制脚本生成

您可以使用脚本选项来控制要生成的脚本。例如,要抑制脚本,请使用不带任何参数的脚本选项

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = repoze.recipe.egg
... find-links = %(server)s
... index = %(server)s/index
... scripts =
... """ % dict(server=link_server))
>>> print system(buildout),
Uninstalling demo.
Installing demo.
>>> ls(sample_buildout, 'bin')
-  buildout

您还可以控制脚本使用的名称

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = repoze.recipe.egg
... find-links = %(server)s
... index = %(server)s/index
... scripts = demo=foo
... """ % dict(server=link_server))
>>> print system(buildout),
Uninstalling demo.
Installing demo.
Generated script '/sample-buildout/bin/foo'.
>>> ls(sample_buildout, 'bin')
-  buildout
-  foo

指定额外的脚本路径

如果我们需要在脚本中包含额外的路径,我们可以使用extra-paths选项

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = repoze.recipe.egg
... find-links = %(server)s
... index = %(server)s/index
... scripts = demo=foo
... extra-paths =
...    /foo/bar
...    /spam/eggs
... """ % dict(server=link_server))
>>> print system(buildout),
Uninstalling demo.
Installing demo.
Generated script '/sample-buildout/bin/foo'.

让我们看看生成的脚本

>>> cat(sample_buildout, 'bin', 'foo') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.4
<BLANKLINE>
import sys
sys.path[0:0] = [
  '/sample-buildout/eggs/demo-0.4c1-py2.4.egg',
  '/sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg',
  '/foo/bar',
  '/spam/eggs',
  ]
<BLANKLINE>
import eggrecipedemo
<BLANKLINE>
if __name__ == '__main__':
    eggrecipedemo.main()

指定初始化代码和参数

有时,我们需要做的不仅仅是调用入口点。我们可以使用初始化和参数选项来指定要包含在生成的脚本中的额外代码

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = repoze.recipe.egg
... find-links = %(server)s
... index = %(server)s/index
... scripts = demo=foo
... extra-paths =
...    /foo/bar
...    /spam/eggs
... initialization = a = (1, 2
...                       3, 4)
... arguments = a, 2
... """ % dict(server=link_server))
>>> print system(buildout),
Uninstalling demo.
Installing demo.
Generated script '/sample-buildout/bin/foo'.
>>> cat(sample_buildout, 'bin', 'foo') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.4
<BLANKLINE>
import sys
sys.path[0:0] = [
  '/sample-buildout/eggs/demo-0.4c1-py2.4.egg',
  '/sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg',
  '/foo/bar',
  '/spam/eggs',
  ]
<BLANKLINE>
a = (1, 2
3, 4)
<BLANKLINE>
import eggrecipedemo
<BLANKLINE>
if __name__ == '__main__':
    eggrecipedemo.main(a, 2)

在这里,我们看到我们指定的初始化代码在设置路径后被添加。注意,如上所述,前导空白已被删除。同样,我们指定的参数代码在入口点调用(到main)中添加。

指定入口点

可以为显式声明的入口点生成脚本。我们可以使用entry-points选项声明入口点

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = repoze.recipe.egg
... find-links = %(server)s
... index = %(server)s/index
... extra-paths =
...    /foo/bar
...    /spam/eggs
... entry-points = alt=eggrecipedemo:alt other=foo.bar:a.b.c
... """ % dict(server=link_server))
>>> print system(buildout),
Uninstalling demo.
Installing demo.
Generated script '/sample-buildout/bin/demo'.
Generated script '/sample-buildout/bin/alt'.
Generated script '/sample-buildout/bin/other'.
>>> ls(sample_buildout, 'bin')
-  alt
-  buildout
-  demo
-  other
>>> cat(sample_buildout, 'bin', 'other')
#!/usr/local/bin/python2.4
<BLANKLINE>
import sys
sys.path[0:0] = [
  '/sample-buildout/eggs/demo-0.4c1-py2.4.egg',
  '/sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg',
  '/foo/bar',
  '/spam/eggs',
  ]
<BLANKLINE>
import foo.bar
<BLANKLINE>
if __name__ == '__main__':
    foo.bar.a.b.c()

离线模式

如果buildout离线选项设置为“true”,则不会尝试联系索引服务器

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
... offline = true
...
... [demo]
... recipe = repoze.recipe.egg
... index = eek!
... scripts = demo=foo
... """ % dict(server=link_server))
>>> print system(buildout),
Uninstalling demo.
Installing demo.
Generated script '/sample-buildout/bin/foo'.

控制使用哪个Python

以下假设您已安装Python 2.3。

我们可以通过指定一个部分名称来指定要使用的Python,该部分用于从Python可执行文件读取。默认值是由python buildout选项定义的部分。

我们有一个链接服务器

>>> print get(link_server),
<html><body>
<a href="demo-0.1-py2.3.egg">demo-0.1-py2.3.egg</a><br>
<a href="demo-0.2-py2.3.egg">demo-0.2-py2.3.egg</a><br>
<a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br>
<a href="demo-0.4c1-py2.3.egg">demo-0.4c1-py2.3.egg</a><br>
<a href="demoneeded-1.0.zip">demoneeded-1.0.zip</a><br>
<a href="demoneeded-1.1.zip">demoneeded-1.1.zip</a><br>
<a href="demoneeded-1.2c1.zip">demoneeded-1.2c1.zip</a><br>
<a href="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
<a href="index/">index/</a><br>
<a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
</body></html>

我们有一个示例buildout。让我们更新其配置文件以使用Python 2.3安装demo包。

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
... eggs-directory = eggs
... index = https://pythonlang.cn/pypi/
...
... [python2.3]
... executable = %(python23)s
...
... [demo]
... recipe = repoze.recipe.egg
... eggs = demo <0.3
... find-links = %(server)s
... python = python2.3
... interpreter = py-demo
... """ % dict(server=link_server, python23=python2_3_executable))

现在,如果我们运行buildout

>>> import os
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout),
Installing demo.
Getting distribution for 'demo<0.3'.
Got demo 0.2.
Getting distribution for 'demoneeded'.
Getting distribution for 'setuptools'.
Got setuptools 0.6.
Got demoneeded 1.2c1.
Generated script '/sample-buildout/bin/demo'.
Generated interpreter '/sample-buildout/bin/py-demo'.

我们将为demo和demoneeded获取Python 2.3的eggs

>>> ls(sample_buildout, 'eggs')
-  demo-0.2-py2.3.egg
-  demoneeded-1.2c1-py2.3.egg
d  setuptools-0.6-py2.3.egg
d  setuptools-0.6-py2.4.egg
-  zc.buildout-1.0-py2.4.egg

并且生成的脚本调用Python 2.3

>>> import sys
>>> if sys.platform == 'win32':
...    script_name = 'demo-script.py'
... else:
...    script_name = 'demo'
>>> f = open(os.path.join(sample_buildout, 'bin', script_name))
>>> f.readline().strip() == '#!' + python2_3_executable
True
>>> print f.read(), # doctest: +NORMALIZE_WHITESPACE
<BLANKLINE>
import sys
sys.path[0:0] = [
  '/sample-buildout/eggs/demo-0.2-py2.3.egg',
  '/sample-buildout/eggs/demoneeded-1.2c1-py2.3.egg',
  ]
<BLANKLINE>
import eggrecipedemo
<BLANKLINE>
if __name__ == '__main__':
    eggrecipedemo.main()
>>> if sys.platform == 'win32':
...     f = open(os.path.join(sample_buildout, 'bin', 'py-demo-script.py'))
... else:
...     f = open(os.path.join(sample_buildout, 'bin', 'py-demo'))
>>> f.readline().strip() == '#!' + python2_3_executable
True
>>> print f.read(), # doctest: +NORMALIZE_WHITESPACE
import sys
<BLANKLINE>
sys.path[0:0] = [
  '/sample-buildout/eggs/demo-0.2-py2.3.egg',
  '/sample-buildout/eggs/demoneeded-1.2c1-py2.3.egg',
  ]
<BLANKLINE>
_interactive = True
if len(sys.argv) > 1:
    import getopt
    _options, _args = getopt.getopt(sys.argv[1:], 'ic:')
    _interactive = False
    for (_opt, _val) in _options:
        if _opt == '-i':
            _interactive = True
        elif _opt == '-c':
            exec _val
<BLANKLINE>
    if _args:
        sys.argv[:] = _args
        execfile(sys.argv[0])
<BLANKLINE>
if _interactive:
    import code
    code.interact(banner="", local=globals())
>>> f.close()

创建需要自定义构建设置的扩展egg

有时,有必要提供额外的控制来创建egg。对于需要访问库或包含文件的扩展模块的egg,通常是这样。

可以使用repoze.recipe.egg:custom配方来定义具有自定义构建参数的egg。当前定义的参数包括

include-dirs

一个目录列表,用于搜索包含文件,以换行符分隔。

library-dirs

一个目录列表,用于搜索要链接的库,以换行符分隔。

rpath

一个目录列表,用于运行时搜索动态库,以换行符分隔。

define

以逗号分隔的C预处理器变量名称列表,用于定义。

undef

以逗号分隔的C预处理器变量名称列表,用于取消定义。

libraries

要链接的附加库的名称。由于distutils的限制以及选项名称,只能指定一个库。

link-objects

要链接的链接对象的名称。由于distutils的限制以及选项名称,只能指定一个链接对象。

debug

编译/链接时包含调试信息

强制

强制构建所有内容(忽略文件时间戳)

编译器

指定编译器类型

swig

swig可执行文件的路径

swig-cpp

让SWIG创建C++文件(默认为C)

swig-opts

SWIG命令行选项列表

此外,还可以使用以下选项来指定egg

egg

创建egg的规范,以setuptools需求字符串的形式安装。默认为部分名称。

find-links

搜索分布的 URL、文件或目录列表。

index

索引服务器的 URL 或几乎任何其他有效 URL。:)

如果没有指定,则使用 Python 包索引,http://cheeseshop.python.org/pypi。您可以使用此选项指定一个替代索引。如果您使用链接选项,并且链接指向所需的分布,则索引可以是任何东西,并且将被很大程度上忽略。在下面的示例中,我们将仅指向我们的链接服务器上的一个空目录。这将使我们的示例运行得稍微快一点。

python

从该部分获取 Python 可执行文件名称。如果没有指定,则使用 buildout python 选项。Python 可执行文件位于命名部分的 executable 选项中。

为了说明这一点,我们将定义一个buildout,用于构建一个简单的扩展模块的egg

#include <Python.h>
#include <extdemo.h>

static PyMethodDef methods[] = {};

PyMODINIT_FUNC
initextdemo(void)
{
    PyObject *m;
    m = Py_InitModule3("extdemo", methods, "");
#ifdef TWO
    PyModule_AddObject(m, "val", PyInt_FromLong(2));
#else
    PyModule_AddObject(m, "val", PyInt_FromLong(EXTDEMO));
#endif
}

该扩展依赖于一个系统依赖的包含文件,extdemo.h,它定义了一个常量EXTDEMO,该常量由扩展公开。

扩展模块作为源分布,extdemo-1.4.tar.gz,在分发服务器上可用。

我们有一个示例buildout,我们将添加一个包含目录和必要的包含文件

>>> mkdir('include')
>>> write('include', 'extdemo.h',
... """
... #define EXTDEMO 42
... """)

我们还将更新buildout配置文件以定义egg的部分

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = extdemo
...
... [extdemo]
... recipe = repoze.recipe.egg:custom
... find-links = %(server)s
... index = %(server)s/index
... include-dirs = include
... """ % dict(server=link_server))
>>> print system(buildout),
Installing extdemo.
zip_safe flag not set; analyzing archive contents...

我们得到了zip_safe警告,因为我们使用的源分发不是基于setuptools的,因此没有设置选项。

egg创建在develop-eggs目录中,而不是eggs目录,因为它依赖于buildout特定的参数,而eggs目录可以在多个buildout之间共享。

>>> ls(sample_buildout, 'develop-eggs')
d  extdemo-1.4-py2.4-unix-i686.egg
-  repoze.recipe.egg.egg-link

请注意,没有安装脚本或依赖项。要安装自定义egg的依赖项或脚本,请定义另一个部分,并使用repoze.recipe.egg配方,将自定义egg作为要安装的egg之一列出。repoze.recipe.egg配方将使用已安装的egg。

让我们定义一个使用我们的ext demo的脚本

>>> mkdir('demo')
>>> write('demo', 'demo.py',
... """
... import extdemo
... def main():
...     print extdemo.val
... """)
>>> write('demo', 'setup.py',
... """
... from setuptools import setup
... setup(name='demo')
... """)
>>> write('buildout.cfg',
... """
... [buildout]
... develop = demo
... parts = extdemo demo
...
... [extdemo]
... recipe = repoze.recipe.egg:custom
... find-links = %(server)s
... index = %(server)s/index
... include-dirs = include
...
... [demo]
... recipe = repoze.recipe.egg
... eggs = demo
...        extdemo
... entry-points = demo=demo:main
... """ % dict(server=link_server))
>>> print system(buildout),
Develop: '/sample-buildout/demo'
Updating extdemo.
Installing demo.
Generated script '/sample-buildout/bin/demo'.

当我们运行脚本时,我们将打印42

>>> print system(join('bin', 'demo')),
42

更新

自定义配方通常会检查符合给定规范的新源分布。这可以通过使用buildout non-newest和offline模式来抑制。我们将为extdemo生成一个新的源分布

>>> update_extdemo()

如果我们以non-newest或offline模式运行buildout

>>> print system(buildout+' -N'),
Develop: '/sample-buildout/demo'
Updating extdemo.
Updating demo.
>>> print system(buildout+' -o'),
Develop: '/sample-buildout/demo'
Updating extdemo.
Updating demo.

我们不会收到更新。

>>> ls(sample_buildout, 'develop-eggs')
-  demo.egg-link
d  extdemo-1.4-py2.4-unix-i686.egg
-  repoze.recipe.egg.egg-link

但如果我们以默认的在线和最新模式运行buildout,我们就会

>>> print system(buildout),
Develop: '/sample-buildout/demo'
Updating extdemo.
zip_safe flag not set; analyzing archive contents...
Updating demo.
Generated script '/sample-buildout/bin/demo'.
>>> ls(sample_buildout, 'develop-eggs')
-  demo.egg-link
d  extdemo-1.4-py2.4-linux-i686.egg
d  extdemo-1.5-py2.4-linux-i686.egg
-  repoze.recipe.egg.egg-link

控制使用的版本

我们可以使用egg选项指定特定版本

>>> write('buildout.cfg',
... """
... [buildout]
... develop = demo
... parts = extdemo demo
...
... [extdemo]
... recipe = repoze.recipe.egg:custom
... egg = extdemo ==1.4
... find-links = %(server)s
... index = %(server)s/index
... include-dirs = include
...
... [demo]
... recipe = repoze.recipe.egg
... eggs = demo
...        extdemo ==1.4
... entry-points = demo=demo:main
... """ % dict(server=link_server))
>>> print system(buildout+' -D'),
Develop: '/sample-buildout/demo'
Uninstalling demo.
Uninstalling extdemo.
Installing extdemo.
zip_safe flag not set; analyzing archive contents...
Installing demo.
Generated script '/sample-buildout/bin/demo'.
>>> ls(sample_buildout, 'develop-eggs')
-  demo.egg-link
d  extdemo-1.4-py2.4-linux-i686.egg
-  repoze.recipe.egg.egg-link

控制开发egg生成

如果您想为开发egg提供自定义构建选项,可以使用develop配方。该配方具有以下选项

path

设置脚本或包含启动脚本的目录的路径。这是必需的。

include-dirs

一个目录列表,用于搜索包含文件,以换行符分隔。

library-dirs

一个目录列表,用于搜索要链接的库,以换行符分隔。

rpath

一个目录列表,用于运行时搜索动态库,以换行符分隔。

define

以逗号分隔的C预处理器变量名称列表,用于定义。

undef

以逗号分隔的C预处理器变量名称列表,用于取消定义。

libraries

要链接的附加库的名称。由于distutils的限制以及选项名称,只能指定一个库。

link-objects

要链接的链接对象的名称。由于distutils的限制以及选项名称,只能指定一个链接对象。

debug

编译/链接时包含调试信息

强制

强制构建所有内容(忽略文件时间戳)

编译器

指定编译器类型

swig

swig可执行文件的路径

swig-cpp

让SWIG创建C++文件(默认为C)

swig-opts

SWIG命令行选项列表

python

从该部分获取 Python 可执行文件名称。如果没有指定,则使用 buildout python 选项。Python 可执行文件位于命名部分的 executable 选项中。

为了说明这一点,我们将使用包含早期部分中的extdemo示例的目录

>>> ls(extdemo)
-  MANIFEST
-  MANIFEST.in
-  README
-  extdemo.c
-  setup.py
>>> write('buildout.cfg',
... """
... [buildout]
... develop = demo
... parts = extdemo demo
...
... [extdemo]
... setup = %(extdemo)s
... recipe = repoze.recipe.egg:develop
... include-dirs = include
... define = TWO
...
... [demo]
... recipe = repoze.recipe.egg
... eggs = demo
...        extdemo
... entry-points = demo=demo:main
... """ % dict(extdemo=extdemo))

请注意,我们添加了define选项来使预处理器变量TWO被定义。这将使模块变量'val'设置为2。

>>> print system(buildout),
Develop: '/sample-buildout/demo'
Uninstalling demo.
Uninstalling extdemo.
Installing extdemo.
Installing demo.
Generated script '/sample-buildout/bin/demo'.

我们的develop-eggs现在包括extdemo的egg链接

>>> ls('develop-eggs')
-  demo.egg-link
-  extdemo.egg-link
-  repoze.recipe.egg.egg-link

并且extdemo现在有一个构建的扩展

>>> ls(extdemo)
-  MANIFEST
-  MANIFEST.in
-  README
d  build
-  extdemo.c
d  extdemo.egg-info
-  extdemo.so
-  setup.py

由于开发egg优先于非开发egg,因此演示脚本将使用新的开发egg

>>> print system(join('bin', 'demo')),
2

其他Recipe的Egg Recipe API

对于配方来说,接受一组egg规范并基于结果的工作集生成脚本是很常见的。egg配方提供了一个其他配方可以使用的API。

配方可以重用egg配方,支持eggs,find-links,index,extra-paths和python选项。这是通过在配方构造函数中创建egg配方实例来实现的。在配方的安装脚本中,使用egg-recipe实例的工作集方法来收集请求的egg和工作集。

为了说明,我们创建了一个围绕egg配方非常薄的示例配方

>>> mkdir(sample_buildout, 'sample')
>>> write(sample_buildout, 'sample', 'sample.py',
... """
... import logging, os
... import repoze.recipe.egg
...
... class Sample:
...
...     def __init__(self, buildout, name, options):
...         self.egg = repoze.recipe.egg.Scripts(buildout, name, options)
...         self.name = name
...         self.options = options
...
...     def install(self):
...         extras = self.options['extras'].split()
...         requirements, ws = self.egg.working_set(extras)
...         print 'Part:', self.name
...         print 'Egg requirements:'
...         for r in requirements:
...             print r
...         print 'Working set:'
...         for d in ws:
...             print d
...         print 'extra paths:', self.egg.extra_paths
...         return ()
...
...     update = install
... """)

在这里,我们在构造函数中实例化了egg配方,并将其保存为属性。这也初始化了选项字典。

在我们的安装方法中,我们在保存的实例上调用了working_set方法。working_set方法接受一个可选的序列,其中包含要包含在工作集中的额外要求。

>>> write(sample_buildout, 'sample', 'setup.py',
... """
... from setuptools import setup
...
... setup(
...     name = "sample",
...     entry_points = {'zc.buildout': ['default = sample:Sample']},
...     install_requires = 'repoze.recipe.egg',
...     )
... """)
>>> write(sample_buildout, 'sample', 'README.txt', " ")
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... develop = sample
... parts = sample-part
...
... [sample-part]
... recipe = sample
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)sindex
... extras = other
... """ % dict(server=link_server))
>>> import os
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout + ' -q'),
Part: sample-part
Egg requirements:
demo<0.3
Working set:
demo 0.2
other 1.0
demoneeded 1.2c1
extra paths: []

通过查看.installed.cfg,我们可以看到选项通过egg食谱计算出的附加数据得到了增强

>>> cat(sample_buildout, '.installed.cfg')
[buildout]
installed_develop_eggs = /sample-buildout/develop-eggs/sample.egg-link
parts = sample-part
<BLANKLINE>
[sample-part]
__buildout_installed__ =
__buildout_signature__ = sample-6aWMvV2EJ9Ijq+bR8ugArQ==
        repoze.recipe.egg-cAsnudgkduAa/Fd+WJIM6Q==
        setuptools-0.6-py2.4.egg
        zc.buildout-+rYeCcmFuD1K/aB77XTj5A==
_b = /sample-buildout/bin
_d = /sample-buildout/develop-eggs
_e = /sample-buildout/eggs
bin-directory = /sample-buildout/bin
develop-eggs-directory = /sample-buildout/develop-eggs
eggs = demo<0.3
eggs-directory = /sample-buildout/eggs
executable = /usr/local/bin/python2.3
extras = other
find-links = http://localhost:27071/
index = http://localhost:27071/index
recipe = sample

如果我们使用extra-paths选项

>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... develop = sample
... parts = sample-part
...
... [sample-part]
... recipe = sample
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)sindex
... extras = other
... extra-paths = /foo/bar
...               /spam/eggs
... """ % dict(server=link_server))

那么我们将在egg食谱实例的extra_paths属性中看到反映

>>> print system(buildout + ' -q'),
Part: sample-part
Egg requirements:
demo<0.3
Working set:
demo 0.2
other 1.0
demoneeded 1.2c1
extra paths: ['/foo/bar', '/spam/eggs']

下载

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

repoze.recipe.egg-0.3.tar.gz (26.5 kB 查看散列值)

上传时间

由以下支持