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

Avoid Debian-patched pip in the shared venv #394

Merged
merged 2 commits into from
Jul 26, 2020

Conversation

mgedmin
Copy link
Contributor

@mgedmin mgedmin commented Apr 24, 2020

Should fix #386.

This fix should be more lightweight than #387, and it is simpler than #388. It tries to find an acceptable middle ground between explicitly supporting Debian's changes to their pip and causing pain to users in order to make a statement.

This patch needs testing. I haven't come up with a test plan yet (I don't want to mess up my currently-working actual pipx setup), but I'll try to do something with docker.

@mgedmin
Copy link
Contributor Author

mgedmin commented Apr 24, 2020

Test plan:

This confirms that my fix works!

Replacing step 3 with pip3 install --user pipx confirms that the test plan can recreate #393, which is a manifestation of #386.

Now to fix unit tests.

# current upstream pip version. Otherwise there's a flood of
# bug reports about things not working, like
# https://github.com/pipxproject/pipx/issues/386
self.upgrade(["-I"] + pip_args, verbose)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this be a NO OP when running outside of Debian? Would not want to make all platforms slower to patch a Debian bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. Some measurements would be nice to have. I don't have any non-Debian-based systems to test against, unless maybe I could come up with something using Docker and Alpine?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, -I makes this step faster

$ docker run -ti --rm python:3.8-alpine sh
... some experiments to get the commands right ...
... which incidentally populate ~/.pip/cache so the measurements are independent of network speed ...
/ # rm -rf env && time python3 -m venv env --clear && time env/bin/python -m pip --disable-pip-version-check install --upgrade pip setuptools wheel
real	0m 1.75s
user	0m 1.59s
sys	0m 0.15s
Collecting pip
  Using cached https://files.pythonhosted.org/packages/54/0c/d01aa759fdc501a58f431eb594a17495f15b88da142ce14b5845662c13f3/pip-20.0.2-py2.py3-none-any.whl
Collecting setuptools
  Using cached https://files.pythonhosted.org/packages/a0/df/635cdb901ee4a8a42ec68e480c49f85f4c59e8816effbf57d9e6ee8b3588/setuptools-46.1.3-py3-none-any.whl
Collecting wheel
  Using cached https://files.pythonhosted.org/packages/8c/23/848298cccf8e40f5bbb59009b32848a4c38f4e7f3364297ab3c3e2e2cd14/wheel-0.34.2-py2.py3-none-any.whl
Installing collected packages: pip, setuptools, wheel
  Found existing installation: pip 19.2.3
    Uninstalling pip-19.2.3:
      Successfully uninstalled pip-19.2.3
  Found existing installation: setuptools 41.2.0
    Uninstalling setuptools-41.2.0:
      Successfully uninstalled setuptools-41.2.0
Successfully installed pip-20.0.2 setuptools-46.1.3 wheel-0.34.2
real	0m 2.53s
user	0m 2.05s
sys	0m 0.19s
/ # rm -rf env && time python3 -m venv env --clear && time env/bin/python -m pip --disable-pip-version-check install -I --upgrade pip setuptools wheel
real	0m 1.77s
user	0m 1.61s
sys	0m 0.15s
Collecting pip
  Using cached https://files.pythonhosted.org/packages/54/0c/d01aa759fdc501a58f431eb594a17495f15b88da142ce14b5845662c13f3/pip-20.0.2-py2.py3-none-any.whl
Collecting setuptools
  Using cached https://files.pythonhosted.org/packages/a0/df/635cdb901ee4a8a42ec68e480c49f85f4c59e8816effbf57d9e6ee8b3588/setuptools-46.1.3-py3-none-any.whl
Collecting wheel
  Using cached https://files.pythonhosted.org/packages/8c/23/848298cccf8e40f5bbb59009b32848a4c38f4e7f3364297ab3c3e2e2cd14/wheel-0.34.2-py2.py3-none-any.whl
Installing collected packages: pip, setuptools, wheel
Successfully installed pip-20.0.2 setuptools-46.1.3 wheel-0.34.2
real	0m 1.83s
user	0m 1.47s
sys	0m 0.18s

without -I: 2.53s
with -I: 1.83s

overhead of python -m venv env --clear: 1.75s (same in both cases)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which incidentally populate ~/.pip/cache so the measurements are independent of network speed ...

Unless I'm misunderstanding something - this comment highlights that time measured avoids one of the most relevant impacts - all users will have to download pip. Here are the docs for -I

-I, --ignore-installed      Ignore the installed packages, overwriting them. This can 
                              break your system if the existing package is of a different version
                              or was installed with a different package manager!

So this would always ignore the system pip (possibly re-downloading it) for everyone.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good point, but as you saw in my terminal log, pip is downloaded and installed irrespective of the -I flag.

I'm not familiar with venv and I don't know where it found the old outdated versions of pip/setuptools that got installed in my experimental venv. Do you know how I could reproduce (in Docker?) a situation where venv installs up-to-date versions if pip/setuotools that don't require an upgrade?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pip is downloaded and installed irrespective of the -I flag.
That is a good point, but as you saw in my terminal log, pip is downloaded and installed irrespective of the -I flag.

