Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg_resources will fail when packaging removes LegacyVersion #2547

Closed
pfmoore opened this issue Jan 31, 2021 · 2 comments
Closed

pkg_resources will fail when packaging removes LegacyVersion #2547

pfmoore opened this issue Jan 31, 2021 · 2 comments

Comments

@pfmoore
Copy link
Member

pfmoore commented Jan 31, 2021

See pypa/pip#9540 for background here.

Basically, pip vendors pkg_resources, but uses it with pip's own vendored copy of packaging, not with the one setuptools vendors. In the latest release of packaging, legacy versions are deprecated and trigger a DeprecationWarning. Python's test suite runs pip with warnings converted to errors, and this resulted in a failure, which I traced back to the following code in pkg_resources:

    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]

(This is an internal function of _by_version_descending). The code is the same in the latest version of setuptools.

Note that this code parses every part of the filename, not checking whether the parse works and so relying on the fact that packaging will currently parse any old garbage, returning a LegacyVersion. This is what triggers the issue here.

Obviously, setuptools won't hit an issue here until it upgrades its vendored copy of packaging to one that finally removes LegacyVersion (or one that deprecates, if the user is running with warnings treated as errors). So it's not an immediate issue here (even though it is for pip).

The following code fixes this problem, but it's not exactly attractive, and I'm not sure whether there's any implication to sometimes returning a string and sometimes a Version. Also, I haven't checked anywhere else to see if this same pattern is repeated anywhere else in setuptools. Maybe it's useful, nevertheless.

    def _by_version(name):
        """
        Parse each component of the filename
        """
        name, ext = os.path.splitext(name)
        parts = itertools.chain(name.split('-'), [ext])
        def safe_parse(s):
            try:
                return packaging.version.parse(s)
            except (packaging.version.InvalidVersion, DeprecationWarning):
                return s
        return [safe_parse(part) for part in parts]
@jaraco
Copy link
Member

jaraco commented Feb 1, 2021

See also #2466, #2497, and #2478. To be sure, Setuptools is uninterested in maintaining support for non-standard versions.

@pfmoore
Copy link
Member Author

pfmoore commented Feb 1, 2021

Sorry I didn't spot the issues you linked. Apologies for that. This can be closed as a duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants