From d3de33538948081d9ef39168fde870c977e30115 Mon Sep 17 00:00:00 2001 From: Erik Bray Date: Thu, 31 Dec 2015 14:17:41 -0500 Subject: Fixes the original root cause of #231, and re-enables the test when the tempdir is a symlink (this does not explicitly test that /tmp itself is a symlink, but the effect is the same--only one of the path levels needs to be a symlink to reproduce this isssue) --- pkg_resources/__init__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 7becc951..7d2fa7e9 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -2182,9 +2182,14 @@ def _handle_ns(packageName, path_item): path = module.__path__ path.append(subpath) loader.load_module(packageName) + + # Ensure that all paths on __path__ have been run through + # normalize_path + normalized_paths = set(_normalize_cached(p) for p in module.__path__) for path_item in path: - if path_item not in module.__path__: - module.__path__.append(path_item) + normalized = _normalize_cached(path_item) + if normalized not in normalized_paths: + module.__path__.append(normalized) return subpath def declare_namespace(packageName): -- cgit v1.2.3 From ebc54982b1085b05054a75dbcdd16008ac20a60e Mon Sep 17 00:00:00 2001 From: Erik Bray Date: Wed, 6 Jan 2016 17:08:56 -0500 Subject: Sort __path__ entries for namespace packages according to their order in sys.path. This ensures that lookups in __path__ will be the same as sys.path resolution. This also adds a replace argument to Distribution.insert_on meant to be used with the replace argumen to WorkingSet.add. This ensures that new sys.path entries added via WorkingSet.add are inserted at the beginning, rather than appended to the end. This is necessary for consistency with the above change, and kind of makes more sense anyways. This means that if a Distribution is added to a WorkingSet, that replaces a different version of that Distribution, the new version of that Distribution will have its location first on sys.path. --- pkg_resources/__init__.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 7d2fa7e9..46db5cc7 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -755,7 +755,7 @@ class WorkingSet(object): will be called. """ if insert: - dist.insert_on(self.entries, entry) + dist.insert_on(self.entries, entry, replace=replace) if entry is None: entry = dist.location @@ -2183,13 +2183,16 @@ def _handle_ns(packageName, path_item): path.append(subpath) loader.load_module(packageName) - # Ensure that all paths on __path__ have been run through - # normalize_path - normalized_paths = set(_normalize_cached(p) for p in module.__path__) - for path_item in path: - normalized = _normalize_cached(path_item) - if normalized not in normalized_paths: - module.__path__.append(normalized) + # Rebuild mod.__path__ ensuring that all entries are ordered + # corresponding to their sys.path order + sys_path= [(p and _normalize_cached(p) or p) for p in sys.path] + def sort_key(p): + parts = p.split(os.sep) + parts = parts[:-(packageName.count('.') + 1)] + return sys_path.index(_normalize_cached(os.sep.join(parts))) + + path.sort(key=sort_key) + module.__path__[:] = [_normalize_cached(p) for p in path] return subpath def declare_namespace(packageName): @@ -2644,7 +2647,7 @@ class Distribution(object): """Ensure distribution is importable on `path` (default=sys.path)""" if path is None: path = sys.path - self.insert_on(path) + self.insert_on(path, replace=True) if path is sys.path: fixup_namespace_packages(self.location) for pkg in self._get_metadata('namespace_packages.txt'): @@ -2721,7 +2724,7 @@ class Distribution(object): """Return the EntryPoint object for `group`+`name`, or ``None``""" return self.get_entry_map(group).get(name) - def insert_on(self, path, loc = None): + def insert_on(self, path, loc=None, replace=False): """Insert self.location in path before its nearest parent directory""" loc = loc or self.location @@ -2745,7 +2748,10 @@ class Distribution(object): else: if path is sys.path: self.check_version_conflict() - path.append(loc) + if replace: + path.insert(0, loc) + else: + path.append(loc) return # p is the spot where we found or inserted loc; now remove duplicates -- cgit v1.2.3 From 8af3b6ef5b4173a0d0d6735147c98c882ae98344 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 06:54:00 -0500 Subject: Always use Python 3 version of map --- pkg_resources/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 7becc951..8382571e 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -46,7 +46,7 @@ except ImportError: import imp as _imp from pkg_resources.extern import six -from pkg_resources.extern.six.moves import urllib +from pkg_resources.extern.six.moves import urllib, map # capture these to bypass sandboxing from os import utime -- cgit v1.2.3 From e2f1814e0d3d8963cf3a1eb4dff6d400b58b4a52 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 18:13:32 -0500 Subject: Invoke import on importlib.machinery directly. Access an attribute to force import in delayed-import environments. Fixes #487. --- pkg_resources/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 50b86cdb..3ecf4c64 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -60,10 +60,11 @@ except ImportError: from os import open as os_open from os.path import isdir, split -# Avoid try/except due to potential problems with delayed import mechanisms. -if sys.version_info >= (3, 3) and sys.implementation.name == "cpython": +try: import importlib.machinery as importlib_machinery -else: + # access attribute to force import under delayed import mechanisms. + importlib_machinery.__name__ +except ImportError: importlib_machinery = None try: -- cgit v1.2.3 From e01792ec62653b00b6d1c25e1ca0d10d22c1b6b9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 26 Jan 2016 14:30:34 -0500 Subject: Combine redundant imports of future functionality --- pkg_resources/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 3ecf4c64..2ba5ca42 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -46,7 +46,7 @@ except ImportError: import imp as _imp from pkg_resources.extern import six -from pkg_resources.extern.six.moves import urllib, map +from pkg_resources.extern.six.moves import urllib, map, filter # capture these to bypass sandboxing from os import utime @@ -77,9 +77,6 @@ __import__('pkg_resources.extern.packaging.version') __import__('pkg_resources.extern.packaging.specifiers') -filter = six.moves.filter -map = six.moves.map - if (3, 0) < sys.version_info < (3, 3): msg = ( "Support for Python 3.0-3.2 has been dropped. Future versions " -- cgit v1.2.3 From 397d759e48bc93597c535c2335c9da37178721a5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 26 Jan 2016 14:34:31 -0500 Subject: Pull up DefaultProvider registration into a classmethod. --- pkg_resources/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 2ba5ca42..b4f910c6 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -1725,10 +1725,14 @@ class DefaultProvider(EggProvider): with open(path, 'rb') as stream: return stream.read() -register_loader_type(type(None), DefaultProvider) + @classmethod + def _register(cls): + register_loader_type(type(None), cls) -if importlib_machinery is not None: - register_loader_type(importlib_machinery.SourceFileLoader, DefaultProvider) + if importlib_machinery is not None: + register_loader_type(importlib_machinery.SourceFileLoader, cls) + +DefaultProvider._register() class EmptyProvider(NullProvider): -- cgit v1.2.3 From 66b3a623dd256def923ddde303b8c95592d0223b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 26 Jan 2016 14:42:03 -0500 Subject: Adapt resolution of classes from importlib.machinery. Restores compatibility for PyPy3 where importlib.machinery exists but FileFinder and SourceFileLoader aren't implemented. --- pkg_resources/__init__.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index b4f910c6..f15becbb 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -1727,10 +1727,9 @@ class DefaultProvider(EggProvider): @classmethod def _register(cls): - register_loader_type(type(None), cls) - - if importlib_machinery is not None: - register_loader_type(importlib_machinery.SourceFileLoader, cls) + loader_cls = getattr(importlib_machinery, 'SourceFileLoader', + type(None)) + register_loader_type(loader_cls, cls) DefaultProvider._register() @@ -2138,7 +2137,7 @@ def find_on_path(importer, path_item, only=False): break register_finder(pkgutil.ImpImporter, find_on_path) -if importlib_machinery is not None: +if hasattr(importlib_machinery, 'FileFinder'): register_finder(importlib_machinery.FileFinder, find_on_path) _declare_state('dict', _namespace_handlers={}) @@ -2255,7 +2254,7 @@ def file_ns_handler(importer, path_item, packageName, module): register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) register_namespace_handler(zipimport.zipimporter, file_ns_handler) -if importlib_machinery is not None: +if hasattr(importlib_machinery, 'FileFinder'): register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) -- cgit v1.2.3 From d16b24ef68298295224f078c96fcbf732aa0dacc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 04:24:04 -0500 Subject: Extract function _rebuild_mod_path --- pkg_resources/__init__.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index f15becbb..3398a56b 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -2183,18 +2183,24 @@ def _handle_ns(packageName, path_item): path = module.__path__ path.append(subpath) loader.load_module(packageName) + _rebuild_mod_path(path, packageName, module) + return subpath - # Rebuild mod.__path__ ensuring that all entries are ordered - # corresponding to their sys.path order - sys_path= [(p and _normalize_cached(p) or p) for p in sys.path] - def sort_key(p): - parts = p.split(os.sep) - parts = parts[:-(packageName.count('.') + 1)] - return sys_path.index(_normalize_cached(os.sep.join(parts))) - path.sort(key=sort_key) - module.__path__[:] = [_normalize_cached(p) for p in path] - return subpath +def _rebuild_mod_path(orig_path, package_name, module): + """ + Rebuild module.__path__ ensuring that all entries are ordered + corresponding to their sys.path order + """ + sys_path= [(p and _normalize_cached(p) or p) for p in sys.path] + def sort_key(p): + parts = p.split(os.sep) + parts = parts[:-(package_name.count('.') + 1)] + return sys_path.index(_normalize_cached(os.sep.join(parts))) + + orig_path.sort(key=sort_key) + module.__path__[:] = [_normalize_cached(p) for p in orig_path] + def declare_namespace(packageName): """Declare that package 'packageName' is a namespace package""" -- cgit v1.2.3 From c8a0d2d70aedf13382c6e0a506c04d449851ec45 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 04:28:06 -0500 Subject: Rename inner function and add docstring --- pkg_resources/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 3398a56b..70658062 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -2192,13 +2192,16 @@ def _rebuild_mod_path(orig_path, package_name, module): Rebuild module.__path__ ensuring that all entries are ordered corresponding to their sys.path order """ - sys_path= [(p and _normalize_cached(p) or p) for p in sys.path] - def sort_key(p): + sys_path = [(p and _normalize_cached(p) or p) for p in sys.path] + def position_in_sys_path(p): + """ + Return the ordinal of the path based on its position in sys.path + """ parts = p.split(os.sep) parts = parts[:-(package_name.count('.') + 1)] return sys_path.index(_normalize_cached(os.sep.join(parts))) - orig_path.sort(key=sort_key) + orig_path.sort(key=position_in_sys_path) module.__path__[:] = [_normalize_cached(p) for p in orig_path] -- cgit v1.2.3 From 94e1f4c266b7fdde993c5fde05f87dcc0afd186e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 04:46:53 -0500 Subject: Normalize all paths, not excluding ''. Fixes #491. --- pkg_resources/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 70658062..7ba23bf5 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -2192,7 +2192,7 @@ def _rebuild_mod_path(orig_path, package_name, module): Rebuild module.__path__ ensuring that all entries are ordered corresponding to their sys.path order """ - sys_path = [(p and _normalize_cached(p) or p) for p in sys.path] + sys_path = [_normalize_cached(p) for p in sys.path] def position_in_sys_path(p): """ Return the ordinal of the path based on its position in sys.path -- cgit v1.2.3 From 0dcee791dfdcfacddaaec79b29f30a347a147413 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 21:35:13 -0500 Subject: Extract variable for template string --- pkg_resources/__init__.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 7ba23bf5..4fdc5f91 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -1174,22 +1174,23 @@ class ResourceManager: old_exc = sys.exc_info()[1] cache_path = self.extraction_path or get_default_cache() - err = ExtractionError("""Can't extract file(s) to egg cache + tmpl = textwrap.dedent(""" + Can't extract file(s) to egg cache -The following error occurred while trying to extract file(s) to the Python egg -cache: + The following error occurred while trying to extract file(s) to the Python egg + cache: - %s + %s -The Python egg cache directory is currently set to: + The Python egg cache directory is currently set to: - %s + %s -Perhaps your account does not have write access to this directory? You can -change the cache directory by setting the PYTHON_EGG_CACHE environment -variable to point to an accessible directory. -""" % (old_exc, cache_path) - ) + Perhaps your account does not have write access to this directory? You can + change the cache directory by setting the PYTHON_EGG_CACHE environment + variable to point to an accessible directory. + """).lstrip() + err = ExtractionError(tmpl % (old_exc, cache_path)) err.manager = self err.cache_path = cache_path err.original_error = old_exc -- cgit v1.2.3 From f9bd9b9f5df54ef5a0bf8d16c3a889ab8c640580 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 21:36:23 -0500 Subject: Use new style string formatting --- pkg_resources/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'pkg_resources/__init__.py') diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 4fdc5f91..d04cd347 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -1180,17 +1180,17 @@ class ResourceManager: The following error occurred while trying to extract file(s) to the Python egg cache: - %s + {old_exc} The Python egg cache directory is currently set to: - %s + {cache_path} Perhaps your account does not have write access to this directory? You can change the cache directory by setting the PYTHON_EGG_CACHE environment variable to point to an accessible directory. """).lstrip() - err = ExtractionError(tmpl % (old_exc, cache_path)) + err = ExtractionError(tmpl.format(**locals())) err.manager = self err.cache_path = cache_path err.original_error = old_exc -- cgit v1.2.3