Skip to content

Commit 3ac70ff

Browse files
authored
Use PEP600 policy names (#288)
Add legacy aliases for `manylinux_2_5`, `manylinux_2_12` & `manylinux_2_17` The platform tag passed to `auditwheel repair` `--plat` argument can use either the PEP600 tag or the legacy tag. The repaired wheel will get both platform tags. e.g. `auditwheel repair --plat manylinux1_x86_64 foo-5.0-cp38-cp38-linux_x86_64.whl` and `auditwheel repair --plat manylinux_2_5_x86_64 foo-5.0-cp38-cp38-linux_x86_64.whl` will both produce `foo-5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl`
1 parent 70e167d commit 3ac70ff

15 files changed

+209
-97
lines changed

auditwheel/main_repair.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from os.path import isfile, exists, abspath, basename
22

33
from auditwheel.patcher import Patchelf
4-
from .policy import (load_policies, get_policy_name, get_priority_by_name,
5-
POLICY_PRIORITY_HIGHEST)
4+
from .policy import (load_policies, get_policy_by_name, get_policy_name,
5+
get_priority_by_name, POLICY_PRIORITY_HIGHEST)
66
from .tools import EnvironmentDefault
77
import logging
88

@@ -11,6 +11,7 @@
1111

1212
def configure_parser(sub_parsers):
1313
policy_names = [p['name'] for p in load_policies()]
14+
policy_names += [alias for p in load_policies() for alias in p['aliases']]
1415
highest_policy = get_policy_name(POLICY_PRIORITY_HIGHEST)
1516
help = "Vendor in external shared library dependencies of a wheel."
1617
p = sub_parsers.add_parser('repair', help=help, description=help)
@@ -69,7 +70,8 @@ def execute(args, p):
6970
logger.info('This does not look like a platform wheel')
7071
return 1
7172

72-
reqd_tag = get_priority_by_name(args.PLAT)
73+
policy = get_policy_by_name(args.PLAT)
74+
reqd_tag = policy['priority']
7375

7476
if reqd_tag > get_priority_by_name(wheel_abi.sym_tag):
7577
msg = ('cannot repair "%s" to "%s" ABI because of the presence '
@@ -85,9 +87,10 @@ def execute(args, p):
8587
(args.WHEEL_FILE, args.PLAT))
8688
p.error(msg)
8789

90+
abis = [policy['name']] + policy['aliases']
8891
patcher = Patchelf()
8992
out_wheel = repair_wheel(args.WHEEL_FILE,
90-
abi=args.PLAT,
93+
abis=abis,
9194
lib_sdir=args.LIB_SDIR,
9295
out_dir=args.WHEEL_DIR,
9396
update_tags=args.UPDATE_TAGS,
@@ -101,8 +104,10 @@ def execute(args, p):
101104
'You requested %s but I have found this wheel is '
102105
'eligible for %s.'),
103106
args.PLAT, analyzed_tag)
107+
policy = get_policy_by_name(analyzed_tag)
108+
abis = [policy['name']] + policy['aliases']
104109
out_wheel = repair_wheel(args.WHEEL_FILE,
105-
abi=analyzed_tag,
110+
abis=abis,
106111
lib_sdir=args.LIB_SDIR,
107112
out_dir=args.WHEEL_DIR,
108113
update_tags=args.UPDATE_TAGS,

auditwheel/main_show.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ def configure_parser(sub_parsers):
1515
def printp(text: str) -> None:
1616
from textwrap import wrap
1717
print()
18-
print('\n'.join(wrap(text)))
18+
print('\n'.join(wrap(text, break_long_words=False,
19+
break_on_hyphens=False)))
1920

2021

2122
def execute(args, p):

auditwheel/policy/__init__.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ def _validate_pep600_compliance(policies) -> None:
6565
if _p['name'] != 'linux':
6666
_p['symbol_versions'] = _p['symbol_versions'][_ARCH_NAME]
6767
_p['name'] = _p['name'] + '_' + _ARCH_NAME
68+
_p['aliases'] = [alias + '_' + _ARCH_NAME
69+
for alias in _p['aliases']]
6870
_POLICIES.append(_p)
6971

7072
POLICY_PRIORITY_HIGHEST = max(p['priority'] for p in _POLICIES)
@@ -81,24 +83,30 @@ def _load_policy_schema():
8183
return schema
8284

8385

84-
def get_policy_name(priority: int) -> Optional[str]:
85-
matches = [p['name'] for p in _POLICIES if p['priority'] == priority]
86+
def get_policy_by_name(name: str) -> Optional[Dict]:
87+
matches = [p for p in _POLICIES
88+
if p['name'] == name or name in p['aliases']]
8689
if len(matches) == 0:
8790
return None
8891
if len(matches) > 1:
89-
raise RuntimeError('Internal error. priorities should be unique')
92+
raise RuntimeError('Internal error. Policies should be unique')
9093
return matches[0]
9194

9295

93-
def get_priority_by_name(name: str) -> Optional[int]:
94-
matches = [p['priority'] for p in _POLICIES if p['name'] == name]
96+
def get_policy_name(priority: int) -> Optional[str]:
97+
matches = [p['name'] for p in _POLICIES if p['priority'] == priority]
9598
if len(matches) == 0:
9699
return None
97100
if len(matches) > 1:
98-
raise RuntimeError('Internal error. Policies should be unique.')
101+
raise RuntimeError('Internal error. priorities should be unique')
99102
return matches[0]
100103

101104

105+
def get_priority_by_name(name: str) -> Optional[int]:
106+
policy = get_policy_by_name(name)
107+
return None if policy is None else policy['priority']
108+
109+
102110
def get_replace_platforms(name: str) -> List[str]:
103111
"""Extract platform tag replacement rules from policy
104112

auditwheel/policy/policy-schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
"name": {
1313
"type": "string"
1414
},
15+
"aliases": {
16+
"type": "array",
17+
"items": {
18+
"type": "string"
19+
}
20+
},
1521
"priority": {
1622
"type": "integer"
1723
},

auditwheel/policy/policy.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
[
22
{"name": "linux",
3+
"aliases": [],
34
"priority": 0,
45
"symbol_versions": {},
56
"lib_whitelist": []
67
},
7-
{"name": "manylinux1",
8+
{"name": "manylinux_2_5",
9+
"aliases": ["manylinux1"],
810
"priority": 100,
911
"symbol_versions": {
1012
"i686": {
@@ -29,7 +31,8 @@
2931
"libSM.so.6", "libGL.so.1", "libgobject-2.0.so.0",
3032
"libgthread-2.0.so.0", "libglib-2.0.so.0", "libresolv.so.2"
3133
]},
32-
{"name": "manylinux2010",
34+
{"name": "manylinux_2_12",
35+
"aliases": ["manylinux2010"],
3336
"priority": 90,
3437
"symbol_versions": {
3538
"i686": {
@@ -54,7 +57,8 @@
5457
"libSM.so.6", "libGL.so.1", "libgobject-2.0.so.0",
5558
"libgthread-2.0.so.0", "libglib-2.0.so.0", "libresolv.so.2"
5659
]},
57-
{"name": "manylinux2014",
60+
{"name": "manylinux_2_17",
61+
"aliases": ["manylinux2014"],
5862
"priority": 80,
5963
"symbol_versions": {
6064
"i686": {
@@ -110,6 +114,7 @@
110114
"libgthread-2.0.so.0", "libglib-2.0.so.0", "libresolv.so.2"
111115
]},
112116
{"name": "manylinux_2_24",
117+
"aliases": [],
113118
"priority": 70,
114119
"symbol_versions": {
115120
"i686": {

auditwheel/repair.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from os.path import exists, basename, abspath, isabs, dirname
1010
from os.path import join as pjoin
1111
from subprocess import check_call
12-
from typing import Dict, Iterable, Optional, Tuple
12+
from typing import Dict, Iterable, List, Optional, Tuple
1313

1414
from auditwheel.patcher import ElfPatcher
1515
from .elfutils import elf_read_rpaths, elf_read_dt_needed, is_subdir
@@ -28,7 +28,7 @@
2828
re.VERBOSE).match
2929

3030

31-
def repair_wheel(wheel_path: str, abi: str, lib_sdir: str, out_dir: str,
31+
def repair_wheel(wheel_path: str, abis: List[str], lib_sdir: str, out_dir: str,
3232
update_tags: bool, patcher: ElfPatcher,
3333
strip: bool = False) -> Optional[str]:
3434

@@ -61,7 +61,7 @@ def repair_wheel(wheel_path: str, abi: str, lib_sdir: str, out_dir: str,
6161
# the wheel, and v['libs'] contains its required libs
6262
for fn, v in external_refs_by_fn.items():
6363

64-
ext_libs = v[abi]['libs'] # type: Dict[str, str]
64+
ext_libs = v[abis[0]]['libs'] # type: Dict[str, str]
6565
for soname, src_path in ext_libs.items():
6666
if src_path is None:
6767
raise ValueError(('Cannot repair wheel, because required '
@@ -88,8 +88,8 @@ def repair_wheel(wheel_path: str, abi: str, lib_sdir: str, out_dir: str,
8888
patcher.replace_needed(path, n, soname_map[n][0])
8989

9090
if update_tags:
91-
ctx.out_wheel = add_platforms(ctx, [abi],
92-
get_replace_platforms(abi))
91+
ctx.out_wheel = add_platforms(ctx, abis,
92+
get_replace_platforms(abis[0]))
9393

9494
if strip:
9595
libs_to_strip = [path for (_, path) in soname_map.values()]

auditwheel/wheeltools.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import csv
1212
from itertools import product
1313
from types import TracebackType
14-
from typing import Generator, Iterable, Optional, Type
14+
from typing import Generator, Iterable, List, Optional, Type
1515
import logging
1616

1717
from base64 import urlsafe_b64encode
@@ -178,7 +178,7 @@ def iter_files(self) -> Generator[str, None, None]:
178178
yield filename
179179

180180

181-
def add_platforms(wheel_ctx: InWheelCtx, platforms: Iterable[str],
181+
def add_platforms(wheel_ctx: InWheelCtx, platforms: List[str],
182182
remove_platforms: Iterable[str] = ()) -> str:
183183
"""Add platform tags `platforms` to a wheel
184184
@@ -189,7 +189,7 @@ def add_platforms(wheel_ctx: InWheelCtx, platforms: Iterable[str],
189189
----------
190190
wheel_ctx : InWheelCtx
191191
An open wheel context
192-
platforms : iterable
192+
platforms : list
193193
platform tags to add to wheel filename and WHEEL tags - e.g.
194194
``('macosx_10_9_intel', 'macosx_10_9_x86_64')
195195
remove_platforms : iterable
@@ -216,9 +216,9 @@ def add_platforms(wheel_ctx: InWheelCtx, platforms: Iterable[str],
216216
fparts = parsed_fname.groupdict()
217217
original_fname_tags = fparts['plat'].split('.')
218218
logger.info('Previous filename tags: %s', ', '.join(original_fname_tags))
219-
fname_tags = {tag for tag in original_fname_tags
220-
if tag not in remove_platforms}
221-
fname_tags |= set(platforms)
219+
fname_tags = [tag for tag in original_fname_tags
220+
if tag not in remove_platforms]
221+
fname_tags = unique_by_index(fname_tags + platforms)
222222

223223
# Can't be 'any' and another platform
224224
if 'any' in fname_tags and len(fname_tags) > 1:

tests/integration/test_bundled_cffi.py

Lines changed: 0 additions & 11 deletions
This file was deleted.

tests/integration/test_bundled_pypy_snappy.py

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import platform
2+
from pathlib import Path
3+
import pytest
4+
from auditwheel.wheel_abi import analyze_wheel_abi
5+
6+
7+
HERE = Path(__file__).parent.resolve()
8+
9+
10+
@pytest.mark.skipif(platform.machine() != 'x86_64', reason='only supported on x86_64')
11+
@pytest.mark.parametrize('file, external_libs', [
12+
('cffi-1.5.0-cp27-none-linux_x86_64.whl', {'libffi.so.5'}),
13+
('python_snappy-0.5.2-pp260-pypy_41-linux_x86_64.whl', {'libsnappy.so.1'}),
14+
])
15+
def test_analyze_wheel_abi(file, external_libs):
16+
winfo = analyze_wheel_abi(str(HERE / file))
17+
assert set(winfo.external_refs['manylinux_2_5_x86_64']['libs']) == external_libs
18+
19+
20+
@pytest.mark.skipif(platform.machine() != 'x86_64', reason='only supported on x86_64')
21+
def test_analyze_wheel_abi_pyfpe():
22+
winfo = analyze_wheel_abi(str(HERE / 'fpewheel-0.0.0-cp35-cp35m-linux_x86_64.whl'))
23+
assert winfo.sym_tag == 'manylinux_2_5_x86_64' # for external symbols, it could get manylinux1
24+
assert winfo.pyfpe_tag == 'linux_x86_64' # but for having the pyfpe reference, it gets just linux

0 commit comments

Comments
 (0)