summaryrefslogtreecommitdiff
path: root/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.txt
diff options
context:
space:
mode:
Diffstat (limited to 'eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.txt')
-rw-r--r--eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.txt1985
1 files changed, 0 insertions, 1985 deletions
diff --git a/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.txt b/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.txt
deleted file mode 100644
index ec654cd..0000000
--- a/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.txt
+++ /dev/null
@@ -1,1985 +0,0 @@
-Python API for egg and script installation
-==========================================
-
-The easy_install module provides some functions to provide support for
-egg and script installation. It provides functionality at the python
-level that is similar to easy_install, with a few exceptions:
-
-- By default, we look for new packages *and* the packages that
- they depend on. This is somewhat like (and uses) the --upgrade
- option of easy_install, except that we also upgrade required
- packages.
-
-- If the highest-revision package satisfying a specification is
- already present, then we don't try to get another one. This saves a
- lot of search time in the common case that packages are pegged to
- specific versions.
-
-- If there is a develop egg that satisfies a requirement, we don't
- look for additional distributions. We always give preference to
- develop eggs.
-
-- Distutils options for building extensions can be passed.
-
-Distribution installation
--------------------------
-
-The easy_install module provides a function, install, for installing one
-or more packages and their dependencies. The install function takes 2
-positional arguments:
-
-- An iterable of setuptools requirement strings for the distributions
- to be installed, and
-
-- A destination directory to install to and to satisfy requirements
- from. The destination directory can be None, in which case, no new
- distributions are downloaded and there will be an error if the
- needed distributions can't be found among those already installed.
-
-It supports a number of optional keyword arguments:
-
-links
- A sequence of URLs, file names, or directories to look for
- links to distributions.
-
-index
- The URL of an index server, or almost any other valid URL. :)
-
- If not specified, the Python Package Index,
- http://pypi.python.org/simple/, is used. You can specify an
- alternate index with this option. If you use the links option and
- if the links point to the needed distributions, then the index can
- be anything and will be largely ignored. In the examples, here,
- we'll just point to an empty directory on our link server. This
- will make our examples run a little bit faster.
-
-executable
- A path to a Python executable. Distributions will be installed
- using this executable and will be for the matching Python version.
-
-path
- A list of additional directories to search for locally-installed
- distributions.
-
-always_unzip
- A flag indicating that newly-downloaded distributions should be
- directories even if they could be installed as zip files.
-
-working_set
- An existing working set to be augmented with additional
- distributions, if necessary to satisfy requirements. This allows
- you to call install multiple times, if necessary, to gather
- multiple sets of requirements.
-
-newest
- A boolean value indicating whether to search for new distributions
- when already-installed distributions meet the requirement. When
- this is true, the default, and when the destination directory is
- not None, then the install function will search for the newest
- distributions that satisfy the requirements.
-
-versions
- A dictionary mapping project names to version numbers to be used
- when selecting distributions. This can be used to specify a set of
- distribution versions independent of other requirements.
-
-use_dependency_links
- A flag indicating whether to search for dependencies using the
- setup dependency_links metadata or not. If true, links are searched
- for using dependency_links in preference to other
- locations. Defaults to true.
-
-include_site_packages
- A flag indicating whether Python's non-standard-library packages should
- be available for finding dependencies. Defaults to true.
-
- Paths outside of Python's standard library--or more precisely, those that
- are not included when Python is started with the -S argument--are loosely
- referred to as "site-packages" here.
-
-relative_paths
- Adjust egg paths so they are relative to the script path. This
- allows scripts to work when scripts and eggs are moved, as long as
- they are both moved in the same way.
-
-The install method returns a working set containing the distributions
-needed to meet the given requirements.
-
-We have a link server that has a number of eggs:
-
- >>> print get(link_server),
- <html><body>
- <a href="bigdemo-0.1-py2.4.egg">bigdemo-0.1-py2.4.egg</a><br>
- <a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br>
- <a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br>
- <a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br>
- <a href="demo-0.4c1-py2.4.egg">demo-0.4c1-py2.4.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.4.egg">other-1.0-py2.4.egg</a><br>
- </body></html>
-
-Let's make a directory and install the demo egg to it, using the demo:
-
- >>> dest = tmpdir('sample-install')
- >>> import zc.buildout.easy_install
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo==0.2'], dest,
- ... links=[link_server], index=link_server+'index/')
-
-We requested version 0.2 of the demo distribution to be installed into
-the destination server. We specified that we should search for links
-on the link server and that we should use the (empty) link server
-index directory as a package index.
-
-The working set contains the distributions we retrieved.
-
- >>> for dist in ws:
- ... print dist
- demo 0.2
- demoneeded 1.1
-
-We got demoneeded because it was a dependency of demo.
-
-And the actual eggs were added to the eggs directory.
-
- >>> ls(dest)
- - demo-0.2-py2.4.egg
- - demoneeded-1.1-py2.4.egg
-
-If we remove the version restriction on demo, but specify a false
-value for newest, no new distributions will be installed:
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/',
- ... newest=False)
- >>> ls(dest)
- - demo-0.2-py2.4.egg
- - demoneeded-1.1-py2.4.egg
-
-If we leave off the newest option, we'll get an update for demo:
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/')
- >>> ls(dest)
- - demo-0.2-py2.4.egg
- - demo-0.3-py2.4.egg
- - demoneeded-1.1-py2.4.egg
-
-Note that we didn't get the newest versions available. There were
-release candidates for newer versions of both packages. By default,
-final releases are preferred. We can change this behavior using the
-prefer_final function:
-
- >>> zc.buildout.easy_install.prefer_final(False)
- True
-
-The old setting is returned.
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/')
- >>> for dist in ws:
- ... print dist
- demo 0.4c1
- demoneeded 1.2c1
-
- >>> ls(dest)
- - demo-0.2-py2.4.egg
- - demo-0.3-py2.4.egg
- - demo-0.4c1-py2.4.egg
- - demoneeded-1.1-py2.4.egg
- - demoneeded-1.2c1-py2.4.egg
-
-Let's put the setting back to the default.
-
- >>> zc.buildout.easy_install.prefer_final(True)
- False
-
-We can supply additional distributions. We can also supply
-specifications for distributions that would normally be found via
-dependencies. We might do this to specify a specific version.
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo', 'other', 'demoneeded==1.0'], dest,
- ... links=[link_server], index=link_server+'index/')
-
- >>> for dist in ws:
- ... print dist
- demo 0.3
- other 1.0
- demoneeded 1.0
-
- >>> ls(dest)
- - demo-0.2-py2.4.egg
- - demo-0.3-py2.4.egg
- - demo-0.4c1-py2.4.egg
- - demoneeded-1.0-py2.4.egg
- - demoneeded-1.1-py2.4.egg
- - demoneeded-1.2c1-py2.4.egg
- d other-1.0-py2.4.egg
-
-We can request that eggs be unzipped even if they are zip safe. This
-can be useful when debugging. (Note that Distribute will unzip eggs by
-default, so if you are using Distribute, most or all eggs will already be
-unzipped without this flag.)
-
- >>> rmdir(dest)
- >>> dest = tmpdir('sample-install')
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/',
- ... always_unzip=True)
-
- >>> ls(dest)
- d demo-0.3-py2.4.egg
- d demoneeded-1.1-py2.4.egg
-
- >>> rmdir(dest)
- >>> dest = tmpdir('sample-install')
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/',
- ... always_unzip=False)
-
- >>> ls(dest)
- - demo-0.3-py2.4.egg
- - demoneeded-1.1-py2.4.egg
-
-We can also set a default by calling the always_unzip function:
-
- >>> zc.buildout.easy_install.always_unzip(True)
- False
-
-The old default is returned:
-
- >>> rmdir(dest)
- >>> dest = tmpdir('sample-install')
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/')
-
- >>> ls(dest)
- d demo-0.3-py2.4.egg
- d demoneeded-1.1-py2.4.egg
-
-
- >>> zc.buildout.easy_install.always_unzip(False)
- True
-
- >>> rmdir(dest)
- >>> dest = tmpdir('sample-install')
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/')
-
- >>> ls(dest)
- - demo-0.3-py2.4.egg
- - demoneeded-1.1-py2.4.egg
-
- >>> rmdir(dest)
- >>> dest = tmpdir('sample-install')
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/',
- ... always_unzip=True)
-
- >>> ls(dest)
- d demo-0.3-py2.4.egg
- d demoneeded-1.1-py2.4.egg
-
-Specifying version information independent of requirements
-----------------------------------------------------------
-
-Sometimes it's useful to specify version information independent of
-normal requirements specifications. For example, a buildout may need
-to lock down a set of versions, without having to put put version
-numbers in setup files or part definitions. If a dictionary is passed
-to the install function, mapping project names to version numbers,
-then the versions numbers will be used.
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/',
- ... versions = dict(demo='0.2', demoneeded='1.0'))
- >>> [d.version for d in ws]
- ['0.2', '1.0']
-
-In this example, we specified a version for demoneeded, even though we
-didn't define a requirement for it. The versions specified apply to
-dependencies as well as the specified requirements.
-
-If we specify a version that's incompatible with a requirement, then
-we'll get an error:
-
- >>> from zope.testing.loggingsupport import InstalledHandler
- >>> handler = InstalledHandler('zc.buildout.easy_install')
- >>> import logging
- >>> logging.getLogger('zc.buildout.easy_install').propagate = False
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo >0.2'], dest, links=[link_server],
- ... index=link_server+'index/',
- ... versions = dict(demo='0.2', demoneeded='1.0'))
- Traceback (most recent call last):
- ...
- IncompatibleVersionError: Bad version 0.2
-
- >>> print handler
- zc.buildout.easy_install DEBUG
- Installing 'demo >0.2'.
- zc.buildout.easy_install ERROR
- The version, 0.2, is not consistent with the requirement, 'demo>0.2'.
-
- >>> handler.clear()
-
-If no versions are specified, a debugging message will be output
-reporting that a version was picked automatically:
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/',
- ... )
-
- >>> print handler
- zc.buildout.easy_install DEBUG
- Installing 'demo'.
- zc.buildout.easy_install DEBUG
- We have the best distribution that satisfies 'demo'.
- zc.buildout.easy_install DEBUG
- Picked: demo = 0.3
- zc.buildout.easy_install DEBUG
- Getting required 'demoneeded'
- zc.buildout.easy_install DEBUG
- required by demo 0.3.
- zc.buildout.easy_install DEBUG
- We have the best distribution that satisfies 'demoneeded'.
- zc.buildout.easy_install DEBUG
- Picked: demoneeded = 1.1
-
- >>> handler.uninstall()
- >>> logging.getLogger('zc.buildout.easy_install').propagate = True
-
-We can request that we get an error if versions are picked:
-
- >>> zc.buildout.easy_install.allow_picked_versions(False)
- True
-
-(The old setting is returned.)
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/',
- ... )
- Traceback (most recent call last):
- ...
- UserError: Picked: demo = 0.3
-
- >>> zc.buildout.easy_install.allow_picked_versions(True)
- False
-
-The function default_versions can be used to get and set default
-version information to be used when no version information is passes.
-If called with an argument, it sets the default versions:
-
- >>> zc.buildout.easy_install.default_versions(dict(demoneeded='1'))
- {}
-
-It always returns the previous default versions. If called without an
-argument, it simply returns the default versions without changing
-them:
-
- >>> zc.buildout.easy_install.default_versions()
- {'demoneeded': '1'}
-
-So with the default versions set, we'll get the requested version even
-if the versions option isn't used:
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/',
- ... )
-
- >>> [d.version for d in ws]
- ['0.3', '1.0']
-
-Of course, we can unset the default versions by passing an empty
-dictionary:
-
- >>> zc.buildout.easy_install.default_versions({})
- {'demoneeded': '1'}
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest, links=[link_server], index=link_server+'index/',
- ... )
-
- >>> [d.version for d in ws]
- ['0.3', '1.1']
-
-Dependencies in Site Packages
------------------------------
-
-Paths outside of Python's standard library--or more precisely, those that are
-not included when Python is started with the -S argument--are loosely referred
-to as "site-packages" here. These site-packages are searched by default for
-distributions. This can be disabled, so that, for instance, a system Python
-can be used with buildout, cleaned of any packages installed by a user or
-system package manager.
-
-The default behavior can be controlled and introspected using
-zc.buildout.easy_install.include_site_packages.
-
- >>> zc.buildout.easy_install.include_site_packages()
- True
-
-Here's an example of using a Python executable that includes our dependencies.
-
-Our "py_path" will have the "demoneeded," and "demo" packages available.
- We'll simply be asking for "demoneeded" here, but without any external
- index or links.
-
- >>> from zc.buildout.tests import create_sample_sys_install
- >>> py_path, site_packages_path = make_py()
- >>> create_sample_sys_install(site_packages_path)
-
- >>> example_dest = tmpdir('site-packages-example-install')
- >>> workingset = zc.buildout.easy_install.install(
- ... ['demoneeded'], example_dest, links=[], executable=py_path,
- ... index=None)
- >>> [dist.project_name for dist in workingset]
- ['demoneeded']
-
-That worked fine. Let's try again with site packages not allowed. We'll
-change the policy by changing the default. Notice that the function for
-changing the default value returns the previous value.
-
- >>> zc.buildout.easy_install.include_site_packages(False)
- True
-
- >>> zc.buildout.easy_install.include_site_packages()
- False
-
- >>> zc.buildout.easy_install.clear_index_cache()
- >>> rmdir(example_dest)
- >>> example_dest = tmpdir('site-packages-example-install')
- >>> workingset = zc.buildout.easy_install.install(
- ... ['demoneeded'], example_dest, links=[], executable=py_path,
- ... index=None)
- Traceback (most recent call last):
- ...
- MissingDistribution: Couldn't find a distribution for 'demoneeded'.
- >>> zc.buildout.easy_install.clear_index_cache()
-
-Now we'll reset the default.
-
- >>> zc.buildout.easy_install.include_site_packages(True)
- False
-
- >>> zc.buildout.easy_install.include_site_packages()
- True
-
-Dependency links
-----------------
-
-Setuptools allows metadata that describes where to search for package
-dependencies. This option is called dependency_links. Buildout has its
-own notion of where to look for dependencies, but it also uses the
-setup tools dependency_links information if it's available.
-
-Let's demo this by creating an egg that specifies dependency_links.
-
-To begin, let's create a new egg repository. This repository hold a
-newer version of the 'demoneeded' egg than the sample repository does.
-
- >>> repoloc = tmpdir('repo')
- >>> from zc.buildout.tests import create_egg
- >>> create_egg('demoneeded', '1.2', repoloc)
- >>> link_server2 = start_server(repoloc)
-
-Turn on logging on this server so that we can see when eggs are pulled
-from it.
-
- >>> get(link_server2 + 'enable_server_logging')
- GET 200 /enable_server_logging
- ''
-
-Now we can create an egg that specifies that its dependencies are
-found on this server.
-
- >>> repoloc = tmpdir('repo2')
- >>> create_egg('hasdeps', '1.0', repoloc,
- ... install_requires = "'demoneeded'",
- ... dependency_links = [link_server2])
-
-Let's add the egg to another repository.
-
- >>> link_server3 = start_server(repoloc)
-
-Now let's install the egg.
-
- >>> example_dest = tmpdir('example-install')
- >>> workingset = zc.buildout.easy_install.install(
- ... ['hasdeps'], example_dest,
- ... links=[link_server3], index=link_server3+'index/')
- GET 200 /
- GET 200 /demoneeded-1.2-pyN.N.egg
-
-The server logs show that the dependency was retrieved from the server
-specified in the dependency_links.
-
-Now let's see what happens if we provide two different ways to retrieve
-the dependencies.
-
- >>> rmdir(example_dest)
- >>> example_dest = tmpdir('example-install')
- >>> workingset = zc.buildout.easy_install.install(
- ... ['hasdeps'], example_dest, index=link_server+'index/',
- ... links=[link_server, link_server3])
- GET 200 /
- GET 200 /demoneeded-1.2-pyN.N.egg
-
-Once again the dependency is fetched from the logging server even
-though it is also available from the non-logging server. This is
-because the version on the logging server is newer and buildout
-normally chooses the newest egg available.
-
-If you wish to control where dependencies come from regardless of
-dependency_links setup metadata use the 'use_dependency_links' option
-to zc.buildout.easy_install.install().
-
- >>> rmdir(example_dest)
- >>> example_dest = tmpdir('example-install')
- >>> workingset = zc.buildout.easy_install.install(
- ... ['hasdeps'], example_dest, index=link_server+'index/',
- ... links=[link_server, link_server3],
- ... use_dependency_links=False)
-
-Notice that this time the dependency egg is not fetched from the
-logging server. When you specify not to use dependency_links, eggs
-will only be searched for using the links you explicitly provide.
-
-Another way to control this option is with the
-zc.buildout.easy_install.use_dependency_links() function. This
-function sets the default behavior for the zc.buildout.easy_install()
-function.
-
- >>> zc.buildout.easy_install.use_dependency_links(False)
- True
-
-The function returns its previous setting.
-
- >>> rmdir(example_dest)
- >>> example_dest = tmpdir('example-install')
- >>> workingset = zc.buildout.easy_install.install(
- ... ['hasdeps'], example_dest, index=link_server+'index/',
- ... links=[link_server, link_server3])
-
-It can be overridden by passing a keyword argument to the install
-function.
-
- >>> rmdir(example_dest)
- >>> example_dest = tmpdir('example-install')
- >>> workingset = zc.buildout.easy_install.install(
- ... ['hasdeps'], example_dest, index=link_server+'index/',
- ... links=[link_server, link_server3],
- ... use_dependency_links=True)
- GET 200 /demoneeded-1.2-pyN.N.egg
-
-To return the dependency_links behavior to normal call the function again.
-
- >>> zc.buildout.easy_install.use_dependency_links(True)
- False
- >>> rmdir(example_dest)
- >>> example_dest = tmpdir('example-install')
- >>> workingset = zc.buildout.easy_install.install(
- ... ['hasdeps'], example_dest, index=link_server+'index/',
- ... links=[link_server, link_server3])
- GET 200 /demoneeded-1.2-pyN.N.egg
-
-
-Script generation
------------------
-
-The easy_install module provides support for creating scripts from eggs.
-It provides two competing functions. One, ``scripts``, is a
-well-established approach to generating reliable scripts with a "clean"
-Python--e.g., one that does not have any packages in its site-packages.
-The other, ``sitepackage_safe_scripts``, is newer, a bit trickier, and is
-designed to work with a Python that has code in its site-packages, such
-as a system Python.
-
-Both are similar to setuptools except that they provides facilities for
-baking a script's path into the script. This has two advantages:
-
-- The eggs to be used by a script are not chosen at run time, making
- startup faster and, more importantly, deterministic.
-
-- The script doesn't have to import pkg_resources because the logic that
- pkg_resources would execute at run time is executed at script-creation
- time. (There is an exception in ``sitepackage_safe_scripts`` if you
- want to have your Python's site packages available, as discussed
- below, but even in that case pkg_resources is only partially
- activated, which can be a significant time savings.)
-
-
-The ``scripts`` function
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``scripts`` function is the first way to generate scripts that we'll
-examine. It is the earlier approach that the package offered. Let's
-create a destination directory for it to place them in:
-
- >>> bin = tmpdir('bin')
-
-Now, we'll use the scripts function to generate scripts in this directory
-from the demo egg:
-
- >>> import sys
- >>> scripts = zc.buildout.easy_install.scripts(
- ... ['demo'], ws, sys.executable, bin)
-
-the four arguments we passed were:
-
-1. A sequence of distribution requirements. These are of the same
- form as setuptools requirements. Here we passed a single
- requirement, for the version 0.1 demo distribution.
-
-2. A working set,
-
-3. The Python executable to use, and
-
-3. The destination directory.
-
-The bin directory now contains a generated script:
-
- >>> ls(bin)
- - demo
-
-The return value is a list of the scripts generated:
-
- >>> import os, sys
- >>> if sys.platform == 'win32':
- ... scripts == [os.path.join(bin, 'demo.exe'),
- ... os.path.join(bin, 'demo-script.py')]
- ... else:
- ... scripts == [os.path.join(bin, 'demo')]
- True
-
-Note that in Windows, 2 files are generated for each script. A script
-file, ending in '-script.py', and an exe file that allows the script
-to be invoked directly without having to specify the Python
-interpreter and without having to provide a '.py' suffix.
-
-The demo script run the entry point defined in the demo egg:
-
- >>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4
- <BLANKLINE>
- import sys
- sys.path[0:0] = [
- '/sample-install/demo-0.3-py2.4.egg',
- '/sample-install/demoneeded-1.1-py2.4.egg',
- ]
- <BLANKLINE>
- import eggrecipedemo
- <BLANKLINE>
- if __name__ == '__main__':
- eggrecipedemo.main()
-
-Some things to note:
-
-- The demo and demoneeded eggs are added to the beginning of sys.path.
-
-- The module for the script entry point is imported and the entry
- point, in this case, 'main', is run.
-
-Rather than requirement strings, you can pass tuples containing 3
-strings:
-
- - A script name,
-
- - A module,
-
- - An attribute expression for an entry point within the module.
-
-For example, we could have passed entry point information directly
-rather than passing a requirement:
-
- >>> scripts = zc.buildout.easy_install.scripts(
- ... [('demo', 'eggrecipedemo', 'main')],
- ... ws, sys.executable, bin)
-
- >>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4
- <BLANKLINE>
- import sys
- sys.path[0:0] = [
- '/sample-install/demo-0.3-py2.4.egg',
- '/sample-install/demoneeded-1.1-py2.4.egg',
- ]
- <BLANKLINE>
- import eggrecipedemo
- <BLANKLINE>
- if __name__ == '__main__':
- eggrecipedemo.main()
-
-Passing entry-point information directly is handy when using eggs (or
-distributions) that don't declare their entry points, such as
-distributions that aren't based on setuptools.
-
-The interpreter keyword argument can be used to generate a script that can
-be used to invoke the Python interactive interpreter with the path set
-based on the working set. This generated script can also be used to
-run other scripts with the path set on the working set:
-
- >>> scripts = zc.buildout.easy_install.scripts(
- ... ['demo'], ws, sys.executable, bin, interpreter='py')
-
-
- >>> ls(bin)
- - demo
- - py
-
- >>> if sys.platform == 'win32':
- ... scripts == [os.path.join(bin, 'demo.exe'),
- ... os.path.join(bin, 'demo-script.py'),
- ... os.path.join(bin, 'py.exe'),
- ... os.path.join(bin, 'py-script.py')]
- ... else:
- ... scripts == [os.path.join(bin, 'demo'),
- ... os.path.join(bin, 'py')]
- True
-
-The py script simply runs the Python interactive interpreter with
-the path set:
-
- >>> cat(bin, 'py') # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4
- <BLANKLINE>
- import sys
- <BLANKLINE>
- sys.path[0:0] = [
- '/sample-install/demo-0.3-pyN.N.egg',
- '/sample-install/demoneeded-1.1-pyN.N.egg',
- ]
- <BLANKLINE>
- _interactive = True
- if len(sys.argv) > 1:
- _options, _args = __import__("getopt").getopt(sys.argv[1:], 'ic:m:')
- _interactive = False
- for (_opt, _val) in _options:
- if _opt == '-i':
- _interactive = True
- elif _opt == '-c':
- exec _val
- elif _opt == '-m':
- sys.argv[1:] = _args
- _args = []
- __import__("runpy").run_module(
- _val, {}, "__main__", alter_sys=True)
- <BLANKLINE>
- if _args:
- sys.argv[:] = _args
- __file__ = _args[0]
- del _options, _args
- execfile(__file__)
- <BLANKLINE>
- if _interactive:
- del _interactive
- __import__("code").interact(banner="", local=globals())
-
-If invoked with a script name and arguments, it will run that script, instead.
-
- >>> write('ascript', '''
- ... "demo doc"
- ... print sys.argv
- ... print (__name__, __file__, __doc__)
- ... ''')
- >>> print system(join(bin, 'py')+' ascript a b c'),
- ['ascript', 'a', 'b', 'c']
- ('__main__', 'ascript', 'demo doc')
-
-For Python 2.5 and higher, you can also use the -m option to run a
-module:
-
- >>> print system(join(bin, 'py')+' -m pdb'),
- usage: pdb.py scriptfile [arg] ...
-
- >>> print system(join(bin, 'py')+' -m pdb what'),
- Error: what does not exist
-
-An additional argument can be passed to define which scripts to install
-and to provide script names. The argument is a dictionary mapping
-original script names to new script names.
-
- >>> bin = tmpdir('bin2')
- >>> scripts = zc.buildout.easy_install.scripts(
- ... ['demo'], ws, sys.executable, bin, dict(demo='run'))
-
- >>> if sys.platform == 'win32':
- ... scripts == [os.path.join(bin, 'run.exe'),
- ... os.path.join(bin, 'run-script.py')]
- ... else:
- ... scripts == [os.path.join(bin, 'run')]
- True
- >>> ls(bin)
- - run
-
- >>> print system(os.path.join(bin, 'run')),
- 3 1
-
-The ``scripts`` function: Including extra paths in scripts
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-We can pass a keyword argument, extra paths, to cause additional paths
-to be included in the a generated script:
-
- >>> foo = tmpdir('foo')
- >>> scripts = zc.buildout.easy_install.scripts(
- ... ['demo'], ws, sys.executable, bin, dict(demo='run'),
- ... extra_paths=[foo])
-
- >>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4
- <BLANKLINE>
- import sys
- sys.path[0:0] = [
- '/sample-install/demo-0.3-py2.4.egg',
- '/sample-install/demoneeded-1.1-py2.4.egg',
- '/foo',
- ]
- <BLANKLINE>
- import eggrecipedemo
- <BLANKLINE>
- if __name__ == '__main__':
- eggrecipedemo.main()
-
-The ``scripts`` function: Providing script arguments
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-An "argument" keyword argument can be used to pass arguments to an
-entry point. The value passed is a source string to be placed between the
-parentheses in the call:
-
- >>> scripts = zc.buildout.easy_install.scripts(
- ... ['demo'], ws, sys.executable, bin, dict(demo='run'),
- ... arguments='1, 2')
-
- >>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4
- import sys
- sys.path[0:0] = [
- '/sample-install/demo-0.3-py2.4.egg',
- '/sample-install/demoneeded-1.1-py2.4.egg',
- ]
- <BLANKLINE>
- import eggrecipedemo
- <BLANKLINE>
- if __name__ == '__main__':
- eggrecipedemo.main(1, 2)
-
-The ``scripts`` function: Passing initialization code
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-You can also pass script initialization code:
-
- >>> scripts = zc.buildout.easy_install.scripts(
- ... ['demo'], ws, sys.executable, bin, dict(demo='run'),
- ... arguments='1, 2',
- ... initialization='import os\nos.chdir("foo")')
-
- >>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4
- import sys
- sys.path[0:0] = [
- '/sample-install/demo-0.3-py2.4.egg',
- '/sample-install/demoneeded-1.1-py2.4.egg',
- ]
- <BLANKLINE>
- import os
- os.chdir("foo")
- <BLANKLINE>
- import eggrecipedemo
- <BLANKLINE>
- if __name__ == '__main__':
- eggrecipedemo.main(1, 2)
-
-The ``scripts`` function: Relative paths
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Sometimes, you want to be able to move a buildout directory around and
-have scripts still work without having to rebuild them. We can
-control this using the relative_paths option to install. You need
-to pass a common base directory of the scripts and eggs:
-
- >>> bo = tmpdir('bo')
- >>> ba = tmpdir('ba')
- >>> mkdir(bo, 'eggs')
- >>> mkdir(bo, 'bin')
- >>> mkdir(bo, 'other')
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], join(bo, 'eggs'), links=[link_server],
- ... index=link_server+'index/')
-
- >>> scripts = zc.buildout.easy_install.scripts(
- ... ['demo'], ws, sys.executable, join(bo, 'bin'), dict(demo='run'),
- ... extra_paths=[ba, join(bo, 'bar')],
- ... interpreter='py',
- ... relative_paths=bo)
-
- >>> cat(bo, 'bin', 'run') # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4
- <BLANKLINE>
- import os
- <BLANKLINE>
- join = os.path.join
- base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
- base = os.path.dirname(base)
- <BLANKLINE>
- import sys
- sys.path[0:0] = [
- join(base, 'eggs/demo-0.3-pyN.N.egg'),
- join(base, 'eggs/demoneeded-1.1-pyN.N.egg'),
- '/ba',
- join(base, 'bar'),
- ]
- <BLANKLINE>
- import eggrecipedemo
- <BLANKLINE>
- if __name__ == '__main__':
- eggrecipedemo.main()
-
-Note that the extra path we specified that was outside the directory
-passed as relative_paths wasn't converted to a relative path.
-
-Of course, running the script works:
-
- >>> print system(join(bo, 'bin', 'run')),
- 3 1
-
-We specified an interpreter and its paths are adjusted too:
-
- >>> cat(bo, 'bin', 'py') # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4
- <BLANKLINE>
- import os
- <BLANKLINE>
- join = os.path.join
- base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
- base = os.path.dirname(base)
- <BLANKLINE>
- import sys
- <BLANKLINE>
- sys.path[0:0] = [
- join(base, 'eggs/demo-0.3-pyN.N.egg'),
- join(base, 'eggs/demoneeded-1.1-pyN.N.egg'),
- '/ba',
- join(base, 'bar'),
- ]
- <BLANKLINE>
- _interactive = True
- if len(sys.argv) > 1:
- _options, _args = __import__("getopt").getopt(sys.argv[1:], 'ic:m:')
- _interactive = False
- for (_opt, _val) in _options:
- if _opt == '-i':
- _interactive = True
- elif _opt == '-c':
- exec _val
- elif _opt == '-m':
- sys.argv[1:] = _args
- _args = []
- __import__("runpy").run_module(
- _val, {}, "__main__", alter_sys=True)
- <BLANKLINE>
- if _args:
- sys.argv[:] = _args
- __file__ = _args[0]
- del _options, _args
- execfile(__file__)
- <BLANKLINE>
- if _interactive:
- del _interactive
- __import__("code").interact(banner="", local=globals())
-
-The ``sitepackage_safe_scripts`` function
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The newer function for creating scripts is ``sitepackage_safe_scripts``.
-It has the same basic functionality as the ``scripts`` function: it can
-create scripts to run arbitrary entry points, and to run a Python
-interpreter. The following are the differences from a user's
-perspective.
-
-- It can be used safely with a Python that has packages installed itself,
- such as a system-installed Python.
-
-- In contrast to the interpreter generated by the ``scripts`` method, which
- supports only a small subset of the usual Python executable's options,
- the interpreter generated by ``sitepackage_safe_scripts`` supports all
- of them. This makes it possible to use as full Python replacement for
- scripts that need the distributions specified in your buildout.
-
-- Both the interpreter and the entry point scripts allow you to include the
- site packages, and/or the sitecustomize, of the Python executable, if
- desired.
-
-It works by creating site.py and sitecustomize.py files that set up the
-desired paths and initialization. These must be placed within an otherwise
-empty directory. Typically this is in a recipe's parts directory.
-
-Here's the simplest example, building an interpreter script.
-
- >>> interpreter_dir = tmpdir('interpreter')
- >>> interpreter_parts_dir = os.path.join(
- ... interpreter_dir, 'parts', 'interpreter')
- >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin')
- >>> mkdir(interpreter_bin_dir)
- >>> mkdir(interpreter_dir, 'eggs')
- >>> mkdir(interpreter_dir, 'parts')
- >>> mkdir(interpreter_parts_dir)
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], join(interpreter_dir, 'eggs'), links=[link_server],
- ... index=link_server+'index/')
- >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
- ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
- ... interpreter='py')
-
-Depending on whether the machine being used is running Windows or not, this
-produces either three or four files. In both cases, we have site.py and
-sitecustomize.py generated in the parts/interpreter directory. For Windows,
-we have py.exe and py-script.py; for other operating systems, we have py.
-
- >>> sitecustomize_path = os.path.join(
- ... interpreter_parts_dir, 'sitecustomize.py')
- >>> site_path = os.path.join(interpreter_parts_dir, 'site.py')
- >>> interpreter_path = os.path.join(interpreter_bin_dir, 'py')
- >>> if sys.platform == 'win32':
- ... py_path = os.path.join(interpreter_bin_dir, 'py-script.py')
- ... expected = [sitecustomize_path,
- ... site_path,
- ... os.path.join(interpreter_bin_dir, 'py.exe'),
- ... py_path]
- ... else:
- ... py_path = interpreter_path
- ... expected = [sitecustomize_path, site_path, py_path]
- ...
- >>> assert generated == expected, repr((generated, expected))
-
-We didn't ask for any initialization, and we didn't ask to use the underlying
-sitecustomization, so sitecustomize.py is empty.
-
- >>> cat(sitecustomize_path)
-
-The interpreter script is simple. It puts the directory with the
-site.py and sitecustomize.py on the PYTHONPATH and (re)starts Python.
-
- >>> cat(py_path)
- #!/usr/bin/python -S
- import os
- import sys
- <BLANKLINE>
- argv = [sys.executable] + sys.argv[1:]
- environ = os.environ.copy()
- path = '/interpreter/parts/interpreter'
- if environ.get('PYTHONPATH'):
- path = os.pathsep.join([path, environ['PYTHONPATH']])
- environ['PYTHONPATH'] = path
- os.execve(sys.executable, argv, environ)
-
-The site.py file is a modified version of the underlying Python's site.py.
-The most important modification is that it has a different version of the
-addsitepackages function. It sets up the Python path, similarly to the
-behavior of the function it replaces. The following shows the part that
-buildout inserts, in the simplest case.
-
- >>> sys.stdout.write('#\n'); cat(site_path)
- ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- #...
- def addsitepackages(known_paths):
- """Add site packages, as determined by zc.buildout.
- <BLANKLINE>
- See original_addsitepackages, below, for the original version."""
- buildout_paths = [
- '/interpreter/eggs/demo-0.3-pyN.N.egg',
- '/interpreter/eggs/demoneeded-1.1-pyN.N.egg'
- ]
- for path in buildout_paths:
- sitedir, sitedircase = makepath(path)
- if not sitedircase in known_paths and os.path.exists(sitedir):
- sys.path.append(sitedir)
- known_paths.add(sitedircase)
- return known_paths
- <BLANKLINE>
- def original_addsitepackages(known_paths):...
-
-Here are some examples of the interpreter in use.
-
- >>> print call_py(interpreter_path, "print 16+26")
- 42
- <BLANKLINE>
- >>> res = call_py(interpreter_path, "import sys; print sys.path")
- >>> print res # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- ['',
- '/interpreter/parts/interpreter',
- ...,
- '/interpreter/eggs/demo-0.3-pyN.N.egg',
- '/interpreter/eggs/demoneeded-1.1-pyN.N.egg']
- <BLANKLINE>
- >>> clean_paths = eval(res.strip()) # This is used later for comparison.
-
-If you provide initialization, it goes in sitecustomize.py.
-
- >>> def reset_interpreter():
- ... # This is necessary because, in our tests, the timestamps of the
- ... # .pyc files are not outdated when we want them to be.
- ... rmdir(interpreter_bin_dir)
- ... mkdir(interpreter_bin_dir)
- ... rmdir(interpreter_parts_dir)
- ... mkdir(interpreter_parts_dir)
- ...
- >>> reset_interpreter()
-
- >>> initialization_string = """\
- ... import os
- ... os.environ['FOO'] = 'bar baz bing shazam'"""
- >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
- ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
- ... interpreter='py', initialization=initialization_string)
- >>> cat(sitecustomize_path)
- import os
- os.environ['FOO'] = 'bar baz bing shazam'
- >>> print call_py(interpreter_path, "import os; print os.environ['FOO']")
- bar baz bing shazam
- <BLANKLINE>
-
-If you use relative paths, this affects the interpreter and site.py. (This is
-again the UNIX version; the Windows version uses subprocess instead of
-os.execve.)
-
- >>> reset_interpreter()
- >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
- ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
- ... interpreter='py', relative_paths=interpreter_dir)
- >>> cat(py_path)
- #!/usr/bin/python -S
- import os
- import sys
- <BLANKLINE>
- join = os.path.join
- base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
- base = os.path.dirname(base)
- <BLANKLINE>
- argv = [sys.executable] + sys.argv[1:]
- environ = os.environ.copy()
- path = join(base, 'parts/interpreter')
- if environ.get('PYTHONPATH'):
- path = os.pathsep.join([path, environ['PYTHONPATH']])
- environ['PYTHONPATH'] = path
- os.execve(sys.executable, argv, environ)
-
-For site.py, we again show only the pertinent parts. Notice that the egg
-paths join a base to a path, as with the use of this argument in the
-``scripts`` function.
-
- >>> sys.stdout.write('#\n'); cat(site_path) # doctest: +ELLIPSIS
- #...
- def addsitepackages(known_paths):
- """Add site packages, as determined by zc.buildout.
- <BLANKLINE>
- See original_addsitepackages, below, for the original version."""
- join = os.path.join
- base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
- base = os.path.dirname(base)
- base = os.path.dirname(base)
- buildout_paths = [
- join(base, 'eggs/demo-0.3-pyN.N.egg'),
- join(base, 'eggs/demoneeded-1.1-pyN.N.egg')
- ]...
-
-The paths resolve in practice as you would expect.
-
- >>> print call_py(interpreter_path,
- ... "import sys, pprint; pprint.pprint(sys.path)")
- ... # doctest: +ELLIPSIS
- ['',
- '/interpreter/parts/interpreter',
- ...,
- '/interpreter/eggs/demo-0.3-pyN.N.egg',
- '/interpreter/eggs/demoneeded-1.1-pyN.N.egg']
- <BLANKLINE>
-
-The ``extra_paths`` argument affects the path in site.py. Notice that
-/interpreter/other is added after the eggs.
-
- >>> reset_interpreter()
- >>> mkdir(interpreter_dir, 'other')
- >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
- ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
- ... interpreter='py', extra_paths=[join(interpreter_dir, 'other')])
- >>> sys.stdout.write('#\n'); cat(site_path) # doctest: +ELLIPSIS
- #...
- def addsitepackages(known_paths):
- """Add site packages, as determined by zc.buildout.
- <BLANKLINE>
- See original_addsitepackages, below, for the original version."""
- buildout_paths = [
- '/interpreter/eggs/demo-0.3-pyN.N.egg',
- '/interpreter/eggs/demoneeded-1.1-pyN.N.egg',
- '/interpreter/other'
- ]...
-
- >>> print call_py(interpreter_path,
- ... "import sys, pprint; pprint.pprint(sys.path)")
- ... # doctest: +ELLIPSIS
- ['',
- '/interpreter/parts/interpreter',
- ...,
- '/interpreter/eggs/demo-0.3-pyN.N.egg',
- '/interpreter/eggs/demoneeded-1.1-pyN.N.egg',
- '/interpreter/other']
- <BLANKLINE>
-
-The ``sitepackage_safe_scripts`` function: using site-packages
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``sitepackage_safe_scripts`` function supports including site
-packages. This has some advantages and some serious dangers.
-
-A typical reason to include site-packages is that it is easier to
-install one or more dependencies in your Python than it is with
-buildout. Some packages, such as lxml or Python PostgreSQL integration,
-have dependencies that can be much easier to build and/or install using
-other mechanisms, such as your operating system's package manager. By
-installing some core packages into your Python's site-packages, this can
-significantly simplify some application installations.
-
-However, doing this has a significant danger. One of the primary goals
-of buildout is to provide repeatability. Some packages (one of the
-better known Python openid packages, for instance) change their behavior
-depending on what packages are available. If Python curl bindings are
-available, these may be preferred by the library. If a certain XML
-package is installed, it may be preferred by the library. These hidden
-choices may cause small or large behavior differences. The fact that
-they can be rarely encountered can actually make it worse: you forget
-that this might be a problem, and debugging the differences can be
-difficult. If you allow site-packages to be included in your buildout,
-and the Python you use is not managed precisely by your application (for
-instance, it is a system Python), you open yourself up to these
-possibilities. Don't be unaware of the dangers.
-
-That explained, let's see how it works. If you don't use namespace packages,
-this is very straightforward.
-
- >>> reset_interpreter()
- >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
- ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
- ... interpreter='py', include_site_packages=True)
- >>> sys.stdout.write('#\n'); cat(site_path)
- ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- #...
- def addsitepackages(known_paths):
- """Add site packages, as determined by zc.buildout.
- <BLANKLINE>
- See original_addsitepackages, below, for the original version."""
- setuptools_path = None
- buildout_paths = [
- '/interpreter/eggs/demo-0.3-pyN.N.egg',
- '/interpreter/eggs/demoneeded-1.1-pyN.N.egg'
- ]
- for path in buildout_paths:
- sitedir, sitedircase = makepath(path)
- if not sitedircase in known_paths and os.path.exists(sitedir):
- sys.path.append(sitedir)
- known_paths.add(sitedircase)
- sys.__egginsert = len(buildout_paths) # Support distribute.
- original_paths = [
- ...
- ]
- for path in original_paths:
- if path == setuptools_path or path not in known_paths:
- addsitedir(path, known_paths)
- return known_paths
- <BLANKLINE>
- def original_addsitepackages(known_paths):...
-
-It simply adds the original paths using addsitedir after the code to add the
-buildout paths.
-
-Here's an example of the new script in use. Other documents and tests in
-this package give the feature a more thorough workout, but this should
-give you an idea of the feature.
-
- >>> res = call_py(interpreter_path, "import sys; print sys.path")
- >>> print res # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- ['',
- '/interpreter/parts/interpreter',
- ...,
- '/interpreter/eggs/demo-0.3-py2.4.egg',
- '/interpreter/eggs/demoneeded-1.1-py2.4.egg',
- ...]
- <BLANKLINE>
-
-The clean_paths gathered earlier is a subset of this full list of paths.
-
- >>> full_paths = eval(res.strip())
- >>> len(clean_paths) < len(full_paths)
- True
- >>> set(os.path.normpath(p) for p in clean_paths).issubset(
- ... os.path.normpath(p) for p in full_paths)
- True
-
-Unfortunately, because of how setuptools namespace packages are implemented
-differently for operating system packages (debs or rpms) as opposed to
-standard setuptools installation, there's a slightly trickier dance if you
-use them. To show this we'll needs some extra eggs that use namespaces.
-We'll use the ``tellmy.fortune`` package, which we'll need to make an initial
-call to another text fixture to create.
-
- >>> from zc.buildout.tests import create_sample_namespace_eggs
- >>> namespace_eggs = tmpdir('namespace_eggs')
- >>> create_sample_namespace_eggs(namespace_eggs)
-
- >>> reset_interpreter()
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo', 'tellmy.fortune'], join(interpreter_dir, 'eggs'),
- ... links=[link_server, namespace_eggs], index=link_server+'index/')
- >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
- ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
- ... interpreter='py', include_site_packages=True)
- >>> sys.stdout.write('#\n'); cat(site_path)
- ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- #...
- def addsitepackages(known_paths):
- """Add site packages, as determined by zc.buildout.
- <BLANKLINE>
- See original_addsitepackages, below, for the original version."""
- setuptools_path = '...setuptools...'
- sys.path.append(setuptools_path)
- known_paths.add(os.path.normcase(setuptools_path))
- import pkg_resources
- buildout_paths = [
- '/interpreter/eggs/demo-0.3-pyN.N.egg',
- '/interpreter/eggs/tellmy.fortune-1.0-pyN.N.egg',
- '...setuptools...',
- '/interpreter/eggs/demoneeded-1.1-pyN.N.egg'
- ]
- for path in buildout_paths:
- sitedir, sitedircase = makepath(path)
- if not sitedircase in known_paths and os.path.exists(sitedir):
- sys.path.append(sitedir)
- known_paths.add(sitedircase)
- pkg_resources.working_set.add_entry(sitedir)
- sys.__egginsert = len(buildout_paths) # Support distribute.
- original_paths = [
- ...
- ]
- for path in original_paths:
- if path == setuptools_path or path not in known_paths:
- addsitedir(path, known_paths)
- return known_paths
- <BLANKLINE>
- def original_addsitepackages(known_paths):...
-
- >>> print call_py(interpreter_path, "import sys; print sys.path")
- ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- ['',
- '/interpreter/parts/interpreter',
- ...,
- '...setuptools...',
- '/interpreter/eggs/demo-0.3-pyN.N.egg',
- '/interpreter/eggs/tellmy.fortune-1.0-pyN.N.egg',
- '/interpreter/eggs/demoneeded-1.1-pyN.N.egg',
- ...]
-
-As you can see, the script now first imports pkg_resources. Then we
-need to process egg files specially to look for namespace packages there
-*before* we process process lines in .pth files that use the "import"
-feature--lines that might be part of the setuptools namespace package
-implementation for system packages, as mentioned above, and that must
-come after processing egg namespaces.
-
-The most complex that this function gets is if you use namespace packages,
-include site-packages, and use relative paths. For completeness, we'll look
-at that result.
-
- >>> reset_interpreter()
- >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
- ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
- ... interpreter='py', include_site_packages=True,
- ... relative_paths=interpreter_dir)
- >>> sys.stdout.write('#\n'); cat(site_path)
- ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- #...
- def addsitepackages(known_paths):
- """Add site packages, as determined by zc.buildout.
- <BLANKLINE>
- See original_addsitepackages, below, for the original version."""
- join = os.path.join
- base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
- base = os.path.dirname(base)
- base = os.path.dirname(base)
- setuptools_path = '...setuptools...'
- sys.path.append(setuptools_path)
- known_paths.add(os.path.normcase(setuptools_path))
- import pkg_resources
- buildout_paths = [
- join(base, 'eggs/demo-0.3-pyN.N.egg'),
- join(base, 'eggs/tellmy.fortune-1.0-pyN.N.egg'),
- '...setuptools...',
- join(base, 'eggs/demoneeded-1.1-pyN.N.egg')
- ]
- for path in buildout_paths:
- sitedir, sitedircase = makepath(path)
- if not sitedircase in known_paths and os.path.exists(sitedir):
- sys.path.append(sitedir)
- known_paths.add(sitedircase)
- pkg_resources.working_set.add_entry(sitedir)
- sys.__egginsert = len(buildout_paths) # Support distribute.
- original_paths = [
- ...
- ]
- for path in original_paths:
- if path == setuptools_path or path not in known_paths:
- addsitedir(path, known_paths)
- return known_paths
- <BLANKLINE>
- def original_addsitepackages(known_paths):...
-
- >>> print call_py(interpreter_path, "import sys; print sys.path")
- ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- ['',
- '/interpreter/parts/interpreter',
- ...,
- '...setuptools...',
- '/interpreter/eggs/demo-0.3-pyN.N.egg',
- '/interpreter/eggs/tellmy.fortune-1.0-pyN.N.egg',
- '/interpreter/eggs/demoneeded-1.1-pyN.N.egg',
- ...]
-
-The ``exec_sitecustomize`` argument does the same thing for the
-sitecustomize module--it allows you to include the code from the
-sitecustomize module in the underlying Python if you set the argument to
-True. The z3c.recipe.scripts package sets up the full environment necessary
-to demonstrate this piece.
-
-The ``sitepackage_safe_scripts`` function: writing scripts for entry points
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-All of the examples so far for this function have been creating
-interpreters. The function can also write scripts for entry
-points. They are almost identical to the scripts that we saw for the
-``scripts`` function except that they ``import site`` after setting the
-sys.path to include our custom site.py and sitecustomize.py files. These
-files then initialize the Python environment as we have already seen. Let's
-see a simple example.
-
- >>> reset_interpreter()
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], join(interpreter_dir, 'eggs'), links=[link_server],
- ... index=link_server+'index/')
- >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
- ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
- ... reqs=['demo'])
-
-As before, in Windows, 2 files are generated for each script. A script
-file, ending in '-script.py', and an exe file that allows the script
-to be invoked directly without having to specify the Python
-interpreter and without having to provide a '.py' suffix. This is in addition
-to the site.py and sitecustomize.py files that are generated as with our
-interpreter examples above.
-
- >>> if sys.platform == 'win32':
- ... demo_path = os.path.join(interpreter_bin_dir, 'demo-script.py')
- ... expected = [sitecustomize_path,
- ... site_path,
- ... os.path.join(interpreter_bin_dir, 'demo.exe'),
- ... demo_path]
- ... else:
- ... demo_path = os.path.join(interpreter_bin_dir, 'demo')
- ... expected = [sitecustomize_path, site_path, demo_path]
- ...
- >>> assert generated == expected, repr((generated, expected))
-
-The demo script runs the entry point defined in the demo egg:
-
- >>> cat(demo_path) # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4 -S
- <BLANKLINE>
- import sys
- sys.path[0:0] = [
- '/interpreter/parts/interpreter',
- ]
- <BLANKLINE>
- <BLANKLINE>
- import os
- path = sys.path[0]
- if os.environ.get('PYTHONPATH'):
- path = os.pathsep.join([path, os.environ['PYTHONPATH']])
- os.environ['BUILDOUT_ORIGINAL_PYTHONPATH'] = os.environ.get('PYTHONPATH', '')
- os.environ['PYTHONPATH'] = path
- import site # imports custom buildout-generated site.py
- <BLANKLINE>
- import eggrecipedemo
- <BLANKLINE>
- if __name__ == '__main__':
- eggrecipedemo.main()
-
- >>> demo_call = join(interpreter_bin_dir, 'demo')
- >>> if sys.platform == 'win32':
- ... demo_call = '"%s"' % demo_call
- >>> print system(demo_call)
- 3 1
- <BLANKLINE>
-
-There are a few differences from the ``scripts`` function. First, the
-``reqs`` argument (an iterable of string requirements or entry point
-tuples) is a keyword argument here. We see that in the example above.
-Second, the ``arguments`` argument is now named ``script_arguments`` to
-try and clarify that it does not affect interpreters. While the
-``initialization`` argument continues to affect both the interpreters
-and the entry point scripts, if you have initialization that is only
-pertinent to the entry point scripts, you can use the
-``script_initialization`` argument.
-
-Let's see ``script_arguments`` and ``script_initialization`` in action.
-
- >>> reset_interpreter()
- >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
- ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
- ... reqs=['demo'], script_arguments='1, 2',
- ... script_initialization='import os\nos.chdir("foo")')
-
- >>> cat(demo_path) # doctest: +NORMALIZE_WHITESPACE
- #!/usr/local/bin/python2.4 -S
- import sys
- sys.path[0:0] = [
- '/interpreter/parts/interpreter',
- ]
- <BLANKLINE>
- import os
- path = sys.path[0]
- if os.environ.get('PYTHONPATH'):
- path = os.pathsep.join([path, os.environ['PYTHONPATH']])
- os.environ['BUILDOUT_ORIGINAL_PYTHONPATH'] = os.environ.get('PYTHONPATH', '')
- os.environ['PYTHONPATH'] = path
- import site # imports custom buildout-generated site.py
- import os
- os.chdir("foo")
- <BLANKLINE>
- import eggrecipedemo
- <BLANKLINE>
- if __name__ == '__main__':
- eggrecipedemo.main(1, 2)
-
-Handling custom build options for extensions provided in source distributions
------------------------------------------------------------------------------
-
-Sometimes, we need to control how extension modules are built. The
-build function provides this level of control. It takes a single
-package specification, downloads a source distribution, and builds it
-with specified custom build options.
-
-The build function takes 3 positional arguments:
-
-spec
- A package specification for a source distribution
-
-dest
- A destination directory
-
-build_ext
- A dictionary of options to be passed to the distutils build_ext
- command when building extensions.
-
-It supports a number of optional keyword arguments:
-
-links
- a sequence of URLs, file names, or directories to look for
- links to distributions,
-
-index
- The URL of an index server, or almost any other valid URL. :)
-
- If not specified, the Python Package Index,
- http://pypi.python.org/simple/, is used. You can specify an
- alternate index with this option. If you use the links option and
- if the links point to the needed distributions, then the index can
- be anything and will be largely ignored. In the examples, here,
- we'll just point to an empty directory on our link server. This
- will make our examples run a little bit faster.
-
-executable
- A path to a Python executable. Distributions will be installed
- using this executable and will be for the matching Python version.
-
-path
- A list of additional directories to search for locally-installed
- distributions.
-
-newest
- A boolean value indicating whether to search for new distributions
- when already-installed distributions meet the requirement. When
- this is true, the default, and when the destination directory is
- not None, then the install function will search for the newest
- distributions that satisfy the requirements.
-
-versions
- A dictionary mapping project names to version numbers to be used
- when selecting distributions. This can be used to specify a set of
- distribution versions independent of other requirements.
-
-
-Our link server included a source distribution that includes a simple
-extension, extdemo.c::
-
- #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
- }
-
-The extension depends on a system-dependent include file, extdemo.h,
-that defines a constant, EXTDEMO, that is exposed by the extension.
-
-We'll add an include directory to our sample buildout and add the
-needed include file to it:
-
- >>> mkdir('include')
- >>> write('include', 'extdemo.h',
- ... """
- ... #define EXTDEMO 42
- ... """)
-
-Now, we can use the build function to create an egg from the source
-distribution:
-
- >>> zc.buildout.easy_install.build(
- ... 'extdemo', dest,
- ... {'include-dirs': os.path.join(sample_buildout, 'include')},
- ... links=[link_server], index=link_server+'index/')
- ['/sample-install/extdemo-1.4-py2.4-unix-i686.egg']
-
-The function returns the list of eggs
-
-Now if we look in our destination directory, we see we have an extdemo egg:
-
- >>> ls(dest)
- - demo-0.2-py2.4.egg
- d demo-0.3-py2.4.egg
- - demoneeded-1.0-py2.4.egg
- d demoneeded-1.1-py2.4.egg
- d extdemo-1.4-py2.4-unix-i686.egg
-
-Let's update our link server with a new version of extdemo:
-
- >>> update_extdemo()
- >>> print get(link_server),
- <html><body>
- <a href="bigdemo-0.1-py2.4.egg">bigdemo-0.1-py2.4.egg</a><br>
- <a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br>
- <a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br>
- <a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br>
- <a href="demo-0.4c1-py2.4.egg">demo-0.4c1-py2.4.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="extdemo-1.5.zip">extdemo-1.5.zip</a><br>
- <a href="index/">index/</a><br>
- <a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br>
- </body></html>
-
-The easy_install caches information about servers to reduce network
-access. To see the update, we have to call the clear_index_cache
-function to clear the index cache:
-
- >>> zc.buildout.easy_install.clear_index_cache()
-
-If we run build with newest set to False, we won't get an update:
-
- >>> zc.buildout.easy_install.build(
- ... 'extdemo', dest,
- ... {'include-dirs': os.path.join(sample_buildout, 'include')},
- ... links=[link_server], index=link_server+'index/',
- ... newest=False)
- ['/sample-install/extdemo-1.4-py2.4-linux-i686.egg']
-
- >>> ls(dest)
- - demo-0.2-py2.4.egg
- d demo-0.3-py2.4.egg
- - demoneeded-1.0-py2.4.egg
- d demoneeded-1.1-py2.4.egg
- d extdemo-1.4-py2.4-unix-i686.egg
-
-But if we run it with the default True setting for newest, then we'll
-get an updated egg:
-
- >>> zc.buildout.easy_install.build(
- ... 'extdemo', dest,
- ... {'include-dirs': os.path.join(sample_buildout, 'include')},
- ... links=[link_server], index=link_server+'index/')
- ['/sample-install/extdemo-1.5-py2.4-unix-i686.egg']
-
- >>> ls(dest)
- - demo-0.2-py2.4.egg
- d demo-0.3-py2.4.egg
- - demoneeded-1.0-py2.4.egg
- d demoneeded-1.1-py2.4.egg
- d extdemo-1.4-py2.4-unix-i686.egg
- d extdemo-1.5-py2.4-unix-i686.egg
-
-The versions option also influences the versions used. For example,
-if we specify a version for extdemo, then that will be used, even
-though it isn't the newest. Let's clean out the destination directory
-first:
-
- >>> import os
- >>> for name in os.listdir(dest):
- ... remove(dest, name)
-
- >>> zc.buildout.easy_install.build(
- ... 'extdemo', dest,
- ... {'include-dirs': os.path.join(sample_buildout, 'include')},
- ... links=[link_server], index=link_server+'index/',
- ... versions=dict(extdemo='1.4'))
- ['/sample-install/extdemo-1.4-py2.4-unix-i686.egg']
-
- >>> ls(dest)
- d extdemo-1.4-py2.4-unix-i686.egg
-
-Handling custom build options for extensions in develop eggs
-------------------------------------------------------------
-
-The develop function is similar to the build function, except that,
-rather than building an egg from a source directory containing a
-setup.py script.
-
-The develop function takes 2 positional arguments:
-
-setup
- The path to a setup script, typically named "setup.py", or a
- directory containing a setup.py script.
-
-dest
- The directory to install the egg link to
-
-It supports some optional keyword argument:
-
-build_ext
- A dictionary of options to be passed to the distutils build_ext
- command when building extensions.
-
-executable
- A path to a Python executable. Distributions will be installed
- using this executable and will be for the matching Python version.
-
-We have a local directory containing the extdemo source:
-
- >>> ls(extdemo)
- - MANIFEST
- - MANIFEST.in
- - README
- - extdemo.c
- - setup.py
-
-Now, we can use the develop function to create a develop egg from the source
-distribution:
-
- >>> zc.buildout.easy_install.develop(
- ... extdemo, dest,
- ... {'include-dirs': os.path.join(sample_buildout, 'include')})
- '/sample-install/extdemo.egg-link'
-
-The name of the egg link created is returned.
-
-Now if we look in our destination directory, we see we have an extdemo
-egg link:
-
- >>> ls(dest)
- d extdemo-1.4-py2.4-unix-i686.egg
- - extdemo.egg-link
-
-And that the source directory contains the compiled extension:
-
- >>> ls(extdemo)
- - MANIFEST
- - MANIFEST.in
- - README
- d build
- - extdemo.c
- d extdemo.egg-info
- - extdemo.so
- - setup.py
-
-Download cache
---------------
-
-Normally, when distributions are installed, if any processing is
-needed, they are downloaded from the internet to a temporary directory
-and then installed from there. A download cache can be used to avoid
-the download step. This can be useful to reduce network access and to
-create source distributions of an entire buildout.
-
-A download cache is specified by calling the download_cache
-function. The function always returns the previous setting. If no
-argument is passed, then the setting is unchanged. If an argument is
-passed, the download cache is set to the given path, which must point
-to an existing directory. Passing None clears the cache setting.
-
-To see this work, we'll create a directory and set it as the cache
-directory:
-
- >>> cache = tmpdir('cache')
- >>> zc.buildout.easy_install.download_cache(cache)
-
-We'll recreate our destination directory:
-
- >>> remove(dest)
- >>> dest = tmpdir('sample-install')
-
-We'd like to see what is being fetched from the server, so we'll
-enable server logging:
-
- >>> get(link_server+'enable_server_logging')
- GET 200 /enable_server_logging
- ''
-
-Now, if we install demo, and extdemo:
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo==0.2'], dest,
- ... links=[link_server], index=link_server+'index/',
- ... always_unzip=True)
- GET 200 /
- GET 404 /index/demo/
- GET 200 /index/
- GET 200 /demo-0.2-py2.4.egg
- GET 404 /index/demoneeded/
- GET 200 /demoneeded-1.1.zip
-
- >>> zc.buildout.easy_install.build(
- ... 'extdemo', dest,
- ... {'include-dirs': os.path.join(sample_buildout, 'include')},
- ... links=[link_server], index=link_server+'index/')
- GET 404 /index/extdemo/
- GET 200 /extdemo-1.5.zip
- ['/sample-install/extdemo-1.5-py2.4-linux-i686.egg']
-
-Not only will we get eggs in our destination directory:
-
- >>> ls(dest)
- d demo-0.2-py2.4.egg
- d demoneeded-1.1-py2.4.egg
- d extdemo-1.5-py2.4-linux-i686.egg
-
-But we'll get distributions in the cache directory:
-
- >>> ls(cache)
- - demo-0.2-py2.4.egg
- - demoneeded-1.1.zip
- - extdemo-1.5.zip
-
-The cache directory contains uninstalled distributions, such as zipped
-eggs or source distributions.
-
-Let's recreate our destination directory and clear the index cache:
-
- >>> remove(dest)
- >>> dest = tmpdir('sample-install')
- >>> zc.buildout.easy_install.clear_index_cache()
-
-Now when we install the distributions:
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo==0.2'], dest,
- ... links=[link_server], index=link_server+'index/',
- ... always_unzip=True)
- GET 200 /
- GET 404 /index/demo/
- GET 200 /index/
- GET 404 /index/demoneeded/
-
- >>> zc.buildout.easy_install.build(
- ... 'extdemo', dest,
- ... {'include-dirs': os.path.join(sample_buildout, 'include')},
- ... links=[link_server], index=link_server+'index/')
- GET 404 /index/extdemo/
- ['/sample-install/extdemo-1.5-py2.4-linux-i686.egg']
-
- >>> ls(dest)
- d demo-0.2-py2.4.egg
- d demoneeded-1.1-py2.4.egg
- d extdemo-1.5-py2.4-linux-i686.egg
-
-Note that we didn't download the distributions from the link server.
-
-If we remove the restriction on demo, we'll download a newer version
-from the link server:
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest,
- ... links=[link_server], index=link_server+'index/',
- ... always_unzip=True)
- GET 200 /demo-0.3-py2.4.egg
-
-Normally, the download cache is the preferred source of downloads, but
-not the only one.
-
-Installing solely from a download cache
----------------------------------------
-
-A download cache can be used as the basis of application source
-releases. In an application source release, we want to distribute an
-application that can be built without making any network accesses. In
-this case, we distribute a download cache and tell the easy_install
-module to install from the download cache only, without making network
-accesses. The install_from_cache function can be used to signal that
-packages should be installed only from the download cache. The
-function always returns the previous setting. Calling it with no
-arguments returns the current setting without changing it:
-
- >>> zc.buildout.easy_install.install_from_cache()
- False
-
-Calling it with a boolean value changes the setting and returns the
-previous setting:
-
- >>> zc.buildout.easy_install.install_from_cache(True)
- False
-
-Let's remove demo-0.3-py2.4.egg from the cache, clear the index cache,
-recreate the destination directory, and reinstall demo:
-
- >>> for f in os.listdir(cache):
- ... if f.startswith('demo-0.3-'):
- ... remove(cache, f)
-
- >>> zc.buildout.easy_install.clear_index_cache()
- >>> remove(dest)
- >>> dest = tmpdir('sample-install')
-
- >>> ws = zc.buildout.easy_install.install(
- ... ['demo'], dest,
- ... links=[link_server], index=link_server+'index/',
- ... always_unzip=True)
-
- >>> ls(dest)
- d demo-0.2-py2.4.egg
- d demoneeded-1.1-py2.4.egg
-
-This time, we didn't download from or even query the link server.
-
-.. Disable the download cache:
-
- >>> zc.buildout.easy_install.download_cache(None)
- '/cache'
-
- >>> zc.buildout.easy_install.install_from_cache(False)
- True