diff options
| author | Jason R. Coombs <jaraco@jaraco.com> | 2016-11-04 15:11:53 -0400 |
|---|---|---|
| committer | Jason R. Coombs <jaraco@jaraco.com> | 2016-11-04 15:11:53 -0400 |
| commit | b163acc7a885419dbdcaf12623abd2d7065d4621 (patch) | |
| tree | 6ed75461972698ea83830e9a43565baf548e3f96 | |
| parent | 51b10c39c0f55aaa34697b16d4b6b04805a4c8ec (diff) | |
| download | external_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.rst | 8 | ||||
| -rw-r--r-- | pkg_resources/__init__.py | 33 |
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'): |
