Python/Wheel
< Python
Naming Convention
The naming format can be found under filename convention in PEP 427:
{distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl
ref: [1]
List all of the tags
pythonX.Y -m pip debug --verbose
import wheel.pep425tags print(wheel.pep425tags.get_supported())
ref: [2]
Check WHL Details
Kenneth v1:
#!/usr/bin/env python3 import argparse from pathlib import Path import sys from packaging.utils import parse_wheel_filename import platform print("System Debug: False") if tag.abi.endswith("d"): print("Wheel Debug: True") if not sys.flags.debug: failure.append(f"The ABI of the wheel is {tag.abi}, which is a debug wheel. However, the python interpeter does not have the debug flags set.") _minor = int(tag.interpreter[idx + 1]) print(f"Wheel Python: 3.{supported_minor}") if sys.version_info.minor != supported_minor: failure.append(f"The python minor version is {sys.version_info.minor}, but the wheel only supports minor version {supported_minor}") s[1] # armv7l if len(pieces) == 3: cpu_architecture += "_" + pieces[2] # x86_64 # Check for MacOSX print(f"System Platform: {sys.platform}") c_ver()[0].split(".") if int(os_major) < int(wheel_os_version_major): failure.append(f"The operating system major version is {os_major}, but the wheel requires at least OS major version {wheel_os_version_major}") ported(args.wheelfile) if len(failures) > 0: print(f"ERROR: {args.wheelfile} is not supported on this platform.") for fail in failures: print(f"REASON: {fail}") s a debug wheel being loaded in a non-debug interpreter? if sys.flags.debug: print("System Debug: True") else: print('fail') else: print('ok') else: print('ok') print() # There should be no restriction on the platform: print(f"Tag Platform: {tag.platform}") is {sys.platform}") print('fail') else: print('ok') else: print('ok') is {os_minor}, but the wheel requires at least OS major version {wheel_os_version_minor}") print('fail') else: print(f"Wheel OS Minor: {wheel_os_version_minor}") print('ok') parse: _, _, _, tags = parse_wheel_filename(p.name) print(f"Wheel: {args.wheelfile}") tag = None for t in tags: should it be using? print(f"System Python: 3.{sys.version_info.minor}") idx = tag.interpreter.find("3") if idx >= 0 and idx < len(tag.interpreter) - 1: failure.append(f"The wheel was build for macosx, but the current platform print() print(f"System Architecture: {platform.machine()}") print(f"Wheel Architecture: {cpu_architecture}") e.ArgumentParser( description="Diagnoses why a wheel is unsupported on a particular platform." ) parser.add_argument("wheelfile", type=Path, help="The name of the wheel file.") args = parser.parse_args() l being loaded by a non-cpython interpreter? print("System CPythonn: " + sys.implementation.name) # cpython if tag.abi.startswith("cp"): print("Wheel Cpyhon: cpython") wheel_os_name = pieces[0] # linux #wheel_os_version_major = pieces[1] wheel_os_version_major = None #wheel_os_version_minor = pieces[2] < int(wheel_os_version_minor): failure.append(f"The operating system minor version print() else: print('ok') ("Wheel Debug: False") print('ok') print() # Is a cpython whee if sys.implementation.name != "cpython": failure.append(f"The ABI of the wheel '{p}' requires cpython, but the system implementation is {sys.implementation.name}") macosx": if sys.platform != "darwin": if cpu_architecture != platform.machine(): failure.append(f"The CPU architecture supported by the wheel is {cpu_architecture}, but the platform has architecture {platform.machine()}") f"File '{p}' does not exist" if not p.is_file(): return f"'{p}' is not a file" if p.suffix != ".whl": return f"'{p}' has incorrect suffix; the suffix must be .whl" ces[3] # ?armv7l? else: print("Warning: Platform tag not as expected, attempting best effort.") print() f sys.version_info.major != 3: print("Error: Expecting Python3") sys.exit(1) def diagnose_unsupported(p: Path) -> str: s_version_minor = pieces[2] cpu_architecture = pie wheel_os_version_minor = None #cpu_architecture = pieces[3] cpu_architecture = piece print(f"Wheel Platform: {wheel_os_name}") print("Wheel Interpreter: " + tag.interpreter) # cp39 print("Wheel Platform: " + tag.platform) # any | linux_armv7l | linux_x86_64 | win_amd64 print() else: print(f"Wheel OS Major: {wheel_os_version_major}") print('ok') if int(os_major) == int(wheel_os_version_major): if int(os_minor) print() wheel_os_version_major = pieces[1] wheel_o if wheel_os_name == " print('fail') else: print('ok') else: print('ok') if tag.platform == "any": print('ok') # return "" pieces = tag.platform.split("_") rint() # If the interpreter is version intolerant, what interpreter supported print('fail') print(f"Tag Pieces: {pieces}") if len(pieces) == 4: wheel_os_name = pieces[0] # linux print() print(f"System OS: {platform.mac_ver()}") print(f"Wheel OS: {wheel_os_version_major} {wheel_os_version_minor}") if wheel_os_version_major: os_major, os_minor, os_patch = platform.ma print('fail') return failure if __name__ == "__main__": parser = argpars failures = diagnose_unsup sys.exit(1) else: print(f"{args.wheelfile} should be supported on your platform!") print("ok") i p = Path(p) if not p.exists(): return failure = [] # The wheel filename must tag = t print("Wheel ABI: " + tag.abi) # cp39 # I else: print print('fail') else: print('ok') else: print("Wheel Cpyhon: False") print('ok') p
Original:
#!/usr/bin/env python3 import argparse from pathlib import Path import sys from packaging.utils import parse_wheel_filename import platform def diagnose_unsupported(p: Path) -> str: p = Path(p) if not p.exists(): return f"File '{p}' does not exist" if not p.is_file(): return f"'{p}' is not a file" if p.suffix != ".whl": return f"'{p}' has incorrect suffix; the suffix must be .whl" # The wheel filename must parse: _, _, _, tags = parse_wheel_filename(p.name) tag = None for t in tags: tag = t # Is a debug wheel being loaded in a non-debug interpreter? if tag.abi.endswith("d"): if not sys.flags.debug: return f"The ABI of the wheel is {tag.abi}, which is a debug wheel. However, the python interpeter does not have the debug flags set." # Is a cpython wheel being loaded by a non-cpython interpreter? if tag.abi.startswith("cp"): if sys.implementation.name != "cpython": return f"The ABI of the wheel '{p}' requires cpython, but the system implementation is {sys.implementation.name}" # If the interpreter is version intolerant, what interpreter should it be using? idx = tag.interpreter.find("3") if idx >= 0 and idx < len(tag.interpreter) - 1: supported_minor = int(tag.interpreter[idx + 1]) if sys.version_info.minor != supported_minor: return f"The python minor version is {sys.version_info.minor}, but the wheel only supports minor version {supported_minor}" # There should be no restriction on the platform: if tag.platform == "any": return "" pieces = tag.platform.split("_") if len(pieces) != 4: print("Unable to parse the platform tag") wheel_os_name = pieces[0] wheel_os_version_major = pieces[1] wheel_os_version_minor = pieces[2] cpu_architecture = pieces[3] if wheel_os_name == "macosx": if sys.platform != "darwin": return f"The wheel was build for macosx, but the current platform is {sys.platform}" if cpu_architecture != platform.machine(): return f"The CPU architecture supported by the wheel is {cpu_architecture}, but the platform has architecture {platform.machine()}" os_major, os_minor, os_patch = platform.mac_ver()[0].split(".") if int(os_major) < int(wheel_os_version_major): return f"The operating system major version is {os_major}, but the wheel requires at least OS major version {wheel_os_version_major}" if int(os_major) == int(wheel_os_version_major): if int(os_minor) < int(wheel_os_version_minor): return f"The operating system minor version is {os_minor}, but the wheel requires at least OS major version {wheel_os_version_minor}" return "" if __name__ == "__main__": parser = argparse.ArgumentParser( description="Diagnoses why a wheel is unsupported on a particular platform." ) parser.add_argument("wheelfile", type=Path, help="The name of the wheel file.") args = parser.parse_args() error_msg = diagnose_unsupported(args.wheelfile) if len(error_msg) > 0: print( f"ERROR: {args.wheelfile} is not supported on this platform. Reason: {error_msg}" ) else: print(f"{args.wheelfile} should be supported on your platform!")
ref: More information about *why* a wheel is not supported on a given platform · Issue #10793 · pypa/pip - https://github.com/pypa/pip/issues/10793