Skip to content

Fix isolated builds when enum34 is installed #8217

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

Closed
wants to merge 1 commit into from

Conversation

abadger
Copy link
Contributor

@abadger abadger commented May 10, 2020

With the prior code, a python library installed into the same directory
as pip will be promoted to be found before other libraries of the same
name when an isolated build is performed. This is because
pip/__main__.py adds the directory holding pip to the front of sys.path
where both the pip library and the other libraries will be found before
the other libraries.

This is especially problematic for libraries which shadow the names of
stdlib libraries. The enum34 library, for instance, will shadow the
stdlib enum library. When pip runs an isolated build and the enum34
library is installed, enum.py from the enum34 library will be found and
imported instead of enum.py from the stdlib. That, in turn, breaks the
stdlib re module which then breaks pip.

This commit fixes that by changing build_env to invoke pip a different
way (by calling python on pip/__main__.py instead of calling python on
pip/). Using __main__.py changes what python sets the value of
__package__ to which, in turn, makes it so the code in __main__.py
does not add the directory holding pip to sys.path.

Fixes #8214

With the prior code, a python library installed into the same directory
as pip will be promoted to be found before other libraries of the same
name when an isolated build is performed.  This is because
pip/__main__.py adds the directory holding pip to the front of sys.path
where both the pip library and the other libraries will be found before
the other libraries.

This is especially problematic for libraries which shadow the names of
stdlib libraries.  The enum34 library, for instance, will shadow the
stdlib enum library.  When pip runs an isolated build and the enum34
library is installed, enum.py from the enum34 library will be found and
imported instead of enum.py from the stdlib.  That, in turn, breaks the
stdlib re module which then breaks pip.

This commit fixes that by changing build_env to invoke pip a different
way (by calling python on pip/__main__.py instead of calling python on
pip/).  Using __main__.py changes what python sets the value of
__package__ to which, in turn, makes it so the code in __main__.py
does not add the directory holding pip to sys.path.

Fixes pypa#8214
@abadger abadger force-pushed the fix-pip-build_env branch from cc18fc2 to cf08eb3 Compare May 10, 2020 00:57
@abadger
Copy link
Contributor Author

abadger commented May 15, 2020

I've been thinking about this all week and I'm pretty sure that there is a drawback to this one. I think it break the guarantee that the pip library that is imported when pip is re-invoked is the same as the pip library which was originally run. The reason is that python is probably going to treat python /path/to/__main__.py as invoking a script rather than executing a module. (I'm not sure if the original code made that guarantee in and of itself either.... It might be that the conditional in __main__.py is what made python import the correct library when pip was re-invoking itself).

@pfmoore
Copy link
Member

pfmoore commented May 15, 2020

Given that the issue is with the internal code that invokes pip to build the isolated environment, why can't we use pip internals here, and do something like

<sys.executable> -c "sys.path.insert(0, <what we want>); from pip import main; main(...)"

There's no need that I can see to mess with pip's command line startup code at all if we do that.

Please do not just put together yet another PR implementing this idea. Instead, can you do as I suggested and start with a test that demonstrates the issue, which can be added to one of the existing PRs, which we can then iterate on to decide on the best implementation.

@abadger
Copy link
Contributor Author

abadger commented May 15, 2020 via email

@pradyunsg
Copy link
Member

Closing due to lack of movement here. Please feel free to file a new PR if you want to get the ball rolling again! :)

@pradyunsg pradyunsg closed this Feb 26, 2021
@abadger
Copy link
Contributor Author

abadger commented Feb 26, 2021

No problem. I open prs because it's fine easier for me to see pros and cons of different ways to implement something with actually working code rather than abstract discussion.

I can open another pr if the score of what pip needs to actually care about is determined in #8214

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 1, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

With Enum34 installed on python3.6+, pip picks up enum34 instead of the stdlib enum package
3 participants