Skip to content

Commit 3b1d9ef

Browse files
authored
Merge pull request #224 from lkollar/non-platform-wheel
Correctly detect non-platform wheels
2 parents d864b5e + cd3874e commit 3b1d9ef

File tree

7 files changed

+63
-22
lines changed

7 files changed

+63
-22
lines changed

auditwheel/main_addtag.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ def execute(args, p):
2424
import os
2525
from wheel.wheelfile import WHEEL_INFO_RE # type: ignore
2626
from .wheeltools import InWheelCtx, add_platforms, WheelToolsError
27-
from .wheel_abi import analyze_wheel_abi
27+
from .wheel_abi import analyze_wheel_abi, NonPlatformWheel
2828

29-
wheel_abi = analyze_wheel_abi(args.WHEEL_FILE)
29+
try:
30+
wheel_abi = analyze_wheel_abi(args.WHEEL_FILE)
31+
except NonPlatformWheel:
32+
logger.info('This does not look like a platform wheel')
33+
return 1
3034

3135
parsed_fname = WHEEL_INFO_RE.search(basename(args.WHEEL_FILE))
3236
in_fname_tags = parsed_fname.groupdict()['plat'].split('.')

auditwheel/main_repair.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def execute(args, p):
4747
import os
4848
from distutils.spawn import find_executable
4949
from .repair import repair_wheel
50-
from .wheel_abi import analyze_wheel_abi
50+
from .wheel_abi import analyze_wheel_abi, NonPlatformWheel
5151

5252
if not isfile(args.WHEEL_FILE):
5353
p.error('cannot access %s. No such file' % args.WHEEL_FILE)
@@ -59,7 +59,12 @@ def execute(args, p):
5959
if not exists(args.WHEEL_DIR):
6060
os.makedirs(args.WHEEL_DIR)
6161

62-
wheel_abi = analyze_wheel_abi(args.WHEEL_FILE)
62+
try:
63+
wheel_abi = analyze_wheel_abi(args.WHEEL_FILE)
64+
except NonPlatformWheel:
65+
logger.info('This does not look like a platform wheel')
66+
return 1
67+
6368
reqd_tag = get_priority_by_name(args.PLAT)
6469

6570
if reqd_tag > get_priority_by_name(wheel_abi.sym_tag):

auditwheel/main_show.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
import logging
2+
13
try:
24
from collections.abc import OrderedDict
35
except ImportError:
46
from collections import OrderedDict
57

8+
logger = logging.getLogger(__name__)
9+
610

711
def configure_parser(sub_parsers):
812
help = "Audit a wheel for external shared library dependencies."
@@ -23,13 +27,18 @@ def execute(args, p):
2327
from .policy import (load_policies, get_priority_by_name,
2428
POLICY_PRIORITY_LOWEST, POLICY_PRIORITY_HIGHEST,
2529
get_policy_name)
26-
from .wheel_abi import analyze_wheel_abi
30+
from .wheel_abi import analyze_wheel_abi, NonPlatformWheel
2731
fn = basename(args.WHEEL_FILE)
2832

2933
if not isfile(args.WHEEL_FILE):
3034
p.error('cannot access %s. No such file' % args.WHEEL_FILE)
3135

32-
winfo = analyze_wheel_abi(args.WHEEL_FILE)
36+
try:
37+
winfo = analyze_wheel_abi(args.WHEEL_FILE)
38+
except NonPlatformWheel:
39+
logger.info('This does not look like a platform wheel')
40+
return 1
41+
3342
libs_with_versions = ['%s with versions %s' % (k, v)
3443
for k, v in winfo.versioned_symbols.items()]
3544

auditwheel/wheel_abi.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
'pyfpe_tag'])
2727

2828

29+
class WheelAbiError(Exception):
30+
"""Root exception class"""
31+
32+
33+
class NonPlatformWheel(WheelAbiError):
34+
"""No ELF binaries in the wheel"""
35+
36+
2937
@functools.lru_cache()
3038
def get_wheel_elfdata(wheel_fn: str):
3139
full_elftree = {}
@@ -38,7 +46,9 @@ def get_wheel_elfdata(wheel_fn: str):
3846
with InGenericPkgCtx(wheel_fn) as ctx:
3947
shared_libraries_in_purelib = []
4048

