From fc8e8060d2a91e6d599070cd84428c8cd42fbd23 Mon Sep 17 00:00:00 2001 From: Aohan Dang Date: Fri, 19 Jul 2024 16:31:38 -0400 Subject: [PATCH] Use regex to analyze wheel tags This simplies the code used to determine which DLLs to ignore based on the Python tag, ABI tag, and platform tag. This also allows us to more easily ignore DLLs for future Python versions and thus includes a presumptive list of DLLs to ignore through Python 3.99. --- delvewheel/_dll_list.py | 116 +++++++----------------------------- delvewheel/_wheel_repair.py | 14 +++-- 2 files changed, 31 insertions(+), 99 deletions(-) diff --git a/delvewheel/_dll_list.py b/delvewheel/_dll_list.py index 3fcfdf3..621524e 100644 --- a/delvewheel/_dll_list.py +++ b/delvewheel/_dll_list.py @@ -53,78 +53,25 @@ def platform_tag_to_type(cls, tag: str) -> typing.Optional['MachineType']: # who builds an extension module against a newer version of MSVC++ than Python # itself is already assuming the risks associated with lack of forward # compatibility. +# +# For efficiency, the dict is sorted approximately from most commonly used to +# least commonly used. The regexes are not compiled here because each is used +# at most once for a given wheel, and many are likely not used. ignore_by_abi_platform = { - 'cp26m-win32': {'msvcr90.dll'}, - 'cp26m-win_amd64': {'msvcr90.dll'}, - 'cp27m-win32': {'msvcr90.dll'}, - 'cp27m-win_amd64': {'msvcr90.dll'}, + # current and future Python versions through 3.99 + 'cp3(9|1[0-2]|(1[3-9]|[2-9][0-9])t?)-win_a(md|rm)64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, + 'cp3(9|1[0-2]|(1[3-9]|[2-9][0-9])t?)-win32': {'vcruntime140.dll'}, + 'cp3((9|1[0-2])d|(1[3-9]|[2-9][0-9])dt?)-win(32|_a(md|rm)64)': {'vcruntime140d.dll', 'ucrtbased.dll'}, + 'pypy3([7-9]|1[0-9]|[2-9][0-9])_pp73-win_amd64': {'vcruntime140.dll'}, + + # older versions of Python + 'cp3([5-7]m|8)-win(32|_amd64)': {'vcruntime140.dll'}, + 'cp3([5-7]dm|8d)-win(32|_amd64)': {'vcruntime140d.dll', 'ucrtbased.dll'}, + 'pypy3[6-7]_pp73-win32': {'vcruntime140.dll'}, + 'pypy_73-win(32|_amd64)': {'vcruntime140.dll'}, + 'cp3[3-4]m-win(32|_amd64)': {'msvcr100.dll'}, + 'cp(26|27|32)m-win(32|_amd64)': {'msvcr90.dll'}, 'pypy_41-win32': {'msvcr90.dll'}, - 'pypy_73-win32': {'vcruntime140.dll'}, - 'pypy_73-win_amd64': {'vcruntime140.dll'}, - 'cp32m-win32': {'msvcr90.dll'}, - 'cp32m-win_amd64': {'msvcr90.dll'}, - 'cp33m-win32': {'msvcr100.dll'}, - 'cp33m-win_amd64': {'msvcr100.dll'}, - 'cp34m-win32': {'msvcr100.dll'}, - 'cp34m-win_amd64': {'msvcr100.dll'}, - 'cp35m-win32': {'vcruntime140.dll'}, - 'cp35dm-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp35m-win_amd64': {'vcruntime140.dll'}, - 'cp35dm-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp36m-win32': {'vcruntime140.dll'}, - 'cp36dm-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp36m-win_amd64': {'vcruntime140.dll'}, - 'cp36dm-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'pypy36_pp73-win32': {'vcruntime140.dll'}, - 'cp37m-win32': {'vcruntime140.dll'}, - 'cp37dm-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp37m-win_amd64': {'vcruntime140.dll'}, - 'cp37dm-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'pypy37_pp73-win32': {'vcruntime140.dll'}, - 'pypy37_pp73-win_amd64': {'vcruntime140.dll'}, - 'cp38-win32': {'vcruntime140.dll'}, - 'cp38d-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp38-win_amd64': {'vcruntime140.dll'}, - 'cp38d-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'pypy38_pp73-win_amd64': {'vcruntime140.dll'}, - 'cp39-win32': {'vcruntime140.dll'}, - 'cp39d-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp39-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp39d-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp39-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp39d-win_arm64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'pypy39_pp73-win_amd64': {'vcruntime140.dll'}, - 'cp310-win32': {'vcruntime140.dll'}, - 'cp310d-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp310-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp310d-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp310-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp310d-win_arm64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'pypy310_pp73-win_amd64': {'vcruntime140.dll'}, - 'cp311-win32': {'vcruntime140.dll'}, - 'cp311d-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp311-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp311d-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp311-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp311d-win_arm64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp312-win32': {'vcruntime140.dll'}, - 'cp312d-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp312-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp312d-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp312-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp312d-win_arm64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp313-win32': {'vcruntime140.dll'}, - 'cp313t-win32': {'vcruntime140.dll'}, - 'cp313d-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp313dt-win32': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp313-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp313t-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp313d-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp313dt-win_amd64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp313-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp313t-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp313d-win_arm64': {'vcruntime140d.dll', 'ucrtbased.dll'}, - 'cp313dt-win_arm64': {'vcruntime140d.dll', 'ucrtbased.dll'}, } # DLLs to ignore based on Python tag and platform tag for a wheel that uses the @@ -132,29 +79,12 @@ def platform_tag_to_type(cls, tag: str) -> typing.Optional['MachineType']: # vcruntime140_1.dll shouldn't be included, but see the above comment for # ignore_by_abi_platform. ignore_abi3 = { - 'cp35-win32': {'vcruntime140.dll'}, - 'cp35-win_amd64': {'vcruntime140.dll'}, - 'cp36-win32': {'vcruntime140.dll'}, - 'cp36-win_amd64': {'vcruntime140.dll'}, - 'cp37-win32': {'vcruntime140.dll'}, - 'cp37-win_amd64': {'vcruntime140.dll'}, - 'cp38-win32': {'vcruntime140.dll'}, - 'cp38-win_amd64': {'vcruntime140.dll'}, - 'cp39-win32': {'vcruntime140.dll'}, - 'cp39-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp39-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp310-win32': {'vcruntime140.dll'}, - 'cp310-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp310-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp311-win32': {'vcruntime140.dll'}, - 'cp311-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp311-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp312-win32': {'vcruntime140.dll'}, - 'cp312-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp312-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp313-win32': {'vcruntime140.dll'}, - 'cp313-win_amd64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, - 'cp313-win_arm64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, + # current and future Python versions through 3.99 + 'cp3(9|[1-9][0-9])-win_a(md|rm)64': {'vcruntime140.dll', 'vcruntime140_1.dll'}, + 'cp3(9|[1-9][0-9])-win32': {'vcruntime140.dll'}, + + # older versions of Python + 'cp3[5-8]-win(32|_amd64)': {'vcruntime140.dll'}, } # Dependency relationships to ignore. diff --git a/delvewheel/_wheel_repair.py b/delvewheel/_wheel_repair.py index de778d0..f143363 100644 --- a/delvewheel/_wheel_repair.py +++ b/delvewheel/_wheel_repair.py @@ -200,9 +200,10 @@ def __init__(self, raise NotImplementedError('Wheels targeting multiple CPU architectures are not supported') ignore_by_abi_platform = set().union(*_dll_list.ignore_by_abi_platform.values()) for abi_tag in abi_tags: - abi_platform = f'{abi_tag}-{platform_tag}' - if abi_platform in _dll_list.ignore_by_abi_platform: - ignore_by_abi_platform &= _dll_list.ignore_by_abi_platform[abi_platform] + for abi_platform_re in _dll_list.ignore_by_abi_platform: + if re.match(abi_platform_re, f'{abi_tag}-{platform_tag}'): + ignore_by_abi_platform &= _dll_list.ignore_by_abi_platform[abi_platform_re] + break else: ignore_by_abi_platform = set() break @@ -212,9 +213,10 @@ def __init__(self, if abi_tags == ['abi3']: ignore_abi3 = set().union(*_dll_list.ignore_abi3.values()) for python_tag in python_tags: - python_platform = f'{python_tag}-{platform_tag}' - if python_platform in _dll_list.ignore_abi3: - ignore_abi3 &= _dll_list.ignore_abi3[python_platform] + for python_platform_re in _dll_list.ignore_abi3: + if re.match(python_platform_re, f'{python_tag}-{platform_tag}'): + ignore_abi3 &= _dll_list.ignore_abi3[python_platform_re] + break else: ignore_abi3 = set() break