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

vendoring logic subtly breaks later usage of unvendored system versions after importing pkg_resources.extern #1383

Open
eli-schwartz opened this issue May 27, 2018 · 10 comments
Labels
bug help wanted Needs Repro Issues that need a reproducible example.

Comments

@eli-schwartz
Copy link
Contributor

eli-schwartz commented May 27, 2018

In theory, if pkg_resources.extern is devendored, it should defer to the system installation of e.g. packaging, which means that:

>>> packaging.version
<module 'pip._vendor.packaging.version' from '/usr/lib/python3.6/site-packages/packaging/version.py'>
>>> pkg_resources.extern.packaging.version
<module 'pip._vendor.packaging.version' from '/usr/lib/python3.6/site-packages/packaging/version.py'>

It would be expected that I could then compare the results, since they're the same thing.

>>> pkg_resources.extern.packaging.version.parse('3.0') == packaging.version.parse('2.0')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'Version' and 'Version'

Oops?

For comparison, this works fine when using the similarly devendored pip.

>>> pip._vendor.packaging.version
<module 'packaging.version' from '/usr/lib/python3.6/site-packages/packaging/version.py'>
>>> packaging.version
<module 'packaging.version' from '/usr/lib/python3.6/site-packages/packaging/version.py'>
>>> pip._vendor.packaging.version.parse('3.0') > packaging.version.parse('2.0')
True

Note that pkg_resources must not be devendored from pip, or else it must be deleted from vendor/__init__.py, since otherwise it will be automatically imported. Even importing pkg_resources causes pip to fail as well.

>>> import pip._vendor.packaging.version
>>> import packaging.version
>>> pip._vendor.packaging.version.parse('3.0') > packaging.version.parse('2.0')
True

vs.

>>> import pip._vendor.packaging.version
>>> import pkg_resources.extern
>>> import packaging.version
>>> pip._vendor.packaging.version.parse('3.0') > packaging.version.parse('2.0')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'Version' and 'Version'

pypa/pip#5429 (comment) suggested the problem is deleting the global module unconditionally, whenever something vendored is in use. This strikes me as incredibly dangerous.

@yan12125
Copy link
Contributor

I believe issue #580 is related. Seems setuptools maintainers were considering switching to the pip approach regarding vendoring to fix such issues.

@jaraco
Copy link
Member

jaraco commented Jul 9, 2018

The origin of that hack is 6a5145a. Even though I wrote that code and I've stared at it for at least 15 minutes, I don't fully understand what's going on there. It seems plausible that the hack is over-reaching and really should only be employed when there's a prefix. So let's give that patch a go.

@jaraco jaraco closed this as completed in 949bd16 Jul 9, 2018
@jaraco
Copy link
Member

jaraco commented Jul 10, 2018

In the commit, @richard-scott reports that the patch (subtly altered) didn't fix the issue.

What we could use at this point is a way to replicate the issue. Could someone devise a recipe that replicates the issue (preferably in a virtualenv and cross-platform or in a docker image).

@jaraco jaraco reopened this Jul 10, 2018
@richard-scott
Copy link

All I did was install a fresh Ubuntu server and attempt to list outdated packages:

$ pip3 list --no-cache-dir --disable-pip-version-check --outdated --format=freeze

That said, I've removed the fix and the above command now works. My setup does automatically patch any pip packages on boot, so one of those may have been updated.

I'm currently running pip-10.0.1, and setuptools-40.0.0.

@pganssle pganssle added Needs Triage Issues that need to be evaluated for severity and status. bug help wanted Needs Repro Issues that need a reproducible example. and removed Needs Triage Issues that need to be evaluated for severity and status. labels Oct 19, 2018
@yan12125
Copy link
Contributor

I'm currently running pip-10.0.1, and setuptools-40.0.0.

@richard-scott This might be the reason for the breakage. You need setuptools >= 40.0.0 and pip >= 19.1 to get this command working with unvendored pip.

@jaraco
Copy link
Member

jaraco commented Mar 21, 2021

Signal boost for #2052, closed as a duplicate of this issue, which contains a lot of context and discussion.

@jaraco
Copy link
Member

jaraco commented Mar 21, 2021

The sole replication I have for this issue is that from @richard-scott, which appears no longer to be an issue:

draft $ cat Dockerfile
FROM ubuntu:focal
RUN apt update
RUN apt upgrade -y
RUN apt install -y python3-pip
draft $ docker run -it @$(docker build -q .) pip3 list --no-cache-dir --disable-pip-version-check --outdated --format=freeze
pip==20.0.2
setuptools==45.2.0
wheel==0.34.2

The examples from the original post don't include prerequisite steps, so it's difficult to tell what packaging or pkg_resources are.

Is this issue still present? If so, what use-cases are still degraded?

@mgorny
Copy link
Contributor

mgorny commented Jan 30, 2022

This still happens when unvendoring is done, i.e. after removing pkg_resources/_vendor.

My reproducer is:

import packaging.version

v1 = packaging.version.parse('1.2.3')

import pkg_resources.extern.packaging.version

v2 = packaging.version.parse('2.3.4')

v1 < v2

Unfortunately, something similar happens in polybar's sphinx logic. IIUC one Version is created early, another one much later and I suspect in between Sphinx imports pkg_resources somewhere.

@mgorny
Copy link
Contributor

mgorny commented Jan 31, 2022

Ironically, this bug is now causing 60.6.0 tests to fail:

_______________________________________________________ TestDepends.testRequire _______________________________________________________
[gw10] linux -- Python 3.9.10 /tmp/portage/dev-python/setuptools-60.6.0/work/setuptools-60.6.0-pypy3/install/usr/bin/pypy3

self = <setuptools.tests.test_setuptools.TestDepends object at 0x000055ee2b945d70>

    @needs_bytecode
    def testRequire(self):
        req = Require('Json', '1.0.3', 'json')
    
        assert req.name == 'Json'
        assert req.module == 'json'
>       assert req.requested_version == version.Version('1.0.3')
E       AssertionError: assert <Version('1.0.3')> == <Version('1.0.3')>
E         +<Version('1.0.3')>
E         -<Version('1.0.3')>

req        = <setuptools.depends.Require object at 0x000055ee2ea540c8>
self       = <setuptools.tests.test_setuptools.TestDepends object at 0x000055ee2b945d70>

/tmp/portage/dev-python/setuptools-60.6.0/work/setuptools-60.6.0/setuptools/tests/test_setuptools.py:94: AssertionError

@mgorny
Copy link
Contributor

mgorny commented Feb 2, 2022

If anyone else's still looking for a "good enough" hack, I've ended up taking unbundling one step further and removing setuptools.extern and pkg_resources.extern entirely:

	rm -r */extern || die
	find -name '*.py' -exec sed \
		-e 's:from \w*[.]extern ::' -e 's:\w*[.]extern[.]::' \
		-i {} + || die

DougBurke added a commit to DougBurke/sherpa that referenced this issue May 1, 2023
The CI runs of sherpa#1752 after
pulling in this branch sherpa#1753
started to fail because of a warning message that I could not
replicate. A search lead to this set of issues

- pypa/setuptools#2104
- pypa/setuptools#2052
- pypa/setuptools#1383

which suggests there's a subtle interaction between pip and
setuptools that we are falling over. As we currently have setuptools
pinned to < 60, whilst the distutils changes coming in Python 3.12
work through the ecosystem, the OTS code we run is likely to
hit this issue (i.e. nothing we can fix) so we can just skip the
warnings. Hopefully we can remove these additions soon.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug help wanted Needs Repro Issues that need a reproducible example.
Projects
None yet
Development

No branches or pull requests

6 participants