Skip to content

Commit

Permalink
Improve tag generation for EggPackage.
Browse files Browse the repository at this point in the history
  • Loading branch information
kwlzn committed May 23, 2018
1 parent 06f77c1 commit 57a2ad1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 26 deletions.
79 changes: 54 additions & 25 deletions pex/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ def satisfies(self, requirement, allow_prereleases=None):
return requirement.specifier.contains(self.raw_version, prereleases=allow_prereleases)

def compatible(self, supported_tags):
"""Is this link compatible with the given tag set?
"""Is this package compatible with the given tag set?
:param supported_tags: A list of tags that is supported by the target
interpeter, as generated by
:func:`pex.pep425tags.get_supported`.
:type supported_tags: list of 3-tuples
"""
return not set(supported_tags).isdisjoint(self._supported_tags)
raise NotImplementedError()


class SourcePackage(Package):
Expand Down Expand Up @@ -142,7 +142,34 @@ def compatible(self, supported_tags):
return True


class EggPackage(Package):
class BinaryPackage(Package):
"""A Package representing a binary distribution which can be e.g. platform specific."""

def __init__(self, *args, **kwargs):
super(BinaryPackage, self).__init__(*args, **kwargs)
self._supported_tags = None

@property
def supported_tags(self):
if not self._supported_tags:
self._supported_tags = frozenset(self._iter_tags())
return self._supported_tags

def _iter_tags(self):
raise NotImplementedError()

def compatible(self, supported_tags):
"""Is this package compatible with the given tag set?
:param supported_tags: A list of tags that is supported by the target
interpeter, as generated by
:func:`pex.pep425tags.get_supported`.
:type supported_tags: list of 3-tuples
"""
return not set(supported_tags).isdisjoint(self.supported_tags)


class EggPackage(BinaryPackage):
"""A Package representing a built egg."""

def __init__(self, url, **kw):
Expand All @@ -161,26 +188,6 @@ def __init__(self, url, **kw):
if self._raw_version is None or self._py_version is None:
raise self.InvalidPackage('url with .egg extension but bad name: %s' % url)

impl = 'py' + self._py_version.replace('.', '')
abi_tag = 'none'
tag_platform = (self._platform or 'any').replace('-', '_')

self._supported_tags = set([(impl, abi_tag, tag_platform)])
if tag_platform != 'any':
self._supported_tags.add((impl, abi_tag, 'any'))

# Work around PyPy versions being weird in pep425tags.get_supported
if self.py_version == '2.7':
self._supported_tags.add(('pp2', abi_tag, tag_platform))
elif self.py_version == '3.2':
self._supported_tags.add(('pp321', abi_tag, tag_platform))
elif self.py_version == '3.3':
# N.B. PyPy 3.3 maps to `pp352` because of PyPy versioning.
# see e.g. http://doc.pypy.org/en/latest/release-pypy3.3-v5.2-alpha1.html
self._supported_tags.add(('pp352', abi_tag, tag_platform))
elif self.py_version == '3.5':
self._supported_tags.add(('pp357', abi_tag, tag_platform))

def __hash__(self):
return hash((self.name, self.version, self.py_version, self.platform))

Expand All @@ -200,8 +207,31 @@ def py_version(self):
def platform(self):
return self._platform

def _iter_tags(self):
abi_tag = 'none'
tag_platform = (self._platform or 'any').replace('-', '_').replace('.', '_')
suffix_maj = self._py_version.split('.', 1)[0]
suffix_min = self._py_version.replace('.', '')

for prefix in ('py', 'cp'):
for suffix in (suffix_maj, suffix_min):
impl = ''.join((prefix, suffix))
yield (impl, abi_tag, tag_platform)

# Work around PyPy versions being weird in pep425tags.get_supported
if self.py_version == '2.7':
yield ('pp2', abi_tag, tag_platform)
elif self.py_version == '3.2':
yield ('pp321', abi_tag, tag_platform)
elif self.py_version == '3.3':
# N.B. PyPy 3.3 maps to `pp352` because of PyPy versioning.
# see e.g. http://doc.pypy.org/en/latest/release-pypy3.3-v5.2-alpha1.html
yield ('pp352', abi_tag, tag_platform)
elif self.py_version == '3.5':
yield ('pp357', abi_tag, tag_platform)


class WheelPackage(Package):
class WheelPackage(BinaryPackage):
"""A Package representing a built wheel."""

def __init__(self, url, **kw):
Expand All @@ -217,7 +247,6 @@ def __init__(self, url, **kw):
# See https://github.com/pypa/pip/issues/1150 for why this is unavoidable.
self._name = self._name.replace('_', '-')
self._raw_version = self._raw_version.replace('_', '-')
self._supported_tags = frozenset(self._iter_tags())

@property
def name(self):
Expand Down
Binary file not shown.
29 changes: 28 additions & 1 deletion tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -834,11 +834,38 @@ def test_pex_manylinux_runtime():


@pytest.mark.skipif(NOT_CPYTHON27)
def test_platform_specific_egg_resolution():
def test_platform_specific_inline_egg_resolution():
with temporary_dir() as td:
pex_out_path = os.path.join(td, 'pex.pex')
res = run_pex_command(['--disable-cache',
'--no-wheel',
'MarkupSafe==1.0',
'-o', pex_out_path])
res.assert_success()


@pytest.mark.skipif(NOT_CPYTHON27)
def test_platform_specific_egg_resolution():
with temporary_dir() as td:
pex_out_path = os.path.join(td, 'pex.pex')
res = run_pex_command(['--disable-cache',
'--no-wheel',
'--no-build',
'--no-pypi',
'--platform=linux-x86_64',
'--find-links=tests/example_packages/',
'M2Crypto==0.22.3',
'-o', pex_out_path])
res.assert_success()


@pytest.mark.skipif(NOT_CPYTHON27)
def test_platform_specific_egg_resolution_matching():
with temporary_dir() as td:
pex_out_path = os.path.join(td, 'pex.pex')
res = run_pex_command(['--disable-cache',
'--no-wheel',
'--no-build',
'netifaces==0.10.6', # Only provides win32 eggs.
'-o', pex_out_path])
res.assert_failure()

0 comments on commit 57a2ad1

Please sign in to comment.