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

Pip does not reinstall with latest setuptools #3874

Closed
ianw opened this issue Jul 25, 2016 · 5 comments
Closed

Pip does not reinstall with latest setuptools #3874

ianw opened this issue Jul 25, 2016 · 5 comments
Labels
auto-locked Outdated issues that have been locked by automation

Comments

@ianw
Copy link
Contributor

ianw commented Jul 25, 2016

  • Pip version: 8.1.2
  • Python version: 2.7
  • Operating System:

Description:

DevStack (OpenStack) has a "libs from git" option where we can choose to install the latest client libraries from a git checkout, rather than using the dependencies from PyPi. This is intended to let us do CI testing with the latest versions of these clients if desired.

Thus what ends up happening is that the clients are installed by pip from pypi during the standard run, and then later we re-install them from a git checkout.

So in the below, I setup a new virtualenv, "pip install python-keystoneclient", then go to a checkout of python-keystone client and "pip install -e" it ... at this point you can see pip thinks that it is installing "3.2.1.dev19" ... but when it is finished, "pip freeze" still reports the old client from PyPi installed.

$ . ./new-setuptools/bin/activate
(new-setuptools)$ pip list
pip (8.1.2)
setuptools (25.0.0)
wheel (0.29.0)
(new-setuptools)$ pip install python-keystoneclient
Collecting python-keystoneclient
  Using cached python_keystoneclient-3.2.0-py2.py3-none-any.whl
... (blah) ...

Installing collected packages: requests, rfc3986, pbr,  ...

(new-setuptools)$ pip freeze
...
pyparsing==2.1.5
python-keystoneclient==3.2.0

(new-setuptools)$ cd ~/programs/python-keystoneclient/

(new-setuptools)$ pip install --upgrade -e .
Obtaining file:///home/iwienand/programs/python-keystoneclient
Requirement already up-to-date: pbr>=1.6 in /tmp/new-setuptools/lib/python2.7/site-packages (from python-keystoneclient==3.2.1.dev19)
Requirement already up-to-date: pyparsing>=2.0.1 in /tmp/new-setuptools/lib/python2.7/site-packages (from oslo.utils>=3.15.0->python-keystoneclient==3.2.1.dev19)
Requirement already up-to-date: monotonic>=0.6 in /tmp/new-setuptools/lib/python2.7/site-packages (from oslo.utils>=3.15.0->python-keystoneclient==3.2.1.dev19)
...
Installing collected packages: python-keystoneclient
  Running setup.py develop for python-keystoneclient
Successfully installed python-keystoneclient-3.2.0

(new-setuptools)$ pip freeze
...
python-keystoneclient==3.2.0
...

I'll avoid it in here for brevity, but you can see in http://paste.openstack.org/show/541509/ where I do the same thing but downgrade setuptools to <25 before, and we get the library installed from the checkout after the "pip -e" install

The suspicious setuptools change is pypa/setuptools@e211f45 but this is talking about easy-install.pth which I'm not sure is related? Investigations continuing...

@ianw
Copy link
Contributor Author

ianw commented Jul 25, 2016

Let me just add a new comment, after investigation. Maybe this is obvious to those who follow this closely, but for others ...

The issue is pypa/setuptools@e211f45

When you install with "pip install -e" (i.e. "python setup.py develop") a /usr/lib/python2.7/site-packages/easy-install.pth file is generated. Before setuptools 25.0 this would do some magic and insert the new directory first in sys.path [1]. i.e., a package installed with "pip install -e" would be picked up before any package installed via regular pip, or system-packages (i.e. the "rewite" method).

After [1], the directory is simply listed in easy-install.pth (i.e. the "raw" method) which means that it just gets inserted at the back of sys.path, and the installed package overwrites it.

In the original pull request [2] it says

Since nobody should be using easy_install (or even python setup.py install, as I understand it), I think the only entries in easy-install.pth should be the result of pip install -e. It seems that the only difference in behavior between pip install and pip install -e should be that they are 'symlinked' (via .pth), and not a wildly different import priority.

Pip doesn't really say anthing about "-e" other than it's "setuptools develop mode". I don't think it explicitly states this in the documentation for development mode [3] but it seems very odd that if I'm deploying a later version from my checkout tree, with --upgrade even, that I will still by default end up importing the old packaged version after this command.

I feel like the usual workflow is something like "pip install -e abc (drags in xyz) ... hack abc ... oops this is a bug in xyz ... pull the xyz git tree ... "pip install -e ." ... hack bug in xyz ... rerun abc tests"

Now you have to take the rather unintuitive step of removing "xyz" before installing it. And if you don't, nothing will warn you or alert you that, actually, you're still using the packaged version of "xyz". You will probably figure this out if you're directly hacking on xyz as in this scenario and your changes don't apply...

Silence is frustrating for interactive use, but very bad for CI. For example, luckily we check in devstack that we are actually using the installs from git we think we are, because we've had problems in this area before -- that flagged this issue. If we didn't, then all CI would still be passing and everyone thinks they're testing their clients from the git tree, but really they're just checking against the latest release because it was installed first! It's not until maybe months later when you cut your new release you realise the "pip install -e" wasn't doing anything all along.

POLS would suggest that pip should probably uninstall the previous package, or otherwise take on the standard upgrade action that removes the old version before doing the "setup develop" so that only the development mode install is available.

[1] https://bitbucket.org/minrk/setuptools/commits/ff7ed172b054c0e598a3aaa77c6b9f1b68a7f158?at=default
[2] https://bitbucket.org/pypa/setuptools/pull-requests/135/remove-import-sys-from-easy-installpth/diff
[3] http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode

@jaraco
Copy link
Member

jaraco commented Jul 25, 2016

Thanks @ianw for the detailed research on this issue. Note that there is a short-term workaround to set SETUPTOOLS_SYS_PATH_TECHNIQUE=rewrite and it will behave the way it always has... but the intention is to deprecate that behavior, once issues like this one have a clear solution. Setuptools will also consider reverting this new behavior and simply using rewrite in all scenarios, but only if that's what the PyPA decides is best.

@dstufft
Copy link
Member

dstufft commented Jul 25, 2016

Presumably pip could uninstall what is already there when doing an editable install too.

ianw added a commit to ianw/pip that referenced this issue Jul 26, 2016
setuptools has changed its default behaviour whe installing packages
installed in "develop mode" (i.e. pip -e) from being inserted first in
sys.path to being added last (for details, see the bug).

This means that if "pip install -e" a git tree to work on something
but have the original package installed from PyPi (etc.), you will not
actually be importing the development version.  During interactive
development you'll probably notice that your changes aren't applying
and start digging around, but this behaviour change could be very bad
in a CI situation where you *think* you've installed a development
version but really, with setuptools>=25, you're just testing the
release version.

This change removes an existing install before deploying in develop
mode.  This way we only have one copy of the package and avoid
ordering issues.  A new test is added.

Fixes pypa#3874
@piotr-dobrogost
Copy link

piotr-dobrogost commented Jul 26, 2016

Compare with issue #1548 and pull #1552. Also issue #1662.

@xavfernandez
Copy link
Member

Should be fixed by #3898

@lock lock bot added the auto-locked Outdated issues that have been locked by automation label Jun 4, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Jun 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
auto-locked Outdated issues that have been locked by automation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants