1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

Preliminary manylinux2 support.

This commit is contained in:
Mark Williams 2018-01-28 22:06:21 -08:00 committed by William T Olson
parent d67d98dd91
commit fde4a826b9
4 changed files with 161 additions and 58 deletions

View file

@ -157,6 +157,23 @@ def is_manylinux1_compatible():
return pip._internal.utils.glibc.have_compatible_glibc(2, 5)
def is_manylinux2_compatible():
# Only Linux, and only x86-64 / i686
if get_platform() not in {"linux_x86_64", "linux_i686"}:
return False
# Check for presence of _manylinux module
try:
import _manylinux
return bool(_manylinux.manylinux2_compatible)
except (ImportError, AttributeError):
# Fall through to heuristic check below
pass
# Check glibc version. CentOS 6 uses glibc 2.12.
return pip._internal.utils.glibc.have_compatible_glibc(2, 12)
def get_darwin_arches(major, minor, machine):
"""Return a list of supported arches (including group arches) for
the given major, minor and machine architecture of an macOS machine.
@ -276,8 +293,16 @@ def get_supported(versions=None, noarch=False, platform=None,
else:
# arch pattern didn't match (?!)
arches = [arch]
elif platform is None and is_manylinux1_compatible():
arches = [arch.replace('linux', 'manylinux1'), arch]
elif arch.startswith('manylinux2'):
# manylinux1 wheels run on manylinux2 systems.
arches = [arch, arch.replace('manylinux2', 'manylinux1')]
elif platform is None:
arches = []
if is_manylinux2_compatible():
arches.append(arch.replace('linux', 'manylinux2'))
if is_manylinux1_compatible():
arches.append(arch.replace('linux', 'manylinux1'))
arches.append(arch)
else:
arches = [arch]

View file

@ -322,54 +322,71 @@ def test_download_specify_platform(script, data):
)
def test_download_platform_manylinux(script, data):
class TestDownloadPlatformManylinuxes(object):
"""
Test using "pip download --platform" to download a .whl archive
supported for a specific platform.
"pip download --platform" downloads a .whl archive supported for
manylinux platforms.
"""
fake_wheel(data, 'fake-1.0-py2.py3-none-any.whl')
# Confirm that universal wheels are returned even for specific
# platforms.
result = script.pip(
'download', '--no-index', '--find-links', data.find_links,
'--only-binary=:all:',
'--dest', '.',
'--platform', 'linux_x86_64',
'fake',
)
assert (
Path('scratch') / 'fake-1.0-py2.py3-none-any.whl'
in result.files_created
)
data.reset()
fake_wheel(data, 'fake-1.0-py2.py3-none-manylinux1_x86_64.whl')
result = script.pip(
'download', '--no-index', '--find-links', data.find_links,
'--only-binary=:all:',
'--dest', '.',
'--platform', 'manylinux1_x86_64',
'fake',
)
assert (
Path('scratch') /
'fake-1.0-py2.py3-none-manylinux1_x86_64.whl'
in result.files_created
)
@pytest.mark.parametrize("platform", [
"linux_x86_64",
"manylinux1_x86_64",
"manylinux2_x86_64",
])
def test_download_universal(self, platform, script, data):
"""
Universal wheels are returned even for specific platforms.
"""
fake_wheel(data, 'fake-1.0-py2.py3-none-any.whl')
result = script.pip(
'download', '--no-index', '--find-links', data.find_links,
'--only-binary=:all:',
'--dest', '.',
'--platform', platform,
'fake',
)
assert (
Path('scratch') / 'fake-1.0-py2.py3-none-any.whl'
in result.files_created
)
# When specifying the platform, manylinux1 needs to be the
# explicit platform--it won't ever be added to the compatible
# tags.
data.reset()
fake_wheel(data, 'fake-1.0-py2.py3-none-linux_x86_64.whl')
result = script.pip(
'download', '--no-index', '--find-links', data.find_links,
'--only-binary=:all:',
'--dest', '.',
'--platform', 'linux_x86_64',
'fake',
expect_error=True,
)
@pytest.mark.parametrize("wheel_abi,platform", [
("manylinux1_x86_64", "manylinux1_x86_64"),
("manylinux1_x86_64", "manylinux2_x86_64"),
("manylinux2_x86_64", "manylinux2_x86_64"),
])
def test_download_compatible_manylinuxes(
self, wheel_abi, platform, script, data,
):
"""
Earlier manylinuxes are compatible with later manylinuxes.
"""
wheel = 'fake-1.0-py2.py3-none-{}.whl'.format(wheel_abi)
fake_wheel(data, wheel)
result = script.pip(
'download', '--no-index', '--find-links', data.find_links,
'--only-binary=:all:',
'--dest', '.',
'--platform', platform,
'fake',
)
assert Path('scratch') / wheel in result.files_created
def test_explicit_platform_only(self, data, script):
"""
When specifying the platform, manylinux1 needs to be the
explicit platform--it won't ever be added to the compatible
tags.
"""
fake_wheel(data, 'fake-1.0-py2.py3-none-linux_x86_64.whl')
script.pip(
'download', '--no-index', '--find-links', data.find_links,
'--only-binary=:all:',
'--dest', '.',
'--platform', 'linux_x86_64',
'fake',
expect_error=True,
)
def test_download_specify_python_version(script, data):

View file

@ -1,5 +1,7 @@
import sys
import pytest
from mock import patch
from pip._internal import pep425tags
@ -114,44 +116,57 @@ class TestPEP425Tags(object):
self.abi_tag_unicode('dm', {'Py_DEBUG': True, 'WITH_PYMALLOC': True})
class TestManylinux1Tags(object):
@pytest.mark.parametrize('is_manylinux_compatible', [
pep425tags.is_manylinux1_compatible,
pep425tags.is_manylinux2_compatible,
])
class TestManylinuxTags(object):
"""
Tests common to all manylinux tags (e.g. manylinux1, manylinux2,
...)
"""
@patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64')
@patch('pip._internal.utils.glibc.have_compatible_glibc',
lambda major, minor: True)
def test_manylinux1_compatible_on_linux_x86_64(self):
def test_manylinux_compatible_on_linux_x86_64(self,
is_manylinux_compatible):
"""
Test that manylinux1 is enabled on linux_x86_64
Test that manylinuxes are enabled on linux_x86_64
"""
assert pep425tags.is_manylinux1_compatible()
assert is_manylinux_compatible()
@patch('pip._internal.pep425tags.get_platform', lambda: 'linux_i686')
@patch('pip._internal.utils.glibc.have_compatible_glibc',
lambda major, minor: True)
def test_manylinux1_compatible_on_linux_i686(self):
def test_manylinux1_compatible_on_linux_i686(self,
is_manylinux_compatible):
"""
Test that manylinux1 is enabled on linux_i686
"""
assert pep425tags.is_manylinux1_compatible()
assert is_manylinux_compatible()
@patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64')
@patch('pip._internal.utils.glibc.have_compatible_glibc',
lambda major, minor: False)
def test_manylinux1_2(self):
def test_manylinux1_2(self, is_manylinux_compatible):
"""
Test that manylinux1 is disabled with incompatible glibc
"""
assert not pep425tags.is_manylinux1_compatible()
assert not is_manylinux_compatible()
@patch('pip._internal.pep425tags.get_platform', lambda: 'arm6vl')
@patch('pip._internal.utils.glibc.have_compatible_glibc',
lambda major, minor: True)
def test_manylinux1_3(self):
def test_manylinux1_3(self, is_manylinux_compatible):
"""
Test that manylinux1 is disabled on arm6vl
"""
assert not pep425tags.is_manylinux1_compatible()
assert not is_manylinux_compatible()
class TestManylinux1Tags(object):
@patch('pip._internal.pep425tags.is_manylinux2_compatible', lambda: False)
@patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64')
@patch('pip._internal.utils.glibc.have_compatible_glibc',
lambda major, minor: True)
@ -172,3 +187,49 @@ class TestManylinux1Tags(object):
assert arches == ['manylinux1_x86_64', 'linux_x86_64', 'any']
else:
assert arches == ['manylinux1_x86_64', 'linux_x86_64']
class TestManylinux2Tags(object):
@patch('pip._internal.pep425tags.get_platform', lambda: 'linux_x86_64')
@patch('pip._internal.utils.glibc.have_compatible_glibc',
lambda major, minor: True)
@patch('sys.platform', 'linux2')
def test_manylinux2_tag_is_first(self):
"""
Test that the more specific tag manylinux2 comes first.
"""
groups = {}
for pyimpl, abi, arch in pep425tags.get_supported():
groups.setdefault((pyimpl, abi), []).append(arch)
for arches in groups.values():
if arches == ['any']:
continue
# Expect the most specific arch first:
if len(arches) == 4:
assert arches == ['manylinux2_x86_64',
'manylinux1_x86_64',
'linux_x86_64',
'any']
else:
assert arches == ['manylinux2_x86_64',
'manylinux1_x86_64',
'linux_x86_64']
@pytest.mark.parametrize("manylinux2,manylinux1", [
("manylinux2_x86_64", "manylinux1_x86_64"),
("manylinux2_i686", "manylinux1_i686"),
])
def test_manylinux2_implies_manylinux1(self, manylinux2, manylinux1):
"""
Specifying manylinux2 implies manylinux1.
"""
groups = {}
for pyimpl, abi, arch in pep425tags.get_supported(platform=manylinux2):
groups.setdefault((pyimpl, abi), []).append(arch)
for arches in groups.values():
if arches == ['any']:
continue
assert arches[:2] == [manylinux2, manylinux1]

View file

@ -539,7 +539,7 @@ class TestTempDirectory(object):
class TestGlibc(object):
def test_manylinux1_check_glibc_version(self):
def test_manylinux_check_glibc_version(self):
"""
Test that the check_glibc_version function is robust against weird
glibc version strings.