-
Notifications
You must be signed in to change notification settings - Fork 3k
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
[WIP] Implement --global and try to default to --user when it makes sense #2418
Conversation
# --isolated and such options as well. | ||
# TODO: Figure out if this works when the directories don't exist. | ||
for path in distutils_scheme("").values(): | ||
if not os.access(path, os.W_OK): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to behave properly on Windows. os.access(r'C:\Windows', os.W_OK)
is True for me, but open(r'C:\Windows\test.file', 'w').close()
fails with errors on 2.7 and 3.4.
I was expecting this check to happen at a higher level - about the point where pip would terminate with an error but instead retry with --user
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Retrying with --user
seems like the wrong answer to me to be honest. It sounds like it'd be easy to lead to half way installed things and it would be a lot more fragile. If os.access
doesn't work we can probably do something based on trying to open file with w
to test it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How soon do we know the destination subfolder? Can we switch when trying to create that (and maybe bring creation sooner if necessary)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, but thinking about it more the other side of this is that we don't want pip install foo
and pip install bar
to install to different locations, so this should ideally be a check that is independent of the thing we're installing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
os.access currently always returns True for directories on Windows: http://bugs.python.org/issue2528
Oh, we'll want to figure out what happens if you do |
Probably leave it alone, yes. But what then if you do But scripts probably want a way to remove all traces of a package. I guess doing both global and user uninstalls is OK, but checking for errors could be annoying (if there's a good chance that one or other of the global and user uninstalls will fail because the package isn't installed). So:
|
Also, suppose I do Questions:
I have a feeling that allowing there to ever be 2 different versions of a package installed will come with a lot of odd edge cases. But of course, we have to allow that as otherwise a user without access to the global location won't be able to upgrade a globally-installed package. Please note - I've deliberately not used sudo here. If you do The answer to all of these questions might well be just to write the code naturally, and wait for bug reports - that may be the only way of getting meaningful feedback on what are real issues, as opposed to theoretical risks. |
Yea they are certainly edge cases we're likely to run into, especially since i don't know how much To answer your questions: I think that we're not going to get around having multiple versions of the same thing installed and only one version visible at a time. This is actually already the case on Debuntu systems where I do think we need to ensure that all of the dependencies are satisfied at an equal level or later level in the hierarchy. What I mean is that It might make sense when doing |
Did you mean (...) from |
|
||
# If any of our potentional locations for writing files is not writable by | ||
# us then we want to use the --user scheme instead of the --global scheme. | ||
# TODO: We should figure out a way to make this work for --root and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if someone intentionally specifies a --root
, but they don't have permissions, it should just fail I think, and never switch to a user install. same thing when specifying custom --install-option
arguments.
note that our distutils_scheme
function reads custom locations from distutils config files, so with your implementation as is, you will be switching users to a user install if any of those custom paths are not writable, which I think is misleading.
Should this and #1668 have some kind of "pip 7" tag? I presume this wouldn't be merged now while there are still 6.x releases planned and I believe I saw that 6.1.0 is the next planned release? |
6.1 is the next planned only because nothing has been merged that would warrant a 7.0. |
Why would it act like I would think that if you're in a virtualenv, it installs to the virtualenv by default always and only does something else if you pass --user or --global. |
Inside of a virtual environment |
Wouldn't hurt to add "7.0" and "Improve our User Experience" milestones? |
It can only be in one milestone, so I added it to 7.0. |
Oh so --global inside a virtualenv means "in the virtualenv"? That is unintuitive to me. Especially when one of the items above says:
But I guess if it makes sense if global in a virtualenv means "not user but global within the virtualenv" But that seems super confusing. What terminology do use to distinguish "global in the virtualenv" to "global global" ("system global"?) |
I guess I was thinking that there are 3 places a package can be installed.
But maybe that is the wrong model. |
It sounds like maybe "global" the way you use the term here means "non-user" (not in the user's directory). I think I assumed "global" to mean "system". Is that right? |
"global" here (AIUI) basically means |
action='store_false', | ||
help='Install into the global site packages.') | ||
|
||
cmd_opts.add_option( | ||
'--egg', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know enough about how command options translate to environment variables and/or config file entries. Does this mean that PIP_GLOBAL
or a global
setting in the config file would make global the default (once the hard-coded default becomes "user")? If not, how would someone say they wanted to have global as the default?
Accidentally closed this, reopening. Sorry! |
Hello! As part of an effort to ease the contribution process and adopt a more standard workflow pip has switched to doing development on the If you do nothing, this Pull Request will be automatically closed by @BrownTruck since it cannot be merged. If this pull request is still valid, please rebase it against If you choose to rebase/merge and resubmit this Pull Request, here is an example message that you can copy and paste:
|
This Pull Request was closed because it cannot be automatically reparented to the Please feel free to re-open it or re-submit it if it is still valid and you have rebased it onto |
Would it be fine if I try to take this forward? |
Sure |
Fixes #1668 by implementing:
--user
is passed we always install into the user site packages.--global
is passed we always install into the global site packages.--global
was passed.--global
was passed.default-install
and if that exists uses--user
or-global
based on it.--user
was passed.--global
was passed.--user
and the user bin isn't on$PATH
.Implementation TODOs:
--root
and such are passed.This is currently untested and is just a first pass but I figured I'd throw it up here for people to see.