aboutsummaryrefslogtreecommitdiffstats
path: root/pkg_resources/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'pkg_resources/__init__.py')
-rw-r--r--pkg_resources/__init__.py57
1 files changed, 41 insertions, 16 deletions
diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py
index 12226d4b..4c9868c7 100644
--- a/pkg_resources/__init__.py
+++ b/pkg_resources/__init__.py
@@ -36,6 +36,7 @@ import plistlib
import email.parser
import tempfile
import textwrap
+import itertools
from pkgutil import get_importer
try:
@@ -74,11 +75,7 @@ __import__('pkg_resources.extern.packaging.requirements')
__import__('pkg_resources.extern.packaging.markers')
if (3, 0) < sys.version_info < (3, 3):
- msg = (
- "Support for Python 3.0-3.2 has been dropped. Future versions "
- "will fail here."
- )
- warnings.warn(msg)
+ raise RuntimeError("Python 3.3 or later is required")
# declare some globals that will be defined later to
# satisfy the linters.
@@ -1966,6 +1963,32 @@ def find_nothing(importer, path_item, only=False):
register_finder(object, find_nothing)
+def _by_version_descending(names):
+ """
+ Given a list of filenames, return them in descending order
+ by version number.
+
+ >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg'
+ >>> _by_version_descending(names)
+ ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar']
+ >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg'
+ >>> _by_version_descending(names)
+ ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg']
+ >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg'
+ >>> _by_version_descending(names)
+ ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg']
+ """
+ def _by_version(name):
+ """
+ Parse each component of the filename
+ """
+ name, ext = os.path.splitext(name)
+ parts = itertools.chain(name.split('-'), [ext])
+ return [packaging.version.parse(part) for part in parts]
+
+ return sorted(names, key=_by_version, reverse=True)
+
+
def find_on_path(importer, path_item, only=False):
"""Yield distributions accessible on a sys.path directory"""
path_item = _normalize_cached(path_item)
@@ -1979,11 +2002,7 @@ def find_on_path(importer, path_item, only=False):
)
else:
# scan for .egg and .egg-info in directory
-
- path_item_entries = os.listdir(path_item)
- # Reverse so we find the newest version of a distribution,
- path_item_entries.sort()
- path_item_entries.reverse()
+ path_item_entries = _by_version_descending(os.listdir(path_item))
for entry in path_item_entries:
lower = entry.lower()
if lower.endswith('.egg-info') or lower.endswith('.dist-info'):
@@ -2094,6 +2113,10 @@ def _rebuild_mod_path(orig_path, package_name, module):
parts = path_parts[:-module_parts]
return safe_sys_path_index(_normalize_cached(os.sep.join(parts)))
+ if not isinstance(orig_path, list):
+ # Is this behavior useful when module.__path__ is not a list?
+ return
+
orig_path.sort(key=position_in_sys_path)
module.__path__[:] = [_normalize_cached(p) for p in orig_path]
@@ -2986,9 +3009,11 @@ def _initialize(g=globals()):
"Set up global resource manager (deliberately not state-saved)"
manager = ResourceManager()
g['_manager'] = manager
- for name in dir(manager):
- if not name.startswith('_'):
- g[name] = getattr(manager, name)
+ g.update(
+ (name, getattr(manager, name))
+ for name in dir(manager)
+ if not name.startswith('_')
+ )
@_call_aside
@@ -3017,10 +3042,10 @@ def _initialize_master_working_set():
# ensure that all distributions added to the working set in the future
# (e.g. by calling ``require()``) will get activated as well,
# with higher priority (replace=True).
- dist = None # ensure dist is defined for del dist below
- for dist in working_set:
+ tuple(
dist.activate(replace=False)
- del dist
+ for dist in working_set
+ )
add_activation_listener(lambda dist: dist.activate(replace=True), existing=False)
working_set.entries = []
# match order