mirror of https://github.com/pypa/pip
Ensure wheel-Version is compatible with pip
This commit is contained in:
parent
19ef5973cd
commit
13f6c68f0c
|
@ -710,6 +710,17 @@ exec(compile(
|
|||
self.install_editable(install_options, global_options)
|
||||
return
|
||||
if self.is_wheel:
|
||||
wheel_version = pip.wheel.wheel_version(self.source_dir)
|
||||
if ((not wheel_version) or
|
||||
(wheel_version[0] > pip.wheel.VERSION_COMPATIBLE[0])):
|
||||
raise UnsupportedWheel(
|
||||
"%s's wheel version is not compatible with this version "
|
||||
"of pip" % self.name
|
||||
)
|
||||
elif (wheel_version[0] == pip.wheel.VERSION_COMPATIBLE[0] and
|
||||
wheel_version > pip.wheel.VERSION_COMPATIBLE):
|
||||
logger.warn('Installing a newer Wheel-Version: %s'
|
||||
% '.'.join(map(str, wheel_version)))
|
||||
self.move_wheel_files(self.source_dir, root=root)
|
||||
self.install_succeeded = True
|
||||
return
|
||||
|
|
34
pip/wheel.py
34
pip/wheel.py
|
@ -21,9 +21,14 @@ from pip.log import logger
|
|||
from pip import pep425tags
|
||||
from pip.util import call_subprocess, normalize_path, make_path_relative
|
||||
from pip._vendor.distlib.scripts import ScriptMaker
|
||||
from pip._vendor.pkg_resources import (
|
||||
Distribution, FileMetadata, PathMetadata
|
||||
)
|
||||
|
||||
wheel_ext = '.whl'
|
||||
|
||||
VERSION_COMPATIBLE = (1, 0)
|
||||
|
||||
|
||||
def rehash(path, algo='sha256', blocksize=1 << 20):
|
||||
"""Return (hash, length) for path using hashlib.new(algo)"""
|
||||
|
@ -392,6 +397,35 @@ def uninstallation_paths(dist):
|
|||
yield path
|
||||
|
||||
|
||||
def wheel_version(source_dir):
|
||||
"""
|
||||
Return the Wheel-Version of an extracted wheel, if possible.
|
||||
|
||||
Otherwise, return False if we couldn't parse / extract it.
|
||||
"""
|
||||
wheel_version_re = "Wheel-Version:(?P<version>.+)\n"
|
||||
try:
|
||||
entries = [e for e in os.listdir(source_dir)
|
||||
if e.lower().endswith('.dist-info')]
|
||||
entry = entries[0]
|
||||
fullpath = os.path.join(source_dir, entry)
|
||||
if os.path.isdir(fullpath):
|
||||
# egg-info directory, allow getting metadata
|
||||
metadata = PathMetadata(source_dir, fullpath)
|
||||
else:
|
||||
metadata = FileMetadata(fullpath)
|
||||
dist = Distribution.from_location(
|
||||
source_dir, entry, metadata
|
||||
)
|
||||
wheel_data = dist.get_metadata('WHEEL')
|
||||
match = re.search(wheel_version_re, wheel_data)
|
||||
version = match.group('version').strip()
|
||||
version = tuple(map(int, version.split('.')))
|
||||
return version
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
class Wheel(object):
|
||||
"""A wheel file"""
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@ FSPkg
|
|||
-----
|
||||
for installing from the file system
|
||||
|
||||
futurewheel
|
||||
-----------
|
||||
Wheels of a Wheel-Version that is newer in minor and major series.
|
||||
|
||||
gmpy-1.15.tar.gz
|
||||
----------------
|
||||
hash testing (although this pkg isn't needed explicitly)
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -5,6 +5,27 @@ import glob
|
|||
from tests.lib.path import Path
|
||||
|
||||
|
||||
def test_install_from_future_wheel_version(script, data):
|
||||
"""
|
||||
Test installing a future wheel (minor series)
|
||||
"""
|
||||
package = data.packages.join("futurewheel-1.9-py2.py3-none-any.whl")
|
||||
result = script.pip('install', package, '--no-index', expect_error=False)
|
||||
# TODO: test that warning is produced
|
||||
package = data.packages.join("futurewheel-3.0-py2.py3-none-any.whl")
|
||||
result = script.pip('install', package, '--no-index', expect_error=True)
|
||||
# TODO: test that package didn't install, anything else necessary?
|
||||
|
||||
|
||||
def test_install_from_broken_wheel(script, data):
|
||||
"""
|
||||
Test installing a future wheel (minor series)
|
||||
"""
|
||||
package = data.packages.join("brokenwheel-1.0-py2.py3-none-any.whl")
|
||||
result = script.pip('install', package, '--no-index', expect_error=True)
|
||||
# TODO: test that package didn't install, anything else necessary?
|
||||
|
||||
|
||||
def test_install_from_wheel(script, data):
|
||||
"""
|
||||
Test installing from a wheel (that has a script)
|
||||
|
|
|
@ -4,6 +4,7 @@ import pytest
|
|||
from mock import patch
|
||||
from pip import wheel
|
||||
from pip.exceptions import InvalidWheelFilename
|
||||
from pip.util import unpack_file
|
||||
|
||||
|
||||
def test_get_entrypoints(tmpdir):
|
||||
|
@ -46,6 +47,20 @@ def test_uninstallation_paths():
|
|||
assert paths2 == paths
|
||||
|
||||
|
||||
def test_version_compatible(tmpdir, data):
|
||||
future_wheel = 'futurewheel-1.9-py2.py3-none-any.whl'
|
||||
broken_wheel = 'brokenwheel-1.0-py2.py3-none-any.whl'
|
||||
future_version = (1, 9)
|
||||
|
||||
unpack_file(data.packages.join(future_wheel),
|
||||
tmpdir + 'future', None, None)
|
||||
unpack_file(data.packages.join(broken_wheel),
|
||||
tmpdir + 'broken', None, None)
|
||||
|
||||
assert wheel.wheel_version(tmpdir + 'future') == future_version
|
||||
assert not wheel.wheel_version(tmpdir + 'broken')
|
||||
|
||||
|
||||
class TestWheelFile(object):
|
||||
|
||||
def test_std_wheel_pattern(self):
|
||||
|
|
Loading…
Reference in New Issue