diff --git a/pip/req/req_install.py b/pip/req/req_install.py index 27a11f76995..6ec2a429072 100644 --- a/pip/req/req_install.py +++ b/pip/req/req_install.py @@ -130,19 +130,15 @@ def from_line(cls, name, comes_from=None, prereleases=None): ) link = Link(path_to_url(name)) - # If the line has an egg= definition, but isn't editable, pull the - # requirement out. Otherwise, assume the name is the req for the non - # URL/path/archive case. - if link and req is None: - url = link.url_without_fragment - # when fragment is None, this will become an 'unnamed' requirement - req = link.egg_fragment + # it's a local file, dir, or url + if link: + url = link.url_without_fragment # Handle relative file URLs if link.scheme == 'file' and re.search(r'\.\./', url): url = path_to_url(os.path.normpath(os.path.abspath(link.path))) - # fail early for invalid or unsupported wheels + # wheel file if link.ext == wheel_ext: wheel = Wheel(link.filename) # can raise InvalidWheelFilename if not wheel.supported(): @@ -150,7 +146,13 @@ def from_line(cls, name, comes_from=None, prereleases=None): "%s is not a supported wheel on this platform." % wheel.filename ) + req = "%s==%s" % (wheel.name, wheel.version) + else: + # set the req to the egg fragment. when it's not there, this + # will become an 'unnamed' requirement + req = link.egg_fragment + # a requirement specifier else: req = name diff --git a/tests/data/packages/simplewheel-1.0-py2.py3-none-any.whl b/tests/data/packages/simplewheel-1.0-py2.py3-none-any.whl new file mode 100644 index 00000000000..0e6b91eea85 Binary files /dev/null and b/tests/data/packages/simplewheel-1.0-py2.py3-none-any.whl differ diff --git a/tests/data/packages/simplewheel-2.0-py2.py3-none-any.whl b/tests/data/packages/simplewheel-2.0-py2.py3-none-any.whl new file mode 100644 index 00000000000..acf0c56cfd9 Binary files /dev/null and b/tests/data/packages/simplewheel-2.0-py2.py3-none-any.whl differ diff --git a/tests/data/src/simplewheel-1.0/setup.cfg b/tests/data/src/simplewheel-1.0/setup.cfg new file mode 100644 index 00000000000..861a9f55426 --- /dev/null +++ b/tests/data/src/simplewheel-1.0/setup.cfg @@ -0,0 +1,5 @@ +[egg_info] +tag_build = +tag_date = 0 +tag_svn_revision = 0 + diff --git a/tests/data/src/simplewheel-1.0/setup.py b/tests/data/src/simplewheel-1.0/setup.py new file mode 100644 index 00000000000..97a2210f0a1 --- /dev/null +++ b/tests/data/src/simplewheel-1.0/setup.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python +from setuptools import setup, find_packages + +setup(name='simplewheel', + version='1.0', + packages=find_packages() + ) diff --git a/tests/data/src/simplewheel-1.0/simple/__init__.py b/tests/data/src/simplewheel-1.0/simple/__init__.py new file mode 100644 index 00000000000..7986d11379a --- /dev/null +++ b/tests/data/src/simplewheel-1.0/simple/__init__.py @@ -0,0 +1 @@ +#dummy diff --git a/tests/data/src/simplewheel-2.0/setup.cfg b/tests/data/src/simplewheel-2.0/setup.cfg new file mode 100644 index 00000000000..861a9f55426 --- /dev/null +++ b/tests/data/src/simplewheel-2.0/setup.cfg @@ -0,0 +1,5 @@ +[egg_info] +tag_build = +tag_date = 0 +tag_svn_revision = 0 + diff --git a/tests/data/src/simplewheel-2.0/setup.py b/tests/data/src/simplewheel-2.0/setup.py new file mode 100644 index 00000000000..f2b31f6af93 --- /dev/null +++ b/tests/data/src/simplewheel-2.0/setup.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python +from setuptools import setup, find_packages + +setup(name='simplewheel', + version='2.0', + packages=find_packages() + ) diff --git a/tests/data/src/simplewheel-2.0/simple/__init__.py b/tests/data/src/simplewheel-2.0/simple/__init__.py new file mode 100644 index 00000000000..7986d11379a --- /dev/null +++ b/tests/data/src/simplewheel-2.0/simple/__init__.py @@ -0,0 +1 @@ +#dummy diff --git a/tests/functional/test_install_wheel.py b/tests/functional/test_install_wheel.py index ac9f7b7c690..6f1bd378fa3 100644 --- a/tests/functional/test_install_wheel.py +++ b/tests/functional/test_install_wheel.py @@ -302,3 +302,15 @@ def test_wheel_no_compiles_pyc(script, data): ) assert not any(exists) + + +def test_install_from_wheel_uninstalls_old_version(script, data): + # regression test for https://github.com/pypa/pip/issues/1825 + package = data.packages.join("simplewheel-1.0-py2.py3-none-any.whl") + result = script.pip('install', package, '--no-index', expect_error=True) + package = data.packages.join("simplewheel-2.0-py2.py3-none-any.whl") + result = script.pip('install', package, '--no-index', expect_error=False) + dist_info_folder = script.site_packages / 'simplewheel-2.0.dist-info' + assert dist_info_folder in result.files_created + dist_info_folder = script.site_packages / 'simplewheel-1.0.dist-info' + assert dist_info_folder not in result.files_created diff --git a/tests/unit/test_req.py b/tests/unit/test_req.py index a44e98bc47b..169fb13b8c4 100644 --- a/tests/unit/test_req.py +++ b/tests/unit/test_req.py @@ -8,6 +8,7 @@ from pip.exceptions import ( PreviousBuildDirError, InvalidWheelFilename, UnsupportedWheel, ) +from pip._vendor import pkg_resources from pip.download import PipSession from pip.index import PackageFinder from pip.log import logger @@ -90,6 +91,10 @@ def test_invalid_wheel_requirement_raises(self): with pytest.raises(InvalidWheelFilename): InstallRequirement.from_line('invalid.whl') + def test_wheel_requirement_sets_req_attribute(self): + req = InstallRequirement.from_line('simple-0.1-py2.py3-none-any.whl') + assert req.req == pkg_resources.Requirement.parse('simple==0.1') + def test_requirements_data_structure_keeps_order(): requirements = Requirements()