summaryrefslogtreecommitdiff
path: root/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.py
diff options
context:
space:
mode:
authorNishanth Amuluru2011-01-11 22:41:51 +0530
committerNishanth Amuluru2011-01-11 22:41:51 +0530
commitb03203c8cb991c16ac8a3d74c8c4078182d0bb48 (patch)
tree7cf13b2deacbfaaec99edb431b83ddd5ea734a52 /eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.py
parent0c50203cd9eb94b819883c3110922e873f003138 (diff)
downloadpytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.gz
pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.bz2
pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.zip
removed all the buildout files
Diffstat (limited to 'eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.py')
-rw-r--r--eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.py1906
1 files changed, 0 insertions, 1906 deletions
diff --git a/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.py b/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.py
deleted file mode 100644
index b09c0c5..0000000
--- a/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/easy_install.py
+++ /dev/null
@@ -1,1906 +0,0 @@
-#############################################################################
-#
-# Copyright (c) 2005 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Python easy_install API
-
-This module provides a high-level Python API for installing packages.
-It doesn't install scripts. It uses setuptools and requires it to be
-installed.
-"""
-
-import distutils.errors
-import fnmatch
-import glob
-import logging
-import os
-import pkg_resources
-import py_compile
-import re
-import setuptools.archive_util
-import setuptools.command.setopt
-import setuptools.package_index
-import shutil
-import subprocess
-import sys
-import tempfile
-import warnings
-import zc.buildout
-import zipimport
-
-_oprp = getattr(os.path, 'realpath', lambda path: path)
-def realpath(path):
- return os.path.normcase(os.path.abspath(_oprp(path)))
-
-default_index_url = os.environ.get(
- 'buildout-testing-index-url',
- 'http://pypi.python.org/simple',
- )
-
-logger = logging.getLogger('zc.buildout.easy_install')
-
-url_match = re.compile('[a-z0-9+.-]+://').match
-
-is_win32 = sys.platform == 'win32'
-is_jython = sys.platform.startswith('java')
-is_distribute = (
- pkg_resources.Requirement.parse('setuptools').key=='distribute')
-
-BROKEN_DASH_S_WARNING = (
- 'Buildout has been asked to exclude or limit site-packages so that '
- 'builds can be repeatable when using a system Python. However, '
- 'the chosen Python executable has a broken implementation of -S (see '
- 'https://bugs.launchpad.net/virtualenv/+bug/572545 for an example '
- "problem) and this breaks buildout's ability to isolate site-packages. "
- "If the executable already has a clean site-packages (e.g., "
- "using virtualenv's ``--no-site-packages`` option) you may be getting "
- 'equivalent repeatability. To silence this warning, use the -s argument '
- 'to the buildout script. Alternatively, use a Python executable with a '
- 'working -S (such as a standard Python binary).')
-
-if is_jython:
- import java.lang.System
- jython_os_name = (java.lang.System.getProperties()['os.name']).lower()
-
-setuptools_loc = pkg_resources.working_set.find(
- pkg_resources.Requirement.parse('setuptools')
- ).location
-
-# Include buildout and setuptools eggs in paths. We prevent dupes just to
-# keep from duplicating any log messages about them.
-buildout_loc = pkg_resources.working_set.find(
- pkg_resources.Requirement.parse('zc.buildout')).location
-buildout_and_setuptools_path = [setuptools_loc]
-if os.path.normpath(setuptools_loc) != os.path.normpath(buildout_loc):
- buildout_and_setuptools_path.append(buildout_loc)
-
-def _has_broken_dash_S(executable):
- """Detect https://bugs.launchpad.net/virtualenv/+bug/572545 ."""
- # The first attempt here was to simply have the executable attempt to import
- # ConfigParser and return the return code. That worked except for tests on
- # Windows, where the return code was wrong for the fake Python executable
- # generated by the virtualenv.txt test, apparently because setuptools' .exe
- # file does not pass the -script.py's returncode back properly, at least in
- # some circumstances. Therefore...print statements.
- stdout, stderr = subprocess.Popen(
- [executable, '-Sc',
- 'try:\n'
- ' import ConfigParser\n'
- 'except ImportError:\n'
- ' print 1\n'
- 'else:\n'
- ' print 0\n'],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
- return bool(int(stdout.strip()))
-
-def _get_system_paths(executable):
- """Return lists of standard lib and site paths for executable.
- """
- # We want to get a list of the site packages, which is not easy.
- # The canonical way to do this is to use
- # distutils.sysconfig.get_python_lib(), but that only returns a
- # single path, which does not reflect reality for many system
- # Pythons, which have multiple additions. Instead, we start Python
- # with -S, which does not import site.py and set up the extra paths
- # like site-packages or (Ubuntu/Debian) dist-packages and
- # python-support. We then compare that sys.path with the normal one
- # (minus user packages if this is Python 2.6, because we don't
- # support those (yet?). The set of the normal one minus the set of
- # the ones in ``python -S`` is the set of packages that are
- # effectively site-packages.
- #
- # The given executable might not be the current executable, so it is
- # appropriate to do another subprocess to figure out what the
- # additional site-package paths are. Moreover, even if this
- # executable *is* the current executable, this code might be run in
- # the context of code that has manipulated the sys.path--for
- # instance, to add local zc.buildout or setuptools eggs.
- def get_sys_path(*args, **kwargs):
- cmd = [executable]
- cmd.extend(args)
- cmd.extend([
- "-c", "import sys, os;"
- "print repr([os.path.normpath(p) for p in sys.path if p])"])
- # Windows needs some (as yet to be determined) part of the real env.
- env = os.environ.copy()
- # We need to make sure that PYTHONPATH, which will often be set
- # to include a custom buildout-generated site.py, is not set, or
- # else we will not get an accurate sys.path for the executable.
- env.pop('PYTHONPATH', None)
- env.update(kwargs)
- _proc = subprocess.Popen(
- cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
- stdout, stderr = _proc.communicate();
- if _proc.returncode:
- raise RuntimeError(
- 'error trying to get system packages:\n%s' % (stderr,))
- res = eval(stdout.strip())
- try:
- res.remove('.')
- except ValueError:
- pass
- return res
- stdlib = get_sys_path('-S') # stdlib only
- no_user_paths = get_sys_path(PYTHONNOUSERSITE='x')
- site_paths = [p for p in no_user_paths if p not in stdlib]
- return (stdlib, site_paths)
-
-def _get_version_info(executable):
- cmd = [executable, '-Sc',
- 'import sys; print(repr(tuple(x for x in sys.version_info)))']
- _proc = subprocess.Popen(
- cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout, stderr = _proc.communicate();
- if _proc.returncode:
- raise RuntimeError(
- 'error trying to get system packages:\n%s' % (stderr,))
- return eval(stdout.strip())
-
-
-class IncompatibleVersionError(zc.buildout.UserError):
- """A specified version is incompatible with a given requirement.
- """
-
-_versions = {sys.executable: '%d.%d' % sys.version_info[:2]}
-def _get_version(executable):
- try:
- return _versions[executable]
- except KeyError:
- cmd = _safe_arg(executable) + ' -V'
- p = subprocess.Popen(cmd,
- shell=True,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- close_fds=not is_win32)
- i, o = (p.stdin, p.stdout)
- i.close()
- version = o.read().strip()
- o.close()
- pystring, version = version.split()
- assert pystring == 'Python'
- version = re.match('(\d[.]\d)([.].*\d)?$', version).group(1)
- _versions[executable] = version
- return version
-
-FILE_SCHEME = re.compile('file://', re.I).match
-
-
-class AllowHostsPackageIndex(setuptools.package_index.PackageIndex):
- """Will allow urls that are local to the system.
-
- No matter what is allow_hosts.
- """
- def url_ok(self, url, fatal=False):
- if FILE_SCHEME(url):
- return True
- return setuptools.package_index.PackageIndex.url_ok(self, url, False)
-
-
-_indexes = {}
-def _get_index(executable, index_url, find_links, allow_hosts=('*',),
- path=None):
- # If path is None, the index will use sys.path. If you provide an empty
- # path ([]), it will complain uselessly about missing index pages for
- # packages found in the paths that you expect to use. Therefore, this path
- # is always the same as the _env path in the Installer.
- key = executable, index_url, tuple(find_links)
- index = _indexes.get(key)
- if index is not None:
- return index
-
- if index_url is None:
- index_url = default_index_url
- index = AllowHostsPackageIndex(
- index_url, hosts=allow_hosts, search_path=path,
- python=_get_version(executable)
- )
-
- if find_links:
- index.add_find_links(find_links)
-
- _indexes[key] = index
- return index
-
-clear_index_cache = _indexes.clear
-
-if is_win32:
- # work around spawn lamosity on windows
- # XXX need safe quoting (see the subprocess.list2cmdline) and test
- def _safe_arg(arg):
- return '"%s"' % arg
-else:
- _safe_arg = str
-
-# The following string is used to run easy_install in
-# Installer._call_easy_install. It is usually started with python -S
-# (that is, don't import site at start). That flag, and all of the code
-# in this snippet above the last two lines, exist to work around a
-# relatively rare problem. If
-#
-# - your buildout configuration is trying to install a package that is within
-# a namespace package, and
-#
-# - you use a Python that has a different version of this package
-# installed in in its site-packages using
-# --single-version-externally-managed (that is, using the mechanism
-# sometimes used by system packagers:
-# http://peak.telecommunity.com/DevCenter/setuptools#install-command ), and
-#
-# - the new package tries to do sys.path tricks in the setup.py to get a
-# __version__,
-#
-# then the older package will be loaded first, making the setup version
-# the wrong number. While very arguably packages simply shouldn't do
-# the sys.path tricks, some do, and we don't want buildout to fall over
-# when they do.
-#
-# The namespace packages installed in site-packages with
-# --single-version-externally-managed use a mechanism that cause them to
-# be processed when site.py is imported (see
-# http://mail.python.org/pipermail/distutils-sig/2009-May/011730.html
-# for another description of the problem). Simply starting Python with
-# -S addresses the problem in Python 2.4 and 2.5, but Python 2.6's
-# distutils imports a value from the site module, so we unfortunately
-# have to do more drastic surgery in the _easy_install_preface code below.
-#
-# Here's an example of the .pth files created by setuptools when using that
-# flag:
-#
-# import sys,new,os;
-# p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('<NAMESPACE>',));
-# ie = os.path.exists(os.path.join(p,'__init__.py'));
-# m = not ie and sys.modules.setdefault('<NAMESPACE>',new.module('<NAMESPACE>'));
-# mp = (m or []) and m.__dict__.setdefault('__path__',[]);
-# (p not in mp) and mp.append(p)
-#
-# The code, below, then, runs under -S, indicating that site.py should
-# not be loaded initially. It gets the initial sys.path under these
-# circumstances, and then imports site (because Python 2.6's distutils
-# will want it, as mentioned above). It then reinstates the old sys.path
-# value. Then it removes namespace packages (created by the setuptools
-# code above) from sys.modules. It identifies namespace packages by
-# iterating over every loaded module. It first looks if there is a
-# __path__, so it is a package; and then it sees if that __path__ does
-# not have an __init__.py. (Note that PEP 382,
-# http://www.python.org/dev/peps/pep-0382, makes it possible to have a
-# namespace package that has an __init__.py, but also should make it
-# unnecessary for site.py to preprocess these packages, so it should be
-# fine, as far as can be guessed as of this writing.) Finally, it
-# imports easy_install and runs it.
-_easy_install_preface = '''\
-import sys,os;\
-p = sys.path[:];\
-import site;\
-sys.path[:] = p;\
-[sys.modules.pop(k) for k, v in sys.modules.items()\
- if hasattr(v, '__path__') and len(v.__path__)==1 and\
- not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))];'''
-_easy_install_cmd = (
- 'from setuptools.command.easy_install import main;main()')
-
-
-class Installer:
-
- _versions = {}
- _download_cache = None
- _install_from_cache = False
- _prefer_final = True
- _use_dependency_links = True
- _allow_picked_versions = True
- _always_unzip = False
- _include_site_packages = True
- _allowed_eggs_from_site_packages = ('*',)
-
- def __init__(self,
- dest=None,
- links=(),
- index=None,
- executable=sys.executable,
- always_unzip=None,
- path=None,
- newest=True,
- versions=None,
- use_dependency_links=None,
- allow_hosts=('*',),
- include_site_packages=None,
- allowed_eggs_from_site_packages=None,
- prefer_final=None,
- ):
- self._dest = dest
- self._allow_hosts = allow_hosts
-
- if self._install_from_cache:
- if not self._download_cache:
- raise ValueError("install_from_cache set to true with no"
- " download cache")
- links = ()
- index = 'file://' + self._download_cache
-
- if use_dependency_links is not None:
- self._use_dependency_links = use_dependency_links
- if prefer_final is not None:
- self._prefer_final = prefer_final
- self._links = links = list(_fix_file_links(links))
- if self._download_cache and (self._download_cache not in links):
- links.insert(0, self._download_cache)
-
- self._index_url = index
- self._executable = executable
- self._has_broken_dash_S = _has_broken_dash_S(self._executable)
- if always_unzip is not None:
- self._always_unzip = always_unzip
- path = (path and path[:] or [])
- if include_site_packages is not None:
- self._include_site_packages = include_site_packages
- if allowed_eggs_from_site_packages is not None:
- self._allowed_eggs_from_site_packages = tuple(
- allowed_eggs_from_site_packages)
- if self._has_broken_dash_S:
- if (not self._include_site_packages or
- self._allowed_eggs_from_site_packages != ('*',)):
- # We can't do this if the executable has a broken -S.
- warnings.warn(BROKEN_DASH_S_WARNING)
- self._include_site_packages = True
- self._allowed_eggs_from_site_packages = ('*',)
- self._easy_install_cmd = _easy_install_cmd
- else:
- self._easy_install_cmd = _easy_install_preface + _easy_install_cmd
- self._easy_install_cmd = _safe_arg(self._easy_install_cmd)
- stdlib, self._site_packages = _get_system_paths(executable)
- version_info = _get_version_info(executable)
- if version_info == sys.version_info:
- # Maybe we can add the buildout and setuptools path. If we
- # are including site_packages, we only have to include the extra
- # bits here, so we don't duplicate. On the other hand, if we
- # are not including site_packages, we only want to include the
- # parts that are not in site_packages, so the code is the same.
- path.extend(
- set(buildout_and_setuptools_path).difference(
- self._site_packages))
- if self._include_site_packages:
- path.extend(self._site_packages)
- if dest is not None and dest not in path:
- path.insert(0, dest)
- self._path = path
- if self._dest is None:
- newest = False
- self._newest = newest
- self._env = pkg_resources.Environment(path,
- python=_get_version(executable))
- self._index = _get_index(executable, index, links, self._allow_hosts,
- self._path)
-
- if versions is not None:
- self._versions = versions
-
- _allowed_eggs_from_site_packages_regex = None
- def allow_site_package_egg(self, name):
- if (not self._include_site_packages or
- not self._allowed_eggs_from_site_packages):
- # If the answer is a blanket "no," perform a shortcut.
- return False
- if self._allowed_eggs_from_site_packages_regex is None:
- pattern = '(%s)' % (
- '|'.join(
- fnmatch.translate(name)
- for name in self._allowed_eggs_from_site_packages),
- )
- self._allowed_eggs_from_site_packages_regex = re.compile(pattern)
- return bool(self._allowed_eggs_from_site_packages_regex.match(name))
-
- def _satisfied(self, req, source=None):
- # We get all distributions that match the given requirement. If we are
- # not supposed to include site-packages for the given egg, we also
- # filter those out. Even if include_site_packages is False and so we
- # have excluded site packages from the _env's paths (see
- # Installer.__init__), we need to do the filtering here because an
- # .egg-link, such as one for setuptools or zc.buildout installed by
- # zc.buildout.buildout.Buildout.bootstrap, can indirectly include a
- # path in our _site_packages.
- dists = [dist for dist in self._env[req.project_name] if (
- dist in req and (
- dist.location not in self._site_packages or
- self.allow_site_package_egg(dist.project_name))
- )
- ]
- if not dists:
- logger.debug('We have no distributions for %s that satisfies %r.',
- req.project_name, str(req))
-
- return None, self._obtain(req, source)
-
- # Note that dists are sorted from best to worst, as promised by
- # env.__getitem__
-
- for dist in dists:
- if (dist.precedence == pkg_resources.DEVELOP_DIST and
- dist.location not in self._site_packages):
- # System eggs are sometimes installed as develop eggs.
- # Those are not the kind of develop eggs we are looking for
- # here: we want ones that the buildout itself has locally as
- # develop eggs.
- logger.debug('We have a develop egg: %s', dist)
- return dist, None
-
- # Special common case, we have a specification for a single version:
- specs = req.specs
- if len(specs) == 1 and specs[0][0] == '==':
- logger.debug('We have the distribution that satisfies %r.',
- str(req))
- return dists[0], None
-
- if self._prefer_final:
- fdists = [dist for dist in dists
- if _final_version(dist.parsed_version)
- ]
- if fdists:
- # There are final dists, so only use those
- dists = fdists
-
- if not self._newest:
- # We don't need the newest, so we'll use the newest one we
- # find, which is the first returned by
- # Environment.__getitem__.
- return dists[0], None
-
- best_we_have = dists[0] # Because dists are sorted from best to worst
-
- # We have some installed distros. There might, theoretically, be
- # newer ones. Let's find out which ones are available and see if
- # any are newer. We only do this if we're willing to install
- # something, which is only true if dest is not None:
-
- if self._dest is not None:
- best_available = self._obtain(req, source)
- else:
- best_available = None
-
- if best_available is None:
- # That's a bit odd. There aren't any distros available.
- # We should use the best one we have that meets the requirement.
- logger.debug(
- 'There are no distros available that meet %r.\n'
- 'Using our best, %s.',
- str(req), best_available)
- return best_we_have, None
-
- if self._prefer_final:
- if _final_version(best_available.parsed_version):
- if _final_version(best_we_have.parsed_version):
- if (best_we_have.parsed_version
- <
- best_available.parsed_version
- ):
- return None, best_available
- else:
- return None, best_available
- else:
- if (not _final_version(best_we_have.parsed_version)
- and
- (best_we_have.parsed_version
- <
- best_available.parsed_version
- )
- ):
- return None, best_available
- else:
- if (best_we_have.parsed_version
- <
- best_available.parsed_version
- ):
- return None, best_available
-
- logger.debug(
- 'We have the best distribution that satisfies %r.',
- str(req))
- return best_we_have, None
-
- def _load_dist(self, dist):
- dists = pkg_resources.Environment(
- dist.location,
- python=_get_version(self._executable),
- )[dist.project_name]
- assert len(dists) == 1
- return dists[0]
-
- def _call_easy_install(self, spec, ws, dest, dist):
-
- tmp = tempfile.mkdtemp(dir=dest)
- try:
- path = setuptools_loc
-
- args = ('-c', self._easy_install_cmd, '-mUNxd', _safe_arg(tmp))
- if not self._has_broken_dash_S:
- args = ('-S',) + args
- if self._always_unzip:
- args += ('-Z', )
- level = logger.getEffectiveLevel()
- if level > 0:
- args += ('-q', )
- elif level < 0:
- args += ('-v', )
-
- args += (_safe_arg(spec), )
-
- if level <= logging.DEBUG:
- logger.debug('Running easy_install:\n%s "%s"\npath=%s\n',
- self._executable, '" "'.join(args), path)
-
- if is_jython:
- extra_env = dict(os.environ, PYTHONPATH=path)
- else:
- args += (dict(os.environ, PYTHONPATH=path), )
-
- sys.stdout.flush() # We want any pending output first
-
- if is_jython:
- exit_code = subprocess.Popen(
- [_safe_arg(self._executable)] + list(args),
- env=extra_env).wait()
- else:
- exit_code = os.spawnle(
- os.P_WAIT, self._executable, _safe_arg (self._executable),
- *args)
-
- dists = []
- env = pkg_resources.Environment(
- [tmp],
- python=_get_version(self._executable),
- )
- for project in env:
- dists.extend(env[project])
-
- if exit_code:
- logger.error(
- "An error occurred when trying to install %s. "
- "Look above this message for any errors that "
- "were output by easy_install.",
- dist)
-
- if not dists:
- raise zc.buildout.UserError("Couldn't install: %s" % dist)
-
- if len(dists) > 1:
- logger.warn("Installing %s\n"
- "caused multiple distributions to be installed:\n"
- "%s\n",
- dist, '\n'.join(map(str, dists)))
- else:
- d = dists[0]
- if d.project_name != dist.project_name:
- logger.warn("Installing %s\n"
- "Caused installation of a distribution:\n"
- "%s\n"
- "with a different project name.",
- dist, d)
- if d.version != dist.version:
- logger.warn("Installing %s\n"
- "Caused installation of a distribution:\n"
- "%s\n"
- "with a different version.",
- dist, d)
-
- result = []
- for d in dists:
- newloc = os.path.join(dest, os.path.basename(d.location))
- if os.path.exists(newloc):
- if os.path.isdir(newloc):
- shutil.rmtree(newloc)
- else:
- os.remove(newloc)
- os.rename(d.location, newloc)
-
- [d] = pkg_resources.Environment(
- [newloc],
- python=_get_version(self._executable),
- )[d.project_name]
-
- result.append(d)
-
- return result
-
- finally:
- shutil.rmtree(tmp)
-
- def _obtain(self, requirement, source=None):
- # initialize out index for this project:
- index = self._index
-
- if index.obtain(requirement) is None:
- # Nothing is available.
- return None
-
- # Filter the available dists for the requirement and source flag. If
- # we are not supposed to include site-packages for the given egg, we
- # also filter those out. Even if include_site_packages is False and so
- # we have excluded site packages from the _env's paths (see
- # Installer.__init__), we need to do the filtering here because an
- # .egg-link, such as one for setuptools or zc.buildout installed by
- # zc.buildout.buildout.Buildout.bootstrap, can indirectly include a
- # path in our _site_packages.
- dists = [dist for dist in index[requirement.project_name] if (
- dist in requirement and (
- dist.location not in self._site_packages or
- self.allow_site_package_egg(dist.project_name))
- and (
- (not source) or
- (dist.precedence == pkg_resources.SOURCE_DIST))
- )
- ]
-
- # If we prefer final dists, filter for final and use the
- # result if it is non empty.
- if self._prefer_final:
- fdists = [dist for dist in dists
- if _final_version(dist.parsed_version)
- ]
- if fdists:
- # There are final dists, so only use those
- dists = fdists
-
- # Now find the best one:
- best = []
- bestv = ()
- for dist in dists:
- distv = dist.parsed_version
- if distv > bestv:
- best = [dist]
- bestv = distv
- elif distv == bestv:
- best.append(dist)
-
- if not best:
- return None
-
- if len(best) == 1:
- return best[0]
-
- if self._download_cache:
- for dist in best:
- if (realpath(os.path.dirname(dist.location))
- ==
- self._download_cache
- ):
- return dist
-
- best.sort()
- return best[-1]
-
- def _fetch(self, dist, tmp, download_cache):
- if (download_cache
- and (realpath(os.path.dirname(dist.location)) == download_cache)
- ):
- return dist
-
- new_location = self._index.download(dist.location, tmp)
- if (download_cache
- and (realpath(new_location) == realpath(dist.location))
- and os.path.isfile(new_location)
- ):
- # setuptools avoids making extra copies, but we want to copy
- # to the download cache
- shutil.copy2(new_location, tmp)
- new_location = os.path.join(tmp, os.path.basename(new_location))
-
- return dist.clone(location=new_location)
-
- def _get_dist(self, requirement, ws, always_unzip):
-
- __doing__ = 'Getting distribution for %r.', str(requirement)
-
- # Maybe an existing dist is already the best dist that satisfies the
- # requirement
- dist, avail = self._satisfied(requirement)
-
- if dist is None:
- if self._dest is not None:
- logger.info(*__doing__)
-
- # Retrieve the dist:
- if avail is None:
- raise MissingDistribution(requirement, ws)
-
- # We may overwrite distributions, so clear importer
- # cache.
- sys.path_importer_cache.clear()
-
- tmp = self._download_cache
- if tmp is None:
- tmp = tempfile.mkdtemp('get_dist')
-
- try:
- dist = self._fetch(avail, tmp, self._download_cache)
-
- if dist is None:
- raise zc.buildout.UserError(
- "Couldn't download distribution %s." % avail)
-
- if dist.precedence == pkg_resources.EGG_DIST:
- # It's already an egg, just fetch it into the dest
-
- newloc = os.path.join(
- self._dest, os.path.basename(dist.location))
-
- if os.path.isdir(dist.location):
- # we got a directory. It must have been
- # obtained locally. Just copy it.
- shutil.copytree(dist.location, newloc)
- else:
-
- if self._always_unzip:
- should_unzip = True
- else:
- metadata = pkg_resources.EggMetadata(
- zipimport.zipimporter(dist.location)
- )
- should_unzip = (
- metadata.has_metadata('not-zip-safe')
- or
- not metadata.has_metadata('zip-safe')
- )
-
- if should_unzip:
- setuptools.archive_util.unpack_archive(
- dist.location, newloc)
- else:
- shutil.copyfile(dist.location, newloc)
-
- redo_pyc(newloc)
-
- # Getting the dist from the environment causes the
- # distribution meta data to be read. Cloning isn't
- # good enough.
- dists = pkg_resources.Environment(
- [newloc],
- python=_get_version(self._executable),
- )[dist.project_name]
- else:
- # It's some other kind of dist. We'll let easy_install
- # deal with it:
- dists = self._call_easy_install(
- dist.location, ws, self._dest, dist)
- for dist in dists:
- redo_pyc(dist.location)
-
- finally:
- if tmp != self._download_cache:
- shutil.rmtree(tmp)
-
- self._env.scan([self._dest])
- dist = self._env.best_match(requirement, ws)
- logger.info("Got %s.", dist)
-
- else:
- dists = [dist]
-
- for dist in dists:
- if (dist.has_metadata('dependency_links.txt')
- and not self._install_from_cache
- and self._use_dependency_links
- ):
- for link in dist.get_metadata_lines('dependency_links.txt'):
- link = link.strip()
- if link not in self._links:
- logger.debug('Adding find link %r from %s', link, dist)
- self._links.append(link)
- self._index = _get_index(self._executable,
- self._index_url, self._links,
- self._allow_hosts, self._path)
-
- for dist in dists:
- # Check whether we picked a version and, if we did, report it:
- if not (
- dist.precedence == pkg_resources.DEVELOP_DIST
- or
- (len(requirement.specs) == 1
- and
- requirement.specs[0][0] == '==')
- ):
- logger.debug('Picked: %s = %s',
- dist.project_name, dist.version)
- if not self._allow_picked_versions:
- raise zc.buildout.UserError(
- 'Picked: %s = %s' % (dist.project_name, dist.version)
- )
-
- return dists
-
- def _maybe_add_setuptools(self, ws, dist):
- if dist.has_metadata('namespace_packages.txt'):
- for r in dist.requires():
- if r.project_name in ('setuptools', 'distribute'):
- break
- else:
- # We have a namespace package but no requirement for setuptools
- if dist.precedence == pkg_resources.DEVELOP_DIST:
- logger.warn(
- "Develop distribution: %s\n"
- "uses namespace packages but the distribution "
- "does not require setuptools.",
- dist)
- requirement = self._constrain(
- pkg_resources.Requirement.parse('setuptools')
- )
- if ws.find(requirement) is None:
- for dist in self._get_dist(requirement, ws, False):
- ws.add(dist)
-
-
- def _constrain(self, requirement):
- if is_distribute and requirement.key == 'setuptools':
- requirement = pkg_resources.Requirement.parse('distribute')
- version = self._versions.get(requirement.project_name)
- if version:
- if version not in requirement:
- logger.error("The version, %s, is not consistent with the "
- "requirement, %r.", version, str(requirement))
- raise IncompatibleVersionError("Bad version", version)
-
- requirement = pkg_resources.Requirement.parse(
- "%s[%s] ==%s" % (requirement.project_name,
- ','.join(requirement.extras),
- version))
-
- return requirement
-
- def install(self, specs, working_set=None):
-
- logger.debug('Installing %s.', repr(specs)[1:-1])
-
- path = self._path
- destination = self._dest
- if destination is not None and destination not in path:
- path.insert(0, destination)
-
- requirements = [self._constrain(pkg_resources.Requirement.parse(spec))
- for spec in specs]
-
-
-
- if working_set is None:
- ws = pkg_resources.WorkingSet([])
- else:
- ws = working_set
-
- for requirement in requirements:
- for dist in self._get_dist(requirement, ws, self._always_unzip):
- ws.add(dist)
- self._maybe_add_setuptools(ws, dist)
-
- # OK, we have the requested distributions and they're in the working
- # set, but they may have unmet requirements. We'll resolve these
- # requirements. This is code modified from
- # pkg_resources.WorkingSet.resolve. We can't reuse that code directly
- # because we have to constrain our requirements (see
- # versions_section_ignored_for_dependency_in_favor_of_site_packages in
- # zc.buildout.tests).
- requirements.reverse() # Set up the stack.
- processed = {} # This is a set of processed requirements.
- best = {} # This is a mapping of key -> dist.
- # Note that we don't use the existing environment, because we want
- # to look for new eggs unless what we have is the best that
- # matches the requirement.
- env = pkg_resources.Environment(ws.entries)
- while requirements:
- # Process dependencies breadth-first.
- req = self._constrain(requirements.pop(0))
- if req in processed:
- # Ignore cyclic or redundant dependencies.
- continue
- dist = best.get(req.key)
- if dist is None:
- # Find the best distribution and add it to the map.
- dist = ws.by_key.get(req.key)
- if dist is None:
- try:
- dist = best[req.key] = env.best_match(req, ws)
- except pkg_resources.VersionConflict, err:
- raise VersionConflict(err, ws)
- if dist is None or (
- dist.location in self._site_packages and not
- self.allow_site_package_egg(dist.project_name)):
- # If we didn't find a distribution in the
- # environment, or what we found is from site
- # packages and not allowed to be there, try
- # again.
- if destination:
- logger.debug('Getting required %r', str(req))
- else:
- logger.debug('Adding required %r', str(req))
- _log_requirement(ws, req)
- for dist in self._get_dist(req,
- ws, self._always_unzip):
- ws.add(dist)
- self._maybe_add_setuptools(ws, dist)
- if dist not in req:
- # Oops, the "best" so far conflicts with a dependency.
- raise VersionConflict(
- pkg_resources.VersionConflict(dist, req), ws)
- requirements.extend(dist.requires(req.extras)[::-1])
- processed[req] = True
- if dist.location in self._site_packages:
- logger.debug('Egg from site-packages: %s', dist)
- return ws
-
- def build(self, spec, build_ext):
-
- requirement = self._constrain(pkg_resources.Requirement.parse(spec))
-
- dist, avail = self._satisfied(requirement, 1)
- if dist is not None:
- return [dist.location]
-
- # Retrieve the dist:
- if avail is None:
- raise zc.buildout.UserError(
- "Couldn't find a source distribution for %r."
- % str(requirement))
-
- logger.debug('Building %r', spec)
-
- tmp = self._download_cache
- if tmp is None:
- tmp = tempfile.mkdtemp('get_dist')
-
- try:
- dist = self._fetch(avail, tmp, self._download_cache)
-
- build_tmp = tempfile.mkdtemp('build')
- try:
- setuptools.archive_util.unpack_archive(dist.location,
- build_tmp)
- if os.path.exists(os.path.join(build_tmp, 'setup.py')):
- base = build_tmp
- else:
- setups = glob.glob(
- os.path.join(build_tmp, '*', 'setup.py'))
- if not setups:
- raise distutils.errors.DistutilsError(
- "Couldn't find a setup script in %s"
- % os.path.basename(dist.location)
- )
- if len(setups) > 1:
- raise distutils.errors.DistutilsError(
- "Multiple setup scripts in %s"
- % os.path.basename(dist.location)
- )
- base = os.path.dirname(setups[0])
-
- setup_cfg = os.path.join(base, 'setup.cfg')
- if not os.path.exists(setup_cfg):
- f = open(setup_cfg, 'w')
- f.close()
- setuptools.command.setopt.edit_config(
- setup_cfg, dict(build_ext=build_ext))
-
- dists = self._call_easy_install(
- base, pkg_resources.WorkingSet(),
- self._dest, dist)
-
- for dist in dists:
- redo_pyc(dist.location)
-
- return [dist.location for dist in dists]
- finally:
- shutil.rmtree(build_tmp)
-
- finally:
- if tmp != self._download_cache:
- shutil.rmtree(tmp)
-
-def default_versions(versions=None):
- old = Installer._versions
- if versions is not None:
- Installer._versions = versions
- return old
-
-def download_cache(path=-1):
- old = Installer._download_cache
- if path != -1:
- if path:
- path = realpath(path)
- Installer._download_cache = path
- return old
-
-def install_from_cache(setting=None):
- old = Installer._install_from_cache
- if setting is not None:
- Installer._install_from_cache = bool(setting)
- return old
-
-def prefer_final(setting=None):
- old = Installer._prefer_final
- if setting is not None:
- Installer._prefer_final = bool(setting)
- return old
-
-def include_site_packages(setting=None):
- old = Installer._include_site_packages
- if setting is not None:
- Installer._include_site_packages = bool(setting)
- return old
-
-def allowed_eggs_from_site_packages(setting=None):
- old = Installer._allowed_eggs_from_site_packages
- if setting is not None:
- Installer._allowed_eggs_from_site_packages = tuple(setting)
- return old
-
-def use_dependency_links(setting=None):
- old = Installer._use_dependency_links
- if setting is not None:
- Installer._use_dependency_links = bool(setting)
- return old
-
-def allow_picked_versions(setting=None):
- old = Installer._allow_picked_versions
- if setting is not None:
- Installer._allow_picked_versions = bool(setting)
- return old
-
-def always_unzip(setting=None):
- old = Installer._always_unzip
- if setting is not None:
- Installer._always_unzip = bool(setting)
- return old
-
-def install(specs, dest,
- links=(), index=None,
- executable=sys.executable, always_unzip=None,
- path=None, working_set=None, newest=True, versions=None,
- use_dependency_links=None, allow_hosts=('*',),
- include_site_packages=None, allowed_eggs_from_site_packages=None,
- prefer_final=None):
- installer = Installer(
- dest, links, index, executable, always_unzip, path, newest,
- versions, use_dependency_links, allow_hosts=allow_hosts,
- include_site_packages=include_site_packages,
- allowed_eggs_from_site_packages=allowed_eggs_from_site_packages,
- prefer_final=prefer_final)
- return installer.install(specs, working_set)
-
-
-def build(spec, dest, build_ext,
- links=(), index=None,
- executable=sys.executable,
- path=None, newest=True, versions=None, allow_hosts=('*',),
- include_site_packages=None, allowed_eggs_from_site_packages=None):
- installer = Installer(
- dest, links, index, executable, True, path, newest, versions,
- allow_hosts=allow_hosts,
- include_site_packages=include_site_packages,
- allowed_eggs_from_site_packages=allowed_eggs_from_site_packages)
- return installer.build(spec, build_ext)
-
-
-
-def _rm(*paths):
- for path in paths:
- if os.path.isdir(path):
- shutil.rmtree(path)
- elif os.path.exists(path):
- os.remove(path)
-
-def _copyeggs(src, dest, suffix, undo):
- result = []
- undo.append(lambda : _rm(*result))
- for name in os.listdir(src):
- if name.endswith(suffix):
- new = os.path.join(dest, name)
- _rm(new)
- os.rename(os.path.join(src, name), new)
- result.append(new)
-
- assert len(result) == 1, str(result)
- undo.pop()
-
- return result[0]
-
-def develop(setup, dest,
- build_ext=None,
- executable=sys.executable):
-
- if os.path.isdir(setup):
- directory = setup
- setup = os.path.join(directory, 'setup.py')
- else:
- directory = os.path.dirname(setup)
-
- undo = []
- try:
- if build_ext:
- setup_cfg = os.path.join(directory, 'setup.cfg')
- if os.path.exists(setup_cfg):
- os.rename(setup_cfg, setup_cfg+'-develop-aside')
- def restore_old_setup():
- if os.path.exists(setup_cfg):
- os.remove(setup_cfg)
- os.rename(setup_cfg+'-develop-aside', setup_cfg)
- undo.append(restore_old_setup)
- else:
- open(setup_cfg, 'w')
- undo.append(lambda: os.remove(setup_cfg))
- setuptools.command.setopt.edit_config(
- setup_cfg, dict(build_ext=build_ext))
-
- fd, tsetup = tempfile.mkstemp()
- undo.append(lambda: os.remove(tsetup))
- undo.append(lambda: os.close(fd))
-
- os.write(fd, runsetup_template % dict(
- setuptools=setuptools_loc,
- setupdir=directory,
- setup=setup,
- __file__ = setup,
- ))
-
- tmp3 = tempfile.mkdtemp('build', dir=dest)
- undo.append(lambda : shutil.rmtree(tmp3))
-
- args = [
- zc.buildout.easy_install._safe_arg(tsetup),
- '-q', 'develop', '-mxN',
- '-d', _safe_arg(tmp3),
- ]
-
- log_level = logger.getEffectiveLevel()
- if log_level <= 0:
- if log_level == 0:
- del args[1]
- else:
- args[1] == '-v'
- if log_level < logging.DEBUG:
- logger.debug("in: %r\n%s", directory, ' '.join(args))
-
- if is_jython:
- assert subprocess.Popen([_safe_arg(executable)] + args).wait() == 0
- else:
- assert os.spawnl(os.P_WAIT, executable, _safe_arg(executable),
- *args) == 0
-
- return _copyeggs(tmp3, dest, '.egg-link', undo)
-
- finally:
- undo.reverse()
- [f() for f in undo]
-
-def working_set(specs, executable, path, include_site_packages=None,
- allowed_eggs_from_site_packages=None, prefer_final=None):
- return install(
- specs, None, executable=executable, path=path,
- include_site_packages=include_site_packages,
- allowed_eggs_from_site_packages=allowed_eggs_from_site_packages,
- prefer_final=prefer_final)
-
-############################################################################
-# Script generation functions
-
-def scripts(
- reqs, working_set, executable, dest,
- scripts=None,
- extra_paths=(),
- arguments='',
- interpreter=None,
- initialization='',
- relative_paths=False,
- ):
- """Generate scripts and/or an interpreter.
-
- See sitepackage_safe_scripts for a version that can be used with a Python
- that has code installed in site-packages. It has more options and a
- different approach.
- """
- path = _get_path(working_set, extra_paths)
- if initialization:
- initialization = '\n'+initialization+'\n'
- generated = _generate_scripts(
- reqs, working_set, dest, path, scripts, relative_paths,
- initialization, executable, arguments)
- if interpreter:
- sname = os.path.join(dest, interpreter)
- spath, rpsetup = _relative_path_and_setup(sname, path, relative_paths)
- generated.extend(
- _pyscript(spath, sname, executable, rpsetup))
- return generated
-
-# We need to give an alternate name to the ``scripts`` function so that it
-# can be referenced within sitepackage_safe_scripts, which uses ``scripts``
-# as an argument name.
-_original_scripts_function = scripts
-
-def sitepackage_safe_scripts(
- dest, working_set, executable, site_py_dest,
- reqs=(),
- scripts=None,
- interpreter=None,
- extra_paths=(),
- initialization='',
- include_site_packages=False,
- exec_sitecustomize=False,
- relative_paths=False,
- script_arguments='',
- script_initialization='',
- ):
- """Generate scripts and/or an interpreter from a system Python.
-
- This accomplishes the same job as the ``scripts`` function, above,
- but it does so in an alternative way that allows safely including
- Python site packages, if desired, and choosing to execute the Python's
- sitecustomize.
- """
- if _has_broken_dash_S(executable):
- if not include_site_packages:
- warnings.warn(BROKEN_DASH_S_WARNING)
- return _original_scripts_function(
- reqs, working_set, executable, dest, scripts, extra_paths,
- script_arguments, interpreter, initialization, relative_paths)
- generated = []
- generated.append(_generate_sitecustomize(
- site_py_dest, executable, initialization, exec_sitecustomize))
- generated.append(_generate_site(
- site_py_dest, working_set, executable, extra_paths,
- include_site_packages, relative_paths))
- script_initialization = _script_initialization_template % dict(
- site_py_dest=site_py_dest,
- script_initialization=script_initialization)
- if not script_initialization.endswith('\n'):
- script_initialization += '\n'
- generated.extend(_generate_scripts(
- reqs, working_set, dest, [site_py_dest], scripts, relative_paths,
- script_initialization, executable, script_arguments, block_site=True))
- if interpreter:
- generated.extend(_generate_interpreter(
- interpreter, dest, executable, site_py_dest, relative_paths))
- return generated
-
-_script_initialization_template = '''
-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
-%(script_initialization)s'''
-
-# Utilities for the script generation functions.
-
-# These are shared by both ``scripts`` and ``sitepackage_safe_scripts``
-
-def _get_path(working_set, extra_paths=()):
- """Given working set and extra paths, return a normalized path list."""
- path = [dist.location for dist in working_set]
- path.extend(extra_paths)
- return map(realpath, path)
-
-def _generate_scripts(reqs, working_set, dest, path, scripts, relative_paths,
- initialization, executable, arguments,
- block_site=False):
- """Generate scripts for the given requirements.
-
- - reqs is an iterable of string requirements or entry points.
- - The requirements must be findable in the given working_set.
- - The dest is the directory in which the scripts should be created.
- - The path is a list of paths that should be added to sys.path.
- - The scripts is an optional dictionary. If included, the keys should be
- the names of the scripts that should be created, as identified in their
- entry points; and the values should be the name the script should
- actually be created with.
- - relative_paths, if given, should be the path that is the root of the
- buildout (the common path that should be the root of what is relative).
- """
- if isinstance(reqs, str):
- raise TypeError('Expected iterable of requirements or entry points,'
- ' got string.')
- generated = []
- entry_points = []
- for req in reqs:
- if isinstance(req, str):
- req = pkg_resources.Requirement.parse(req)
- dist = working_set.find(req)
- for name in pkg_resources.get_entry_map(dist, 'console_scripts'):
- entry_point = dist.get_entry_info('console_scripts', name)
- entry_points.append(
- (name, entry_point.module_name,
- '.'.join(entry_point.attrs))
- )
- else:
- entry_points.append(req)
- for name, module_name, attrs in entry_points:
- if scripts is not None:
- sname = scripts.get(name)
- if sname is None:
- continue
- else:
- sname = name
- sname = os.path.join(dest, sname)
- spath, rpsetup = _relative_path_and_setup(sname, path, relative_paths)
- generated.extend(
- _script(sname, executable, rpsetup, spath, initialization,
- module_name, attrs, arguments, block_site=block_site))
- return generated
-
-def _relative_path_and_setup(sname, path,
- relative_paths=False, indent_level=1,
- omit_os_import=False):
- """Return a string of code of paths and of setup if appropriate.
-
- - sname is the full path to the script name to be created.
- - path is the list of paths to be added to sys.path.
- - relative_paths, if given, should be the path that is the root of the
- buildout (the common path that should be the root of what is relative).
- - indent_level is the number of four-space indents that the path should
- insert before each element of the path.
- """
- if relative_paths:
- relative_paths = os.path.normcase(relative_paths)
- sname = os.path.normcase(os.path.abspath(sname))
- spath = _format_paths(
- [_relativitize(os.path.normcase(path_item), sname, relative_paths)
- for path_item in path], indent_level=indent_level)
- rpsetup = relative_paths_setup
- if not omit_os_import:
- rpsetup = '\n\nimport os\n' + rpsetup
- for i in range(_relative_depth(relative_paths, sname)):
- rpsetup += "\nbase = os.path.dirname(base)"
- else:
- spath = _format_paths((repr(p) for p in path),
- indent_level=indent_level)
- rpsetup = ''
- return spath, rpsetup
-
-def _relative_depth(common, path):
- """Return number of dirs separating ``path`` from ancestor, ``common``.
-
- For instance, if path is /foo/bar/baz/bing, and common is /foo, this will
- return 2--in UNIX, the number of ".." to get from bing's directory
- to foo.
-
- This is a helper for _relative_path_and_setup.
- """
- n = 0
- while 1:
- dirname = os.path.dirname(path)
- if dirname == path:
- raise AssertionError("dirname of %s is the same" % dirname)
- if dirname == common:
- break
- n += 1
- path = dirname
- return n
-
-def _relative_path(common, path):
- """Return the relative path from ``common`` to ``path``.
-
- This is a helper for _relativitize, which is a helper to
- _relative_path_and_setup.
- """
- r = []
- while 1:
- dirname, basename = os.path.split(path)
- r.append(basename)
- if dirname == common:
- break
- if dirname == path:
- raise AssertionError("dirname of %s is the same" % dirname)
- path = dirname
- r.reverse()
- return os.path.join(*r)
-
-def _relativitize(path, script, relative_paths):
- """Return a code string for the given path.
-
- Path is relative to the base path ``relative_paths``if the common prefix
- between ``path`` and ``script`` starts with ``relative_paths``.
- """
- if path == script:
- raise AssertionError("path == script")
- common = os.path.dirname(os.path.commonprefix([path, script]))
- if (common == relative_paths or
- common.startswith(os.path.join(relative_paths, ''))
- ):
- return "join(base, %r)" % _relative_path(common, path)
- else:
- return repr(path)
-
-relative_paths_setup = """
-join = os.path.join
-base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))"""
-
-def _write_script(full_name, contents, logged_type):
- """Write contents of script in full_name, logging the action.
-
- The only tricky bit in this function is that it supports Windows by
- creating exe files using a pkg_resources helper.
- """
- generated = []
- script_name = full_name
- if is_win32:
- script_name += '-script.py'
- # Generate exe file and give the script a magic name.
- exe = full_name + '.exe'
- new_data = pkg_resources.resource_string('setuptools', 'cli.exe')
- if not os.path.exists(exe) or (open(exe, 'rb').read() != new_data):
- # Only write it if it's different.
- open(exe, 'wb').write(new_data)
- generated.append(exe)
- changed = not (os.path.exists(script_name) and
- open(script_name).read() == contents)
- if changed:
- open(script_name, 'w').write(contents)
- try:
- os.chmod(script_name, 0755)
- except (AttributeError, os.error):
- pass
- logger.info("Generated %s %r.", logged_type, full_name)
- generated.append(script_name)
- return generated
-
-def _format_paths(paths, indent_level=1):
- """Format paths for inclusion in a script."""
- separator = ',\n' + indent_level * ' '
- return separator.join(paths)
-
-def _script(dest, executable, relative_paths_setup, path, initialization,
- module_name, attrs, arguments, block_site=False):
- if block_site:
- dash_S = ' -S'
- else:
- dash_S = ''
- contents = script_template % dict(
- python=_safe_arg(executable),
- dash_S=dash_S,
- path=path,
- module_name=module_name,
- attrs=attrs,
- arguments=arguments,
- initialization=initialization,
- relative_paths_setup=relative_paths_setup,
- )
- return _write_script(dest, contents, 'script')
-
-if is_jython and jython_os_name == 'linux':
- script_header = '#!/usr/bin/env %(python)s%(dash_S)s'
-else:
- script_header = '#!%(python)s%(dash_S)s'
-
-sys_path_template = '''\
-import sys
-sys.path[0:0] = [
- %s,
- ]
-'''
-
-script_template = script_header + '''\
-%(relative_paths_setup)s
-
-import sys
-sys.path[0:0] = [
- %(path)s,
- ]
-
-%(initialization)s
-import %(module_name)s
-
-if __name__ == '__main__':
- %(module_name)s.%(attrs)s(%(arguments)s)
-'''
-
-# These are used only by the older ``scripts`` function.
-
-def _pyscript(path, dest, executable, rsetup):
- contents = py_script_template % dict(
- python=_safe_arg(executable),
- dash_S='',
- path=path,
- relative_paths_setup=rsetup,
- )
- return _write_script(dest, contents, 'interpreter')
-
-py_script_template = script_header + '''\
-%(relative_paths_setup)s
-
-import sys
-
-sys.path[0:0] = [
- %(path)s,
- ]
-
-_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)
-
- if _args:
- sys.argv[:] = _args
- __file__ = _args[0]
- del _options, _args
- execfile(__file__)
-
-if _interactive:
- del _interactive
- __import__("code").interact(banner="", local=globals())
-'''
-
-# These are used only by the newer ``sitepackage_safe_scripts`` function.
-
-def _get_module_file(executable, name, silent=False):
- """Return a module's file path.
-
- - executable is a path to the desired Python executable.
- - name is the name of the (pure, not C) Python module.
- """
- cmd = [executable, "-Sc",
- "import imp; "
- "fp, path, desc = imp.find_module(%r); "
- "fp.close(); "
- "print path" % (name,)]
- env = os.environ.copy()
- # We need to make sure that PYTHONPATH, which will often be set to
- # include a custom buildout-generated site.py, is not set, or else
- # we will not get an accurate value for the "real" site.py and
- # sitecustomize.py.
- env.pop('PYTHONPATH', None)
- _proc = subprocess.Popen(
- cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
- stdout, stderr = _proc.communicate();
- if _proc.returncode:
- if not silent:
- logger.info(
- 'Could not find file for module %s:\n%s', name, stderr)
- return None
- # else: ...
- res = stdout.strip()
- if res.endswith('.pyc') or res.endswith('.pyo'):
- raise RuntimeError('Cannot find uncompiled version of %s' % (name,))
- if not os.path.exists(res):
- raise RuntimeError(
- 'File does not exist for module %s:\n%s' % (name, res))
- return res
-
-def _generate_sitecustomize(dest, executable, initialization='',
- exec_sitecustomize=False):
- """Write a sitecustomize file with optional custom initialization.
-
- The created script will execute the underlying Python's
- sitecustomize if exec_sitecustomize is True.
- """
- sitecustomize_path = os.path.join(dest, 'sitecustomize.py')
- sitecustomize = open(sitecustomize_path, 'w')
- if initialization:
- sitecustomize.write(initialization + '\n')
- if exec_sitecustomize:
- real_sitecustomize_path = _get_module_file(
- executable, 'sitecustomize', silent=True)
- if real_sitecustomize_path:
- real_sitecustomize = open(real_sitecustomize_path, 'r')
- sitecustomize.write(
- '\n# The following is from\n# %s\n' %
- (real_sitecustomize_path,))
- sitecustomize.write(real_sitecustomize.read())
- real_sitecustomize.close()
- sitecustomize.close()
- return sitecustomize_path
-
-def _generate_site(dest, working_set, executable, extra_paths=(),
- include_site_packages=False, relative_paths=False):
- """Write a site.py file with eggs from working_set.
-
- extra_paths will be added to the path. If include_site_packages is True,
- paths from the underlying Python will be added.
- """
- path = _get_path(working_set, extra_paths)
- site_path = os.path.join(dest, 'site.py')
- original_path_setup = preamble = ''
- if include_site_packages:
- stdlib, site_paths = _get_system_paths(executable)
- # We want to make sure that paths from site-packages, such as those
- # allowed by allowed_eggs_from_site_packages, always come last, or
- # else site-packages paths may include packages that mask the eggs we
- # really want.
- path = [p for p in path if p not in site_paths]
- # Now we set up the code we need.
- original_path_setup = original_path_snippet % (
- _format_paths((repr(p) for p in site_paths), 2),)
- distribution = working_set.find(
- pkg_resources.Requirement.parse('setuptools'))
- if distribution is not None:
- # We need to worry about namespace packages.
- if relative_paths:
- location = _relativitize(
- distribution.location,
- os.path.normcase(os.path.abspath(site_path)),
- relative_paths)
- else:
- location = repr(distribution.location)
- preamble = namespace_include_site_packages_setup % (location,)
- original_path_setup = (
- addsitedir_namespace_originalpackages_snippet +
- original_path_setup)
- else:
- preamble = '\n setuptools_path = None'
- egg_path_string, relative_preamble = _relative_path_and_setup(
- site_path, path, relative_paths, indent_level=2, omit_os_import=True)
- if relative_preamble:
- relative_preamble = '\n'.join(
- [(line and ' %s' % (line,) or line)
- for line in relative_preamble.split('\n')])
- preamble = relative_preamble + preamble
- addsitepackages_marker = 'def addsitepackages('
- enableusersite_marker = 'ENABLE_USER_SITE = '
- successful_rewrite = False
- real_site_path = _get_module_file(executable, 'site')
- real_site = open(real_site_path, 'r')
- site = open(site_path, 'w')
- try:
- for line in real_site.readlines():
- if line.startswith(enableusersite_marker):
- site.write(enableusersite_marker)
- site.write('False # buildout does not support user sites.\n')
- elif line.startswith(addsitepackages_marker):
- site.write(addsitepackages_script % (
- preamble, egg_path_string, original_path_setup))
- site.write(line[len(addsitepackages_marker):])
- successful_rewrite = True
- else:
- site.write(line)
- finally:
- site.close()
- real_site.close()
- if not successful_rewrite:
- raise RuntimeError(
- 'Buildout did not successfully rewrite %s to %s' %
- (real_site_path, site_path))
- return site_path
-
-namespace_include_site_packages_setup = '''
- setuptools_path = %s
- sys.path.append(setuptools_path)
- known_paths.add(os.path.normcase(setuptools_path))
- import pkg_resources'''
-
-addsitedir_namespace_originalpackages_snippet = '''
- pkg_resources.working_set.add_entry(sitedir)'''
-
-original_path_snippet = '''
- sys.__egginsert = len(buildout_paths) # Support distribute.
- original_paths = [
- %s
- ]
- for path in original_paths:
- if path == setuptools_path or path not in known_paths:
- addsitedir(path, known_paths)'''
-
-addsitepackages_script = '''\
-def addsitepackages(known_paths):
- """Add site packages, as determined by zc.buildout.
-
- See original_addsitepackages, below, for the original version."""%s
- buildout_paths = [
- %s
- ]
- 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)%s
- return known_paths
-
-def original_addsitepackages('''
-
-def _generate_interpreter(name, dest, executable, site_py_dest,
- relative_paths=False):
- """Write an interpreter script, using the site.py approach."""
- full_name = os.path.join(dest, name)
- site_py_dest_string, rpsetup = _relative_path_and_setup(
- full_name, [site_py_dest], relative_paths, omit_os_import=True)
- if rpsetup:
- rpsetup += "\n"
- if sys.platform == 'win32':
- windows_import = '\nimport subprocess'
- # os.exec* is a mess on Windows, particularly if the path
- # to the executable has spaces and the Python is using MSVCRT.
- # The standard fix is to surround the executable's path with quotes,
- # but that has been unreliable in testing.
- #
- # Here's a demonstration of the problem. Given a Python
- # compiled with a MSVCRT-based compiler, such as the free Visual
- # C++ 2008 Express Edition, and an executable path with spaces
- # in it such as the below, we see the following.
- #
- # >>> import os
- # >>> p0 = 'C:\\Documents and Settings\\Administrator\\My Documents\\Downloads\\Python-2.6.4\\PCbuild\\python.exe'
- # >>> os.path.exists(p0)
- # True
- # >>> os.execv(p0, [])
- # Traceback (most recent call last):
- # File "<stdin>", line 1, in <module>
- # OSError: [Errno 22] Invalid argument
- #
- # That seems like a standard problem. The standard solution is
- # to quote the path (see, for instance
- # http://bugs.python.org/issue436259). However, this solution,
- # and other variations, fail:
- #
- # >>> p1 = '"C:\\Documents and Settings\\Administrator\\My Documents\\Downloads\\Python-2.6.4\\PCbuild\\python.exe"'
- # >>> os.execv(p1, [])
- # Traceback (most recent call last):
- # File "<stdin>", line 1, in <module>
- # OSError: [Errno 22] Invalid argument
- #
- # We simply use subprocess instead, since it handles everything
- # nicely, and the transparency of exec* (that is, not running,
- # perhaps unexpectedly, in a subprocess) is arguably not a
- # necessity, at least for many use cases.
- execute = 'subprocess.call(argv, env=environ)'
- else:
- windows_import = ''
- execute = 'os.execve(sys.executable, argv, environ)'
- contents = interpreter_template % dict(
- python=_safe_arg(executable),
- dash_S=' -S',
- site_dest=site_py_dest_string,
- relative_paths_setup=rpsetup,
- windows_import=windows_import,
- execute=execute,
- )
- return _write_script(full_name, contents, 'interpreter')
-
-interpreter_template = script_header + '''
-import os
-import sys%(windows_import)s
-%(relative_paths_setup)s
-argv = [sys.executable] + sys.argv[1:]
-environ = os.environ.copy()
-path = %(site_dest)s
-if environ.get('PYTHONPATH'):
- path = os.pathsep.join([path, environ['PYTHONPATH']])
-environ['PYTHONPATH'] = path
-%(execute)s
-'''
-
-# End of script generation code.
-############################################################################
-
-runsetup_template = """
-import sys
-sys.path.insert(0, %(setupdir)r)
-sys.path.insert(0, %(setuptools)r)
-import os, setuptools
-
-__file__ = %(__file__)r
-
-os.chdir(%(setupdir)r)
-sys.argv[0] = %(setup)r
-execfile(%(setup)r)
-"""
-
-
-class VersionConflict(zc.buildout.UserError):
-
- def __init__(self, err, ws):
- ws = list(ws)
- ws.sort()
- self.err, self.ws = err, ws
-
- def __str__(self):
- existing_dist, req = self.err
- result = ["There is a version conflict.",
- "We already have: %s" % existing_dist,
- ]
- for dist in self.ws:
- if req in dist.requires():
- result.append("but %s requires %r." % (dist, str(req)))
- return '\n'.join(result)
-
-
-class MissingDistribution(zc.buildout.UserError):
-
- def __init__(self, req, ws):
- ws = list(ws)
- ws.sort()
- self.data = req, ws
-
- def __str__(self):
- req, ws = self.data
- return "Couldn't find a distribution for %r." % str(req)
-
-def _log_requirement(ws, req):
- ws = list(ws)
- ws.sort()
- for dist in ws:
- if req in dist.requires():
- logger.debug(" required by %s." % dist)
-
-def _fix_file_links(links):
- for link in links:
- if link.startswith('file://') and link[-1] != '/':
- if os.path.isdir(link[7:]):
- # work around excessive restriction in setuptools:
- link += '/'
- yield link
-
-_final_parts = '*final-', '*final'
-def _final_version(parsed_version):
- for part in parsed_version:
- if (part[:1] == '*') and (part not in _final_parts):
- return False
- return True
-
-def redo_pyc(egg):
- if not os.path.isdir(egg):
- return
- for dirpath, dirnames, filenames in os.walk(egg):
- for filename in filenames:
- if not filename.endswith('.py'):
- continue
- filepath = os.path.join(dirpath, filename)
- if not (os.path.exists(filepath+'c')
- or os.path.exists(filepath+'o')):
- # If it wasn't compiled, it may not be compilable
- continue
-
- # OK, it looks like we should try to compile.
-
- # Remove old files.
- for suffix in 'co':
- if os.path.exists(filepath+suffix):
- os.remove(filepath+suffix)
-
- # Compile under current optimization
- try:
- py_compile.compile(filepath)
- except py_compile.PyCompileError:
- logger.warning("Couldn't compile %s", filepath)
- else:
- # Recompile under other optimization. :)
- args = [_safe_arg(sys.executable)]
- if __debug__:
- args.append('-O')
- args.extend(['-m', 'py_compile', _safe_arg(filepath)])
-
- if is_jython:
- subprocess.call([sys.executable, args])
- else:
- os.spawnv(os.P_WAIT, sys.executable, args)
-