The log shows pip was cached, but in any case, the shared libs directory is created rarely, and installing a version of pip that is guaranteed to be good is appealing. Being able to install packages from the internet is required for pipx to work, so I don't think pip, setuptools, and wheel being downloaded every once in a while will have a significant negative impact on user experience.

Is this actually overwriting the system pip or just the pip in the venv? If it's the former I don't think we should land it because we could be breaking OS's. If it's the latter, I think we should merge this since it will make pipx hermetic to whatever weird system things are going on. Does anyone know?

Copy link
Member

@cs01 cs01 Jul 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another q: should --force-reinstall be preferred? https://stackoverflow.com/questions/51913361/difference-between-pip-install-options-ignore-installed-and-force-reinstall indicated the following

"Otherwise, you may get obscure import errors after reinstall due to stale modules still available in sys.path."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a scary warning in the pip docs:

Ignore the installed packages, overwriting them. This can break your system if the existing package is of a different version or was installed with a different package manager!

https://pip.pypa.io/en/stable/reference/pip_install/

I don't know enough about the relationship between OS packages vs how --ignore-installed or --force-reinstall affects them, so unfortunately I don't feel comfortable merging this.

@@ -5,6 +5,7 @@ dev
- [bugfix] Replaced implicit dependency on setuptools with an explicit dependency on packaging (#339).
- [refactor] Moved all commands to separate files within the commands module (#255).
- [bugfix] Continue reinstalling packages after failure
- [bugfix] Fixed incompatibility with Debian/Ubuntu changes made to their version of pip (#386).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering the bug is within Debian packaging I consider this more an enhancement than bug fix; something along the line (Support Debian 20s pip patching).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've checked the "Allow edits from maintainers" box.

I'm a bit confused about the phrase "Support Debian 20s pip". What's "20s"? pip version?

I haven't mentioned specific Debian/Ubuntu/pip versions because I haven't done the research to figure out where the incompatibility got introduced. I know things worked in Ubuntu 19.10 and broke in 20.04. I don't run Debian myself and have trouble remembering its version numbers and codenames.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would

Suggested change
- [bugfix] Fixed incompatibility with Debian/Ubuntu changes made to their version of pip (#386).
- [enhancement] Insulate from problems caused by Debian/Ubuntu changes made to their version of pip (#386).

work for you?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debian decided lately to package pip by trying to devendor six from within pip... the problem is the way they did this unvendoring does not work with venvs... Not to mention the pip within the venv is supposed to be the latest pip (or the bundled version), but either way not a reference to the operating system pip, but a full copy on its own that install/uninstallable.

Anyways I've purposefully did not do any changes here as IMHO this should be fixed on Debian side and not our end. Just throwing my ideas out there, however not planning to accept this PR myself. Maybe other maintainers are more agreeable to it, in which case I'll not stop it 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The optimal solution is for Debian to fix this issue. But from a user perspective, it looks like pipx is broken, and there is no way for us to control Debian. Is there a timeline for the fix on the Debian side?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a link to the bug in the Debian bug tracker? (This assumes anyone reported it to Debian already.)

Once it's fixed in Debian, it should be possible to backport the fix to Ubuntu 20.04 LTS by creating a SRU. It's just tedious work.

In the meantime I suspect users will keep filing duplicate bug reports or looking for alternative projects...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't look like anyone's reported it to Debian, so I went ahead and did just now: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=958764

@ivanov
Copy link

ivanov commented Apr 25, 2020

I'm reposting my code comment reply here:

@mgedmin wrote:

$ docker run -ti --rm python:3.8-alpine sh
... some experiments to get the commands right ...
... which incidentally populate ~/.pip/cache so the measurements are independent of network speed ....

Unless I'm misunderstanding something - this comment highlights that time measured avoids one of the most relevant impacts - all users will have to download pip. Here are the docs for -I

-I, --ignore-installed      Ignore the installed packages, overwriting them. This can 
                              break your system if the existing package is of a different version
                              or was installed with a different package manager!

So this would always ignore the system pip (possibly re-downloading it) for everyone. I don't think that's great. I think the approach in #388 is sufficient for getting a workable pip out of how it is packaged in Debian that does not force everyone else to reinstall pip.

@cs01
Copy link
Member

cs01 commented May 11, 2020

Where are we on this?

Debian has fixed its pip installation thanks to @ivanov (#388 (comment)). Is this still needed or should it be closed?

Its fine if it causes a slight slowdown because it only affects the shared libraries, which are installed rarely, and thus the impact to the user will be minimal.

I am curious if adding this would sidestep various inconsistencies in the environment though, which might be nice since it would ensure the same pip source code is used for everyone.

In that case we may want to consider adding this even though Debian has fixed its vendoring upstream.

@mgedmin mgedmin force-pushed the debian-what-you-doin branch from 6ab2540 to 1040577 Compare May 11, 2020 07:50
@mgedmin
Copy link
Contributor Author

mgedmin commented May 11, 2020

Rebased on master to resolve the changelog merge conflict.

@cs01 cs01 force-pushed the debian-what-you-doin branch from 1040577 to 70f027b Compare July 14, 2020 20:26
@gaborbernat gaborbernat merged commit 2f46e80 into pypa:master Jul 26, 2020
@mgedmin mgedmin deleted the debian-what-you-doin branch August 19, 2020 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ModuleNotFoundError: No module named 'pip._vendor.six' when running "pipx install"
4 participants