From 529158ae1f0826cc705f94c8cb57d06cd24fd815 Mon Sep 17 00:00:00 2001 From: Kyle Benesch <4b796c65+github@gmail.com> Date: Thu, 2 Jan 2025 22:58:27 -0800 Subject: [PATCH] Suppress macholib header parse error Macholib raises ValueError when failing to parse files which can be used to detect if the file is a Mach-O object. It is also raised on Mach-O objects it doesn't know how to handle. Checking for this error means `_is_macho_file` is redundant. --- Changelog.md | 4 ++++ delocate/delocating.py | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 1177ec38..6a3d66eb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -34,6 +34,10 @@ rules on making a good Changelog. - `delocate-merge` now supports libraries with missing or unusual extensions. [#228](https://github.com/matthew-brett/delocate/issues/228) - Now supports library files ending in parentheses. +- Fixed `Unknown Mach-O header` error when encountering a fat static library. + These files will be ignored until + [macholib](https://github.com/ronaldoussoren/macholib) supports them. + [#229](https://github.com/matthew-brett/delocate/issues/229) ### Removed diff --git a/delocate/delocating.py b/delocate/delocating.py index 4f71f64f..112ea4c1 100644 --- a/delocate/delocating.py +++ b/delocate/delocating.py @@ -40,7 +40,6 @@ from .pkginfo import read_pkg_info, write_pkg_info from .tmpdirs import TemporaryDirectory from .tools import ( - _is_macho_file, _remove_absolute_rpaths, dir2zip, find_package_dirs, @@ -599,9 +598,16 @@ def _get_macos_min_version(dylib_path: Path) -> Iterator[tuple[str, Version]]: Version The minimum macOS version. """ - if not _is_macho_file(dylib_path): - return - for header in MachO(dylib_path).headers: + try: + macho = MachO(dylib_path) + except ValueError as exc: + if str(exc.args[0]).startswith( + ("Unknown fat header magic", "Unknown Mach-O header") + ): + return # Not a recognised Mach-O object file + raise # Unexpected error + + for header in macho.headers: for cmd in header.commands: if cmd[0].cmd == LC_BUILD_VERSION: version = cmd[1].minos @@ -798,6 +804,8 @@ def _calculate_minimum_wheel_name( all_library_versions: dict[str, dict[Version, list[Path]]] = {} for lib in wheel_dir.glob("**/*"): + if lib.is_dir(): + continue for arch, version in _get_macos_min_version(lib): all_library_versions.setdefault(arch.lower(), {}).setdefault( version, []