mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Remove the workarounds/hacks to handle distribute -> setuptools
This commit is contained in:
parent
695e6925d7
commit
18064e7017
6 changed files with 37 additions and 219 deletions
|
@ -39,6 +39,12 @@
|
|||
* Improve logging when a requirement marker doesn't match your environment
|
||||
(:pull:`2735`)
|
||||
|
||||
* Removed the temporary modifications (that began in pip v1.4 when distribute
|
||||
and setuptools merged) that allowed distribute to be considered a conflict to
|
||||
setuptools. ``pip install -U setuptools`` will no longer upgrade "distribute"
|
||||
to "setuptools". Instead, use ``pip install -U distribute`` (:pull:`2767`).
|
||||
|
||||
|
||||
**6.1.1 (2015-04-07)**
|
||||
|
||||
* No longer ignore dependencies which have been added to the standard library,
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
:orphan:
|
||||
|
||||
"ImportError: No module named setuptools"
|
||||
+++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Although using ``pip install --upgrade setuptools`` to upgrade from distribute
|
||||
to setuptools works in isolation, it's possible to get "ImportError: No module
|
||||
named setuptools" when using pip<1.4 to upgrade a package that depends on
|
||||
setuptools or distribute.
|
||||
|
||||
e.g. when running a command like this: `pip install --upgrade pyramid`
|
||||
|
||||
Solution
|
||||
~~~~~~~~
|
||||
|
||||
To prevent the problem in *new* environments (that aren't broken yet):
|
||||
|
||||
* Option 1:
|
||||
|
||||
* *First* run `pip install -U setuptools`,
|
||||
* *Then* run the command to upgrade your package (e.g. `pip install --upgrade pyramid`)
|
||||
|
||||
* Option 2:
|
||||
|
||||
* Upgrade pip using :ref:`get-pip <get-pip>`
|
||||
* *Then* run the command to upgrade your package (e.g. `pip install --upgrade pyramid`)
|
||||
|
||||
To fix the problem once it's occurred, you'll need to manually install the new
|
||||
setuptools, then rerun the upgrade that failed.
|
||||
|
||||
1. Download `ez_setup.py` (https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py)
|
||||
2. Run `python ez_setup.py`
|
||||
3. Then rerun your upgrade (e.g. `pip install --upgrade pyramid`)
|
||||
|
||||
|
||||
Cause
|
||||
~~~~~
|
||||
|
||||
distribute-0.7.3 is just an empty wrapper that only serves to require the new
|
||||
setuptools (setuptools>=0.7) so that it will be installed. (If you don't know
|
||||
yet, the "new setuptools" is a merge of distribute and setuptools back into one
|
||||
project).
|
||||
|
||||
distribute-0.7.3 does its job well, when the upgrade is done in isolation.
|
||||
E.g. if you're currently on distribute-0.6.X, then running `pip install -U
|
||||
setuptools` works fine to upgrade you to setuptools>=0.7.
|
||||
|
||||
The problem occurs when:
|
||||
|
||||
1. you are currently using an older distribute (i.e. 0.6.X)
|
||||
2. and you try to use pip to upgrade a package that *depends* on setuptools or
|
||||
distribute.
|
||||
|
||||
As part of the upgrade process, pip builds an install list that ends up
|
||||
including distribute-0.7.3 and setuptools>=0.7 , but they can end up being
|
||||
separated by other dependencies in the list, so what can happen is this:
|
||||
|
||||
1. pip uninstalls the existing distribute
|
||||
2. pip installs distribute-0.7.3 (which has no importable setuptools, that pip
|
||||
*needs* internally to function)
|
||||
3. pip moves on to install another dependency (before setuptools>=0.7) and is
|
||||
unable to proceed without the setuptools package
|
||||
|
||||
Note that pip v1.4 has fixes to prevent this. distribute-0.7.3 (or
|
||||
setuptools>=0.7) by themselves cannot prevent this kind of problem.
|
||||
|
||||
|
||||
.. _setuptools: https://pypi.python.org/pypi/setuptools
|
||||
.. _distribute: https://pypi.python.org/pypi/distribute
|
|
@ -33,11 +33,10 @@ Then run the following (which may require administrator access):
|
|||
|
||||
python get-pip.py
|
||||
|
||||
If `setuptools`_ (or `distribute`_) is not already installed, ``get-pip.py`` will
|
||||
install `setuptools`_ for you. [3]_
|
||||
If `setuptools`_ is not already installed, ``get-pip.py`` will install
|
||||
`setuptools`_ for you. [3]_
|
||||
|
||||
To upgrade an existing `setuptools`_ (or `distribute`_), run ``pip install -U
|
||||
setuptools``. [4]_
|
||||
To upgrade an existing `setuptools`_, run ``pip install -U setuptools``.
|
||||
|
||||
Additionally, ``get-pip.py`` supports using the :ref:`pip install options <pip
|
||||
install Options>` and the :ref:`general options <General Options>`. Below are
|
||||
|
@ -47,7 +46,7 @@ Install from local copies of pip and setuptools::
|
|||
|
||||
python get-pip.py --no-index --find-links=/local/copies
|
||||
|
||||
Install to the user site [5]_::
|
||||
Install to the user site [4]_::
|
||||
|
||||
python get-pip.py --user
|
||||
|
||||
|
@ -66,7 +65,7 @@ On Linux or OS X:
|
|||
pip install -U pip
|
||||
|
||||
|
||||
On Windows [6]_:
|
||||
On Windows [5]_:
|
||||
|
||||
::
|
||||
|
||||
|
@ -101,19 +100,13 @@ On Fedora::
|
|||
.. [3] Beginning with pip v1.5.1, ``get-pip.py`` stopped requiring setuptools to
|
||||
be installed first.
|
||||
|
||||
.. [4] Although using ``pip install --upgrade setuptools`` to upgrade from
|
||||
distribute to setuptools works in isolation, it's possible to get
|
||||
"ImportError: No module named setuptools" when using pip<1.4 to upgrade a
|
||||
package that depends on setuptools or distribute. See :doc:`here for
|
||||
details <distribute_setuptools>`.
|
||||
|
||||
.. [5] The pip developers are considering making ``--user`` the default for all
|
||||
.. [4] The pip developers are considering making ``--user`` the default for all
|
||||
installs, including ``get-pip.py`` installs of pip, but at this time,
|
||||
``--user`` installs for pip itself, should not be considered to be fully
|
||||
tested or endorsed. For discussion, see `Issue 1668
|
||||
<https://github.com/pypa/pip/issues/1668>`_.
|
||||
|
||||
.. [6] https://github.com/pypa/pip/issues/1299
|
||||
.. [5] https://github.com/pypa/pip/issues/1299
|
||||
|
||||
.. _setuptools: https://pypi.python.org/pypi/setuptools
|
||||
.. _distribute: https://pypi.python.org/pypi/distribute
|
||||
|
|
|
@ -378,18 +378,6 @@ class InstallRequirement(object):
|
|||
)
|
||||
|
||||
with indent_log():
|
||||
# if it's distribute>=0.7, it won't contain an importable
|
||||
# setuptools, and having an egg-info dir blocks the ability of
|
||||
# setup.py to find setuptools plugins, so delete the egg-info dir
|
||||
# if no setuptools. it will get recreated by the run of egg_info
|
||||
# NOTE: this self.name check only works when installing from a
|
||||
# specifier (not archive path/urls)
|
||||
# TODO: take this out later
|
||||
if (self.name == 'distribute' and not
|
||||
os.path.isdir(
|
||||
os.path.join(self.source_dir, 'setuptools'))):
|
||||
rmtree(os.path.join(self.source_dir, 'distribute.egg-info'))
|
||||
|
||||
script = self._run_setup_py
|
||||
script = script.replace('__SETUP_PY__', repr(self.setup_py))
|
||||
script = script.replace('__PKG_NAME__', repr(self.name))
|
||||
|
@ -989,17 +977,7 @@ exec(compile(
|
|||
if self.req is None:
|
||||
return False
|
||||
try:
|
||||
# DISTRIBUTE TO SETUPTOOLS UPGRADE HACK (1 of 3 parts)
|
||||
# if we've already set distribute as a conflict to setuptools
|
||||
# then this check has already run before. we don't want it to
|
||||
# run again, and return False, since it would block the uninstall
|
||||
# TODO: remove this later
|
||||
if (self.req.project_name == 'setuptools' and
|
||||
self.conflicts_with and
|
||||
self.conflicts_with.project_name == 'distribute'):
|
||||
return True
|
||||
else:
|
||||
self.satisfied_by = pkg_resources.get_distribution(self.req)
|
||||
self.satisfied_by = pkg_resources.get_distribution(self.req)
|
||||
except pkg_resources.DistributionNotFound:
|
||||
return False
|
||||
except pkg_resources.VersionConflict:
|
||||
|
|
|
@ -599,20 +599,6 @@ class RequirementSet(object):
|
|||
"""
|
||||
to_install = self._to_install()
|
||||
|
||||
# DISTRIBUTE TO SETUPTOOLS UPGRADE HACK (1 of 3 parts)
|
||||
# move the distribute-0.7.X wrapper to the end because it does not
|
||||
# install a setuptools package. by moving it to the end, we ensure it's
|
||||
# setuptools dependency is handled first, which will provide the
|
||||
# setuptools package
|
||||
# TODO: take this out later
|
||||
distribute_req = pkg_resources.Requirement.parse("distribute>=0.7")
|
||||
for req in to_install:
|
||||
if (req.name == 'distribute' and
|
||||
req.installed_version is not None and
|
||||
req.installed_version in distribute_req):
|
||||
to_install.remove(req)
|
||||
to_install.append(req)
|
||||
|
||||
if to_install:
|
||||
logger.info(
|
||||
'Installing collected packages: %s',
|
||||
|
@ -621,33 +607,6 @@ class RequirementSet(object):
|
|||
|
||||
with indent_log():
|
||||
for requirement in to_install:
|
||||
|
||||
# DISTRIBUTE TO SETUPTOOLS UPGRADE HACK (1 of 3 parts)
|
||||
# when upgrading from distribute-0.6.X to the new merged
|
||||
# setuptools in py2, we need to force setuptools to uninstall
|
||||
# distribute. In py3, which is always using distribute, this
|
||||
# conversion is already happening in distribute's
|
||||
# pkg_resources. It's ok *not* to check if setuptools>=0.7
|
||||
# because if someone were actually trying to ugrade from
|
||||
# distribute to setuptools 0.6.X, then all this could do is
|
||||
# actually help, although that upgade path was certainly never
|
||||
# "supported"
|
||||
# TODO: remove this later
|
||||
if requirement.name == 'setuptools':
|
||||
try:
|
||||
# only uninstall distribute<0.7. For >=0.7, setuptools
|
||||
# will also be present, and that's what we need to
|
||||
# uninstall
|
||||
distribute_requirement = \
|
||||
pkg_resources.Requirement.parse("distribute<0.7")
|
||||
existing_distribute = \
|
||||
pkg_resources.get_distribution("distribute")
|
||||
if existing_distribute in distribute_requirement:
|
||||
requirement.conflicts_with = existing_distribute
|
||||
except pkg_resources.DistributionNotFound:
|
||||
# distribute wasn't installed, so nothing to do
|
||||
pass
|
||||
|
||||
if requirement.conflicts_with:
|
||||
logger.info(
|
||||
'Found existing installation: %s',
|
||||
|
|
|
@ -298,12 +298,27 @@ def test_upgrade_vcs_req_with_dist_found(script):
|
|||
assert "pypi.python.org" not in result.stdout, result.stdout
|
||||
|
||||
|
||||
class TestUpgradeSetuptools(object):
|
||||
class TestUpgradeDistributeToSetuptools(object):
|
||||
"""
|
||||
Tests for upgrading to setuptools (using pip from src tree)
|
||||
The tests use a *fixed* set of packages from our test packages dir
|
||||
note: virtualenv-1.9.1 contains distribute-0.6.34
|
||||
note: virtualenv-1.10 contains setuptools-0.9.7
|
||||
From pip1.4 to pip6, pip supported a set of "hacks" (see Issue #1122) to
|
||||
allow distribute to conflict with setuptools, so that the following would
|
||||
work to upgrade distribute:
|
||||
|
||||
``pip install -U setuptools``
|
||||
|
||||
In pip7, the hacks were removed. This test remains to at least confirm pip
|
||||
can upgrade distribute to setuptools using:
|
||||
|
||||
``pip install -U distribute``
|
||||
|
||||
The reason this works is that a final version of distribute (v0.7.3) was
|
||||
released that is simple wrapper with:
|
||||
|
||||
install_requires=['setuptools>=0.7']
|
||||
|
||||
The test use a fixed set of packages from our test packages dir. Note that
|
||||
virtualenv-1.9.1 contains distribute-0.6.34 and virtualenv-1.10 contains
|
||||
setuptools-0.9.7
|
||||
"""
|
||||
|
||||
def prep_ve(self, script, version, pip_src, distribute=False):
|
||||
|
@ -328,82 +343,18 @@ class TestUpgradeSetuptools(object):
|
|||
expect_stderr=True,
|
||||
)
|
||||
|
||||
@pytest.mark.skipif("sys.version_info >= (3,0)")
|
||||
def test_py2_from_setuptools_6_to_setuptools_7(
|
||||
self, script, data, virtualenv):
|
||||
self.prep_ve(script, '1.9.1', virtualenv.pip_source_dir)
|
||||
result = self.script.run(
|
||||
self.ve_bin / 'pip', 'install', '--no-binary=:all:', '--no-index',
|
||||
'--find-links=%s' % data.find_links, '-U', 'setuptools'
|
||||
)
|
||||
assert (
|
||||
"Found existing installation: setuptools 0.6rc11" in result.stdout
|
||||
)
|
||||
result = self.script.run(self.ve_bin / 'pip', 'list')
|
||||
assert "setuptools (0.9.8)" in result.stdout
|
||||
|
||||
def test_py2_py3_from_distribute_6_to_setuptools_7(
|
||||
def test_from_distribute_6_to_setuptools_7(
|
||||
self, script, data, virtualenv):
|
||||
self.prep_ve(
|
||||
script, '1.9.1', virtualenv.pip_source_dir, distribute=True
|
||||
)
|
||||
result = self.script.run(
|
||||
self.ve_bin / 'pip', 'install', '--no-index',
|
||||
'--find-links=%s' % data.find_links, '-U', 'setuptools'
|
||||
'--find-links=%s' % data.find_links, '-U', 'distribute'
|
||||
)
|
||||
assert (
|
||||
"Found existing installation: distribute 0.6.34" in result.stdout
|
||||
)
|
||||
result = self.script.run(self.ve_bin / 'pip', 'list')
|
||||
assert "setuptools (0.9.8)" in result.stdout
|
||||
assert "distribute (0.7.3)" not in result.stdout
|
||||
|
||||
def test_from_setuptools_7_to_setuptools_7(self, script, data, virtualenv):
|
||||
self.prep_ve(script, '1.10', virtualenv.pip_source_dir)
|
||||
result = self.script.run(
|
||||
self.ve_bin / 'pip', 'install', '--no-index',
|
||||
'--find-links=%s' % data.find_links, '-U', 'setuptools'
|
||||
)
|
||||
assert "Found existing installation: setuptools 0.9.7" in result.stdout
|
||||
result = self.script.run(self.ve_bin / 'pip', 'list')
|
||||
assert "setuptools (0.9.8)" in result.stdout
|
||||
|
||||
def test_from_setuptools_7_to_setuptools_7_using_wheel(
|
||||
self, script, data, virtualenv):
|
||||
self.prep_ve(script, '1.10', virtualenv.pip_source_dir)
|
||||
result = self.script.run(
|
||||
self.ve_bin / 'pip', 'install', '--no-index',
|
||||
'--find-links=%s' % data.find_links, '-U', 'setuptools'
|
||||
)
|
||||
assert "Found existing installation: setuptools 0.9.7" in result.stdout
|
||||
# only wheels use dist-info
|
||||
assert 'setuptools-0.9.8.dist-info' in str(result.files_created)
|
||||
result = self.script.run(self.ve_bin / 'pip', 'list')
|
||||
assert "setuptools (0.9.8)" in result.stdout
|
||||
|
||||
# disabling intermittent travis failure:
|
||||
# https://github.com/pypa/pip/issues/1379
|
||||
@pytest.mark.skipif("hasattr(sys, 'pypy_version_info')")
|
||||
def test_from_setuptools_7_to_setuptools_7_with_distribute_7_installed(
|
||||
self, script, data, virtualenv):
|
||||
self.prep_ve(
|
||||
script, '1.9.1', virtualenv.pip_source_dir, distribute=True
|
||||
)
|
||||
result = self.script.run(
|
||||
self.ve_bin / 'pip', 'install', '--no-index',
|
||||
'--find-links=%s' % data.find_links, '-U', 'setuptools'
|
||||
)
|
||||
result = self.script.run(
|
||||
self.ve_bin / 'pip', 'install', '--no-index',
|
||||
'--find-links=%s' % data.find_links, 'setuptools==0.9.6'
|
||||
)
|
||||
result = self.script.run(self.ve_bin / 'pip', 'list')
|
||||
assert "setuptools (0.9.6)" in result.stdout
|
||||
assert "distribute (0.7.3)" not in result.stdout
|
||||
result = self.script.run(
|
||||
self.ve_bin / 'pip', 'install', '--no-index',
|
||||
'--find-links=%s' % data.find_links, '-U', 'setuptools'
|
||||
)
|
||||
assert "Found existing installation: setuptools 0.9.6" in result.stdout
|
||||
result = self.script.run(self.ve_bin / 'pip', 'list')
|
||||
assert "setuptools (0.9.8)" in result.stdout
|
||||
assert "distribute (0.7.3)" in result.stdout
|
||||
|
|
Loading…
Reference in a new issue