49+
platform_wheel = False
4150
for fn, elf in elf_file_filter(ctx.iter_files()):
51+
platform_wheel = True
4252

4353
# Check for invalid binary wheel format: no shared library should
4454
# be found in purelib
@@ -79,6 +89,9 @@ def get_wheel_elfdata(wheel_fn: str):
7989
# its internal references later.
8090
nonpy_elftree[fn] = elftree
8191

92+
if not platform_wheel:
93+
raise NonPlatformWheel
94+
8295
# If at least one shared library exists in purelib, raise an error
8396
if shared_libraries_in_purelib:
8497
raise RuntimeError(
112 KB
Binary file not shown.

tests/integration/test_manylinux.py

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ def docker_container_ctx(image, io_dir=None, env_variables={}):
104104
container.remove(force=True)
105105

106106

107-
def docker_exec(container, cmd):
107+
def docker_exec(container, cmd, expected_retcode=0):
108108
logger.info("docker exec %s: %r", container.id[:12], cmd)
109109
ec, output = container.exec_run(cmd)
110110
output = output.decode(ENCODING)
111-
if ec != 0:
111+
if ec != expected_retcode:
112112
print(output)
113113
raise CalledProcessError(ec, cmd, output=output)
114114
return output
@@ -379,6 +379,7 @@ def test_build_repair_pure_wheel(any_manylinux_container, io_folder):
379379
# If six has already been built and put in cache, let's reuse this.
380380
shutil.copy2(op.join(WHEEL_CACHE_FOLDER, policy, ORIGINAL_SIX_WHEEL),
381381
op.join(io_folder, ORIGINAL_SIX_WHEEL))
382+
logger.info("Copied six wheel from {} to {}".format(WHEEL_CACHE_FOLDER, io_folder))
382383
else:
383384
docker_exec(manylinux_ctr, 'pip wheel -w /io --no-binary=:all: six==1.11.0')
384385
os.makedirs(op.join(WHEEL_CACHE_FOLDER, policy), exist_ok=True)
@@ -394,21 +395,13 @@ def test_build_repair_pure_wheel(any_manylinux_container, io_folder):
394395
repair_command = (
395396
'auditwheel repair --plat {policy} -w /io /io/{orig_wheel}'
396397
).format(policy=policy, orig_wheel=orig_wheel)
397-
docker_exec(manylinux_ctr, repair_command)
398-
filenames = os.listdir(io_folder)
399-
assert len(filenames) == 1 # no new wheels
400-
assert filenames == [ORIGINAL_SIX_WHEEL]
398+
output = docker_exec(manylinux_ctr, repair_command, expected_retcode=1)
399+
assert "This does not look like a platform wheel" in output
401400

402-
output = docker_exec(manylinux_ctr, 'auditwheel show /io/' + filenames[0])
403-
expected = 'manylinux1' if PLATFORM in {'x86_64', 'i686'} else 'manylinux2014'
404-
assert ''.join([
405-
ORIGINAL_SIX_WHEEL,
406-
' is consistent with the following platform tag: ',
407-
'"{}_{}". '.format(expected, PLATFORM),
408-
'The wheel references no external versioned symbols from system- ',
409-
'provided shared libraries. ',
410-
'The wheel requires no external shared libraries! :)',
411-
]) in output.replace('\n', ' ')
401+
output = docker_exec(manylinux_ctr, 'auditwheel show /io/{orig_wheel}'
402+
.format(orig_wheel=orig_wheel),
403+
expected_retcode=1)
404+
assert "This does not look like a platform wheel" in output
412405

413406

414407
@pytest.mark.parametrize('dtag', ['rpath', 'runpath'])
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import pathlib
2+
import subprocess
3+
4+
import pytest
5+
6+
HERE = pathlib.Path(__file__).parent.resolve()
7+
8+
9+
@pytest.mark.parametrize("mode", ["repair", "addtag", "show"])
10+
def test_non_platform_wheel_repair(mode):
11+
wheel = HERE / "plumbum-1.6.8-py2.py3-none-any.whl"
12+
proc = subprocess.run(["auditwheel", mode, str(wheel)],
13+
stderr=subprocess.PIPE,
14+
universal_newlines=True)
15+
assert proc.returncode == 1
16+
assert "This does not look like a platform wheel" in proc.stderr
17+
assert "AttributeError" not in proc.stderr

0 commit comments

Comments
 (0)