diff --git a/requirements-repair.txt b/requirements-repair.txt index 2ca56a4..de121f3 100644 --- a/requirements-repair.txt +++ b/requirements-repair.txt @@ -1,2 +1 @@ -git+https://github.com/jcfr/wheeltools.git@wheeltools-2018-10-28-a2f174d0e -wheel<0.38 +wheel>=0.40.0 diff --git a/scripts/convert_to_generic_platform_wheel.py b/scripts/convert_to_generic_platform_wheel.py deleted file mode 100644 index 7296d73..0000000 --- a/scripts/convert_to_generic_platform_wheel.py +++ /dev/null @@ -1,208 +0,0 @@ -# -*- coding: utf-8 -*- -import argparse -import logging -import os -import sys -from itertools import product -from os.path import abspath, basename, dirname, isfile, splitext -from os.path import join as pjoin - -try: - from wheel.install import WheelFile -except ImportError: # As of Wheel 0.32.0 - from wheel.wheelfile import WheelFile - -from wheel.pkginfo import read_pkg_info, write_pkg_info -from wheeltools.tools import unique_by_index -from wheeltools.wheeltools import InWheelCtx - -logger = logging.getLogger(splitext(basename(__file__))[0]) - - -def _get_wheelinfo_name(wheelfile): - # Work round wheel API compatibility - try: - return wheelfile.wheelinfo_name - except AttributeError: - return wheelfile.dist_info_path + "/WHEEL" - - -def _to_generic_pyver(pyver_tags): - """Convert from CPython implementation to generic python version tags - - Convert each CPython version tag to the equivalent generic tag. - - For example:: - - cp35 -> py3 - cp27 -> py2 - - See https://www.python.org/dev/peps/pep-0425/#python-tag - """ - return ['py%s' % tag[2] if tag.startswith('cp') else tag for tag in pyver_tags] - - -def _convert_to_generic_platform_wheel(wheel_ctx, py2_py3, additional_platforms): - """Switch to generic python tags and remove ABI tags from a wheel - - Convert implementation specific python tags to their generic equivalent and - remove all ABI tags from wheel_ctx's filename and ``WHEEL`` file. - - Parameters - ---------- - wheel_ctx : InWheelCtx - An open wheel context - py2_py3: Bool - Whether the pyver tag shall be py2.py3 or just the one inferred from the wheel name - additional_platforms : Optional[Iterable[str]] - An optional iterable of additional platform to add to the wheel - """ - - abi_tags = ['none'] - - wf = WheelFile(wheel_ctx.in_wheel) - info_fname = _get_wheelinfo_name(wf) - info = read_pkg_info(info_fname) - - # Check what tags we have - if wheel_ctx.out_wheel is not None: - out_dir = dirname(wheel_ctx.out_wheel) - wheel_fname = basename(wheel_ctx.out_wheel) - else: - out_dir = '.' - wheel_fname = basename(wheel_ctx.in_wheel) - - # Update wheel filename - fparts = wf.parsed_filename.groupdict() - platform_tags = fparts['plat'].split('.') - logger.debug('Previous platform tags: %s', ', '.join(platform_tags)) - if additional_platforms: - platform_tags = sorted(set(platform_tags + list(additional_platforms))) - fparts['plat'] = '.'.join(platform_tags) - logger.debug('New platform tags ....: %s', ', '.join(platform_tags)) - else: - logger.debug('No platform tags change needed.') - - original_abi_tags = fparts['abi'].split('.') - logger.debug('Previous ABI tags: %s', ', '.join(original_abi_tags)) - if abi_tags != original_abi_tags: - logger.debug('New ABI tags ....: %s', ', '.join(abi_tags)) - fparts['abi'] = '.'.join(abi_tags) - else: - logger.debug('No ABI tags change needed.') - - original_pyver_tags = fparts['pyver'].split('.') - logger.debug('Previous pyver tags: %s', ', '.join(original_pyver_tags)) - pyver_tags = _to_generic_pyver(original_pyver_tags) - if py2_py3: - if len({"py2", "py3"} & set(pyver_tags)) == 0: - raise ValueError("pyver_tags does not contain py2 nor py3") - pyver_tags = sorted(set(pyver_tags + ["py2", "py3"])) - if pyver_tags != original_pyver_tags: - logger.debug('New pyver tags ....: %s', ', '.join(pyver_tags)) - fparts['pyver'] = '.'.join(pyver_tags) - else: - logger.debug('No pyver change needed.') - - _, ext = splitext(wheel_fname) - fparts['ext'] = ext - out_wheel_fname = "{namever}-{pyver}-{abi}-{plat}{ext}".format(**fparts) - - logger.info('Previous filename: %s', wheel_fname) - if out_wheel_fname != wheel_fname: - logger.info('New filename ....: %s', out_wheel_fname) - else: - logger.info('No filename change needed.') - - out_wheel = pjoin(out_dir, out_wheel_fname) - - # Update wheel tags - in_info_tags = [tag for name, tag in info.items() if name == 'Tag'] - logger.info('Previous WHEEL info tags: %s', ', '.join(in_info_tags)) - - # Python version, C-API version combinations - pyc_apis = [] - for py_ver in pyver_tags: - abi = 'none' - pyc_apis.append('-'.join([py_ver, abi])) - # unique Python version, C-API version combinations - pyc_apis = unique_by_index(pyc_apis) - - # Set tags for each Python version, C-API combination - updated_tags = ['-'.join(tup) for tup in product(pyc_apis, platform_tags)] - - if updated_tags != in_info_tags: - del info['Tag'] - for tag in updated_tags: - info.add_header('Tag', tag) - - logger.info('New WHEEL info tags ....: %s', ', '.join(info.get_all('Tag'))) - write_pkg_info(info_fname, info) - else: - logger.info('No WHEEL info change needed.') - return out_wheel - - -def convert_to_generic_platform_wheel(wheel_path, out_dir='./dist/', remove_original=False, verbose=0, - py2_py3=False, additional_platforms=None): - logging.disable(logging.NOTSET) - if verbose >= 1: - logging.basicConfig(level=logging.DEBUG) - else: - logging.basicConfig(level=logging.INFO) - - wheel_fname = basename(wheel_path) - out_dir = abspath(out_dir) - - with InWheelCtx(wheel_path) as ctx: - ctx.out_wheel = pjoin(out_dir, wheel_fname) - ctx.out_wheel = _convert_to_generic_platform_wheel(ctx, py2_py3, additional_platforms) - - if remove_original: - logger.info('Removed original wheel %s', wheel_path) - os.remove(wheel_path) - - -def main(): - p = argparse.ArgumentParser(description='Convert wheel to be independent of python implementation and ABI') - p.set_defaults(prog=basename(sys.argv[0])) - p.add_argument("-v", - "--verbose", - action='count', - dest='verbose', - default=0, - help='Give more output. Option is additive') - - p.add_argument('WHEEL_FILE', help='Path to wheel file.') - p.add_argument('-w', - '--wheel-dir', - dest='WHEEL_DIR', - type=abspath, - help='Directory to store updated wheels (default: "dist/")', - default='dist/') - p.add_argument("-r", - "--remove-original", - dest='remove_original', - action='store_true', - help='Remove original wheel') - p.add_argument("--py2-py3", - dest='py2_py3', - action='store_true', - help='Remove original wheel') - p.add_argument("-p", - "--add-platform", - dest='additional_platforms', - action="append", - help='Add a platform tag') - - args = p.parse_args() - - if not isfile(args.WHEEL_FILE): - p.error('cannot access %s. No such file' % args.WHEEL_FILE) - - convert_to_generic_platform_wheel(args.WHEEL_FILE, args.WHEEL_DIR, args.remove_original, args.verbose, - args.py2_py3, args.additional_platforms) - - -if __name__ == '__main__': - main() diff --git a/scripts/repair_wheel.py b/scripts/repair_wheel.py index 737df38..b7e14a0 100644 --- a/scripts/repair_wheel.py +++ b/scripts/repair_wheel.py @@ -8,8 +8,6 @@ import zipfile from pathlib import Path -from convert_to_generic_platform_wheel import convert_to_generic_platform_wheel - def main(): if sys.platform.startswith("linux"): @@ -56,8 +54,8 @@ def main(): assert len(files) == 1, files file = files[0] - # we need to handle macOS x86_64 & arm64 here for now, let's use additional_platforms for this. - additional_platforms = [] + # we need to handle macOS x86_64 & arm64 here for now, let's use platform_tag_args for this. + platform_tag_args = [] if os_ == "macos": # delocate-wheel --require-archs does not seem to check executables... with tempfile.TemporaryDirectory() as tmpdir2_: @@ -67,7 +65,7 @@ def main(): exe = list(tmpdir2.glob("**/bin/ninja")) assert len(exe) == 1, exe subprocess.run(["lipo", str(exe[0]), "-verify_arch", "x86_64", "arm64"], check=True, stdout=subprocess.PIPE) - + additional_platforms = [] # first, get the target macOS deployment target from the wheel match = re.match(r"^.*-macosx_(\d+)_(\d+)_.*\.whl$", file.name) assert match is not None, f"Couldn't match on {file.name}" @@ -88,13 +86,18 @@ def main(): # They're were also issues with pip not picking up some universal2 wheels, tag twice additional_platforms.append("macosx_11_0_universal2") + platform_tag_args = [f"--platform-tag=+{'.'.join(additional_platforms)}"] + # make this a py2.py3 wheel - convert_to_generic_platform_wheel( - str(file), - out_dir=str(wheelhouse), - py2_py3=True, - additional_platforms=additional_platforms, + subprocess.run( + ["wheel", "tags", "--python-tag", "py2.py3", "--abi-tag", "none", *platform_tag_args, "--remove", str(file)], + check=True, + stdout=subprocess.PIPE, ) + files = list(tmpdir.glob("*.whl")) + assert len(files) == 1, files + file = files[0] + file.rename(wheelhouse / file.name) if __name__ == "__main__":