[Checkins] SVN: zc.buildout/branches/gary-support-system-python/src/zc/buildout/ fix and test for edge case in include-site-packages code
Gary Poster
gary.poster at canonical.com
Thu Jul 9 10:43:18 EDT 2009
Log message for revision 101765:
fix and test for edge case in include-site-packages code
Changed:
U zc.buildout/branches/gary-support-system-python/src/zc/buildout/easy_install.py
U zc.buildout/branches/gary-support-system-python/src/zc/buildout/tests.py
-=-
Modified: zc.buildout/branches/gary-support-system-python/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/branches/gary-support-system-python/src/zc/buildout/easy_install.py 2009-07-09 14:43:15 UTC (rev 101764)
+++ zc.buildout/branches/gary-support-system-python/src/zc/buildout/easy_install.py 2009-07-09 14:43:18 UTC (rev 101765)
@@ -235,10 +235,10 @@
path = (path and path[:] or [])
if include_site_packages is not None:
self._include_site_packages = include_site_packages
- stdlib, site_packages = _get_system_packages(executable)
+ stdlib, self._site_packages = _get_system_packages(executable)
if self._include_site_packages:
path.extend(buildout_and_setuptools_path)
- path.extend(site_packages)
+ path.extend(self._site_packages)
# else we could try to still include the buildout_and_setuptools_path
# if the elements are not in site_packages, but we're not bothering
# with this optimization for now, in the name of code simplicity.
@@ -257,7 +257,19 @@
self._versions = versions
def _satisfied(self, req, source=None):
- dists = [dist for dist in self._env[req.project_name] if dist in req]
+ # We get all distributions that match the given requirement. If we
+ # are not supposed to include site-packages, we also filter those out.
+ # We need to do the filtering here even though we have exluded
+ # site packages from the _env's paths (see Installer.__init__) 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 (
+ self._include_site_packages or
+ dist.location not in self._site_packages)
+ )
+ ]
if not dists:
logger.debug('We have no distributions for %s that satisfies %r.',
req.project_name, str(req))
@@ -461,10 +473,19 @@
# Nothing is available.
return None
- # Filter the available dists for the requirement and source flag
+ # Filter the available dists for the requirement and source flag. If we
+ # are not supposed to include site-packages, we also filter those out.
+ # We need to do the filtering here even though we have exluded site
+ # packages from the _index's paths (see Installer.__init__) 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
+ (self._include_site_packages or
+ dist.location not in self._site_packages)
+ and
((not source) or
(dist.precedence == pkg_resources.SOURCE_DIST)
)
Modified: zc.buildout/branches/gary-support-system-python/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/branches/gary-support-system-python/src/zc/buildout/tests.py 2009-07-09 14:43:15 UTC (rev 101764)
+++ zc.buildout/branches/gary-support-system-python/src/zc/buildout/tests.py 2009-07-09 14:43:18 UTC (rev 101765)
@@ -2376,6 +2376,53 @@
That's a failure, as expected.
+Now we explore an important edge case.
+
+Some system Pythons include setuptools (and other Python packages) in their
+site-packages (or equivalent) using a .egg-info directory. The pkg_resources
+module (from setuptools) considers a package installed using .egg-info to be a
+develop egg.
+
+zc.buildout.buildout.Buildout.bootstrap will make setuptools and zc.buildout
+available to the buildout via the eggs directory, for normal eggs; or the
+develop-eggs directory, for develop-eggs.
+
+If setuptools or zc.buildout is found in site-packages and considered by
+pkg_resources to be a develop egg, then the bootstrap code will use a .egg-link
+in the local develop-eggs, pointing to site-packages, in its entirety. Because
+develop-eggs must always be available for searching for distributions, this
+indirectly brings site-packages back into the search path for distributions.
+
+Because of this, we have to take special care that we still exclude
+site-packages even in this case. See the comments about site packages in the
+Installer._satisfied and Installer._obtain methods for the implementation
+(as of this writing).
+
+In this demonstration, we insert a link to the "other" distribution in our
+develop-eggs, which would bring the package back in, except for the special
+care we have taken to exclude it.
+
+ >>> zc.buildout.easy_install.clear_index_cache()
+ >>> rmdir(example_dest)
+ >>> example_dest = tmpdir('site-packages-example-install')
+ >>> mkdir(example_dest, 'develop-eggs')
+ >>> stdlib, site_packages = (
+ ... zc.buildout.easy_install._get_system_packages(primed_executable))
+ >>> path_to_other = [p for p in site_packages if 'other' in p][0]
+ >>> write(example_dest, 'develop-eggs', 'other.egg-link', path_to_other)
+ >>> workingset = zc.buildout.easy_install.install(
+ ... ['other'], example_dest, links=[],
+ ... path=[join(example_dest, 'develop-eggs')],
+ ... executable=primed_executable,
+ ... index=None, include_site_packages=False)
+ Traceback (most recent call last):
+ ...
+ MissingDistribution: Couldn't find a distribution for 'other'.
+
+The MissingDistribution error shows that buildout correctly excluded the
+"site-packages" source even though it was indirectly included in the path
+via a .egg-link file.
+
"""
def buildout_include_site_packages_option():
@@ -2395,6 +2442,7 @@
... '''
... [buildout]
... parts = eggs
+ ... find-links =
...
... [primed_python]
... executable = %(primed_executable)s
@@ -2418,6 +2466,7 @@
... '''
... [buildout]
... parts = eggs
+ ... find-links =
... include-site-packages = false
...
... [primed_python]
More information about the Checkins
mailing list