aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2016-11-04 15:11:53 -0400
committerJason R. Coombs <jaraco@jaraco.com>2016-11-04 15:11:53 -0400
commitb163acc7a885419dbdcaf12623abd2d7065d4621 (patch)
tree6ed75461972698ea83830e9a43565baf548e3f96
parent51b10c39c0f55aaa34697b16d4b6b04805a4c8ec (diff)
downloadexternal_python_setuptools-b163acc7a885419dbdcaf12623abd2d7065d4621.tar.gz
external_python_setuptools-b163acc7a885419dbdcaf12623abd2d7065d4621.tar.bz2
external_python_setuptools-b163acc7a885419dbdcaf12623abd2d7065d4621.zip
Use packaging.version.Version to sort filenames by the version of the package they represent. Alternate implementation of that proposed in #829. Also ref #629.
-rw-r--r--CHANGES.rst8
-rw-r--r--pkg_resources/__init__.py33
2 files changed, 36 insertions, 5 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 3ef933e5..8caa2138 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,6 +2,14 @@
CHANGES
=======
+v28.8.0
+-------
+
+* #629: Per the discussion, refine the sorting to use version
+ value order for more accurate detection of the latest
+ available version when scanning for packages. See also
+ #829.
+
v28.7.1
-------
diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py
index 12226d4b..a323857c 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:
@@ -1966,6 +1967,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 +2006,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'):