-
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
pip should reinstall . #536
Comments
Should the general heuristic be to reinstall local files that are given on the command line? This would keep local files in requirement files from being reinstalled automatically, which may or may not be a good idea, I can't decide. (It should be feasible to determine why something is being installed using |
The heuristic would be local directories passed on the command line. I was developing something without using pip install -e and "my edits don't show up until I edit setup.py with a new version number" was rather surprising. Is there just a way to reinstall one thing without updating all the deps? |
I'm not sure there is, |
I'd personally prefer if |
Perhaps an |
This might be fixed actually; needs someone to test it :) |
Not sure what is fixed/needed fixing ^^
|
'pip install .' should reinstall everytime |
Could you explain why? |
I agree. I can see the logic that you're looking for a workflow of "do some edits / If IMO, you should either use |
(To clarify, I agree with @piotr-dobrogost's question, not with @rbtcollins suggestion...) |
@pfmoore I don't think . needs any special casing. pip supports two means to resolve distributions: by name (where version constraints can be applied) or by location (where they cannot). Location should always reinstall in my opinion, because thats a lot easier to model for users. '.' is just a commonly used location, but the logic applies equally to git+ urls, tarball urls (e.g. vcs exports), and working directories of dependencies. |
@rbtcollins OK, I see what you're saying now. Not sure if I agree (I'll have to think about it) but I see what you're proposing. |
+1 for always reinstall for all local paths and urls. The current behavior is very counterintuitive. |
I agree concerning local directory path or vcs link without specific commit. I'd find it strange to have |
Couldn't/shouldn't pip find out what's the version first (by running |
@piotr-dobrogost developers don't have accurate version information in working trees. |
+1 to @rbtcollins's suggestion too, FWIW. Common situation: a VCS checkout with nominal version "1.2+dev". If I run And then yeah we could try to get fancy and avoid the reinstall in some particular cases, like tarballs-with-embedded-version-numbers (but not other tarballs) or URLs-with-hashes (but not other URLs), but it seems like there are better things to spend our cleverness on -- plus the cleverer we try to be, the more likely we are to introduce subtle bugs and confuse users. "Always reinstall when given a location" is simple and works. |
(I understand from the distutils-sig discussions on new sdist formats that There may be corner cases with the above that you'd prefer to work |
I agree with @pfmoore wrt always installing from a local directory, use typical rules for a tarball. |
I'm not overly fussed about the tarball case, because the working directory case is the one that people are stubbing their toe on everyday and I don't want to hold up fixing it. If we at least have consensus to fix that then we should go ahead and do it. I do think you're all wrong though :-) First, people do actually do
or
and I don't see what we gain by gratuitously breaking them. So that's an obvious case at one end bf of the spectrum. But on further thought, I also disagree about even the most extreme example on the other end. Consider:
I think this should do an install even if lxml==2.3.1 is already installed. If I just went to the trouble of manually downloading and specifying a file by hand, then there are few things more infuriating than some piece of smug, overly confident software chiding me and refusing to follow my explicit instructions. And honestly pip doesn't know better than me here. If I asked to get an installation of |
So, let me try again. Axiomatic: Users have to learn about any hidden behaviours we have. "Lookup by name == trust version; otherwise == always install." -> There is one condition and 3 concepts for users to learn. "Lookup by anything other than local directories == trust version; everything else == always install." is one condition but 4 concepts - its harder. But more importantly, that heuristics is less useful, as @njsmith points out, because tarball exports from VCS systems will also tend to have broken version metadata (assuming they work at all, which many won't). Local build artifacts generated from CI systems will have broken metadata. "It is a file" is not a good indicator for "has good version metadata" |
I'm seeing where both @njsmith and @rbtcollins come from but still treating the exact same file differently on the merit of its origin (downloaded from index or read from local system) seems wrong. Also I do not see the need to go out of the way to make installing something with broken metadata just work when all that is needed in this case is passing flag forcing installation. The original motivation for wanting this was:
As developing without using editable mode is an odd thing to do (there's no information why this was taking place; where there any obstacles to using editable mode?) it's hard to treat this as valid motivation for whatever follows. |
That's exactly not the argument. The argument is that we should respect the user's request: if they typed out the name of a specific file and asked for it to be installed then we should install that file, and the only way we can do that reliably is by, you know, installing it. (Even our metadata standards acknowledge that version comparisons aren't sufficient; they include the (Seriously, when pip does it's "sorry Dave, you already have that installed" routine, then the nasty combination of feeling helpless and patronized at -- by a stupid piece of software no less! -- is so frustrating that it makes it one of the very few cases where my initial impulse is to yell "no fuck YOU FIRST" and dropkick my laptop. It's a pretty visceral reaction. Maybe this kind of feeling is par for the course when dealing with python packaging right now, but I'd really like it if using pip became a pleasant thing that I looked forward to :-/.)
Well, this is somewhere tangential, and I'm in the middle of writing a longer reply to the mailing list thread about why I also dislike editable mode and recommend that no one use it, so... I will just say that the world contains multitudes who use a variety of different workflows, and pip should support them too. And in particular if we think "setup.py install must die" as Nick's bof session said, then pip install needs to be at least as capable as setup.py install. Right now setup.py handles non-editable install workflows just fine (or at least well enough to convince most users that it's working), so if pip doesn't then that's effectively a regression. |
I've been thinking about this more. I think I am on board with the idea that if someone points to a direct location we should install that regardless of what is already installed and the version number should only be used in the resolution algorithm to detect conflicts with other people depending on that thing. |
@dstufft: absolutely!
The issue however is that it is not the exact same file(s) -- it's a file with the same version number. In the use case of an end user installing a package the current behaviour makes sense -- of course it does. And PYPi enforces that you can't upload a fixed/updated package with the same version number. But the other use-case is developers of packages -- and then you really, really, don't want to have to increment your version number with every stinking change. And maybe you are testing/debugging the package installation / building, not just the code, so -e doesn't make sense either. In my case, I build conda packages, but I like use pip to do the actual building, so I get all the proper pipi meta-data -- and during testing/debugging the build process I really do want to re-build teh same version, really I do. And I think as people start to build more complex binary wheels, this will come up more. |
There seems to be consensus that pip should reinstall every time the user does IIUC, the following would not behave differently from today even if this request is implemented.
So, if someone is eager for the always-reinstall behaviour (or want to pin to the current behaviour), you can use one of the above. |
Honestly, I've no idea. I'm OK in principle with the idea of "pip should reinstall every time the user does
Once we're clear on what "should reinstall" actually means, we can debate how corner cases will be handled. Also, to be clear, we're only considering local directories here, so this won't address @njsmith's case from #536 (comment) - is that correct? My personal view is that restricting the change to local directories is correct - as I said above, there are existing explicit options for people wanting this behaviour in other contexts. |
I think it definitely makes sense for local directories, because local directories are likely going to be cases where someone has made modifications and the version number no matter matches reality. Other cases are... more grey. Starting with local directories seems to be a reasonable idea though, and considering other cases as time goes on. and FTR, I think it should mean that we essentially treat it like |
OK, so installing a local directory simply implies Regarding @pradyunsg's other questions:
That works, but why would anyone care? If it was an important use case, we wouldn't be having this discussion anyway. It's a way of getting the current behaviour after the change, I guess...
I have no idea what the point is here. It seems to be trying to get the new behaviour with the current pip, but |
@pfmoore: I think conceptually, We would also want to skip caching wheels in this case; probably we already do but mentioning for completeness. More generally I think it would make sense to apply similar logic to any case where pip's input is not a package-name-plus-version-constraints, and for the same reason. So I should also say I'm totally fine with @dstufft's suggestion to implement this incrementally. |
Here's an alternative conceptual model that I think is equivalent. Right now, if you If you add Now, for something like So far I'm just describing how pip currently works. You can see that there's some kind of prioritization going on because currently if you specify a local directory, then you might be told "name-drop is already installed" (environment beats explicitly specified files), but you'll never see pip go off and install name-version from pypi instead (explicitly specified files beats indexes). So the suggestion here is to swap the priority order, so it goes (1) explicitly specified files, (2) current environment, (3) configured indexes. |
@njsmith OK, so that's an option I hadn't considered (although it's probably what I really meant by my option (3) but hadn't thought it through. @dstufft prefers (1), and I'm mildly in favour of (1). Basically, in my view (1) is simpler to explain, as it introduces no new behaviour, just alters which behaviour applies in this case.
Hmm, I have to say I find this explanation pretty baffling. I'm willing to take your word for it that it's the same as your previous statement, but I wouldn't like to try to explain the proposed behaviour this way to a new user. However, regarding the wheel cache, you're absolutely right that letting any of this near the wheel cache is a big problem. Wheels are essentially required to be uniquely specified by (project name, version). And this new behaviour is explicitly acknowledging that (project name, version) is not sufficient to uniquely identify a wheel. I suspect that there are a number of other ways that people could break the wheel cache, but we'd probably respond with "different wheels with the same name/version aren't supported". This change makes the case of I'm not (quite) changing my mind to oppose this proposal, but I do think we need to carefully think through the implications for the principle "(name, version) uniquely identifies a wheel". (I think it might be possible to rescue the principle by distinguishing between "local" wheels and "published" wheels, but it'll be tricky to formulate the distinction clearly). |
I'm not sure what the practical difference between (1) and (3) is TBH, I'm mostly just opposed to (2). |
Basically, I asked that to figure out how to get the behaviours even if there's a change in pip and the current pip - something that would behave the same regardless; kinda for reference if someone wants those behaviours - in an effort to understand better what's being asked for. |
The wheel cache thing is related, but I think it's separate. It's already true that |
Agreed it's somewhat separate, my concern is that saying "the problem is because you changed the code but left the version the same" may not be an acceptable answer after we make this change (whereas now, while it may not be liked, I think it's the reality). In other words, I'm not sure that at the moment "if they do, it's a bug", as we currently expect (project, version) to uniquely identify a wheel. But either we don't worry about it for now (which may cause problems for users of the change - I'm not one of those so I can't really say) or we thrash out the correct behaviour as part of this change. No big deal either way. |
I'd prefer that but, also, I don't want to be a part of a (possibly long?) discussion right now. Would it be possible to hold out further discussion until someone comes around willing to take this through till implementation? Or is there someone who is willing to right now? |
Agreed, it's an implementation issue. No need to get into details now. |
I just tried |
I've labelled this issue as an "deferred till PR". This label is essentially for indicating that further discussion related to this issue should be deferred until someone comes around to make a PR. This does not mean that the said PR would be accepted - it has not been determined whether this is a useful change to pip and that decision has been deferred until the PR is made. |
I experienced this 'issue' also this week, and in IRC it was suggested I log my experience ITT. We wanted to switch to a different service to prerender our pages for SEO reasons, and this service required a different custom backend for one of our dependancies; django-seo-js==0.3.1 I forked the package to a private repository and went off to get the implementation working, installing it manually into my venv. I figured changing our production requirements.txt to the git uri I installed from locally would be adequate and off it went to the live sites. This caused a few minutes of downtime as the package did not get updated so django crashed trying to call the new custom backend, and it was resolved quickly by uninstalling the dependency on each application server and re-installing from requirements.txt, restarting uwsgi. What would have been better is if I had known that pip determines to install requirements by matching against data in setup.py so I could have changed them in my forked version. Alternatively and as this issue suggests if pip did not keep/match metadata against local caches and instead installed from the URI provided on 'pip install' as I had assumed it would, my issue would have been prevented. Took me a bit of googling and asking around to figure out what combination of --upgrade or --no-cache-dir might have what effects depending on what venv/system pip caches were in what state before I determined what I think is the 'proper' solution, which seems to be eloquently explained here: https://www.python.org/dev/peps/pep-0440/ Anyways just my $.02 |
We have #4764 which would fix this. :) |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
When asked to 'pip install .' it would be nice if pip actually reinstalled it, rather than checking the version number.
The text was updated successfully, but these errors were encountered: