From 45a7969ab25dad1b3313be25c661e32a0002a9a5 Mon Sep 17 00:00:00 2001 From: Kyle Benesch <4b796c65+github@gmail.com> Date: Tue, 12 Dec 2023 01:27:59 -0800 Subject: [PATCH 1/2] Change VSCode fixAll setting to 'always' VSCode was automatically updating this option --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 2a70362d..47a5206a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,7 +4,7 @@ ], "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll": true, + "source.fixAll": "always" }, "[python]": { "editor.defaultFormatter": "charliermarsh.ruff" From 62f0a50ed6028ef89033b36278530fd291fbf16e Mon Sep 17 00:00:00 2001 From: Kyle Benesch <4b796c65+github@gmail.com> Date: Tue, 28 Nov 2023 18:15:31 -0800 Subject: [PATCH 2/2] Expand globs in script arguments Add glob script tests Some commands are too complex for this workaround --- Changelog.md | 6 ++++++ delocate/cmd/common.py | 19 ++++++++++++++++- delocate/cmd/delocate_addplat.py | 7 ++++--- delocate/cmd/delocate_listdeps.py | 7 ++++--- delocate/cmd/delocate_path.py | 6 ++++-- delocate/cmd/delocate_wheel.py | 8 +++++--- delocate/tests/test_scripts.py | 34 +++++++++++++++++++++++++++++++ 7 files changed, 75 insertions(+), 12 deletions(-) diff --git a/Changelog.md b/Changelog.md index b7ac909e..baa78d7b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,12 @@ rules on making a good Changelog. ## [Unreleased] +### Changed + +- Handle glob paths in more cases for `delocate-wheel`, `delocate-path`, + `delocate-listdeps`, and `delocate-addplat`. + [#71](https://github.com/matthew-brett/delocate/issues/71) + ### Fixed - No longer picks a random directory when multiple directories end with the diff --git a/delocate/cmd/common.py b/delocate/cmd/common.py index ab94a3ae..d4457e43 100644 --- a/delocate/cmd/common.py +++ b/delocate/cmd/common.py @@ -4,11 +4,13 @@ """ from __future__ import annotations +import glob import logging import os import sys from argparse import ArgumentParser, Namespace -from typing import Callable, List +from pathlib import Path +from typing import Callable, Iterable, Iterator, List from typing_extensions import Literal, TypedDict @@ -114,3 +116,18 @@ def copy_filter_exclude(name: str) -> bool: "ignore_missing": args.ignore_missing_dependencies, "sanitize_rpaths": args.sanitize_rpaths, } + + +def glob_paths(paths: Iterable[str]) -> Iterator[str]: + """Iterate over the expanded paths of potential glob paths. + + Does not try to glob paths which match existing files. + """ + for path in paths: + if Path(path).exists(): + yield path # Don't try to expand paths when their target exists + continue + expanded_paths = glob.glob(path) + if not expanded_paths: + raise FileNotFoundError(path) + yield from expanded_paths diff --git a/delocate/cmd/delocate_addplat.py b/delocate/cmd/delocate_addplat.py index 017f51ee..f858fe3d 100755 --- a/delocate/cmd/delocate_addplat.py +++ b/delocate/cmd/delocate_addplat.py @@ -21,7 +21,7 @@ from os.path import expanduser, realpath from os.path import join as exists -from delocate.cmd.common import common_parser, verbosity_config +from delocate.cmd.common import common_parser, glob_paths, verbosity_config from delocate.wheeltools import WheelToolsError, add_platforms parser = ArgumentParser(description=__doc__, parents=[common_parser]) @@ -94,7 +94,8 @@ def main() -> None: args = parser.parse_args() verbosity_config(args) - multi = len(args.wheels) > 1 + wheels = list(glob_paths(args.wheels)) + multi = len(wheels) > 1 if args.wheel_dir: wheel_dir = expanduser(args.wheel_dir) if not exists(wheel_dir): @@ -110,7 +111,7 @@ def main() -> None: ] if len(plat_tags) == 0: raise RuntimeError("Need at least one --osx-ver or --plat-tag") - for wheel in args.wheels: + for wheel in wheels: if multi or args.verbose: print( "Setting platform tags {0} for wheel {1}".format( diff --git a/delocate/cmd/delocate_listdeps.py b/delocate/cmd/delocate_listdeps.py index 391a5931..e9bc6911 100755 --- a/delocate/cmd/delocate_listdeps.py +++ b/delocate/cmd/delocate_listdeps.py @@ -10,7 +10,7 @@ from os.path import sep as psep from delocate import wheel_libs -from delocate.cmd.common import common_parser, verbosity_config +from delocate.cmd.common import common_parser, glob_paths, verbosity_config from delocate.delocating import filter_system_libs from delocate.libsana import stripped_lib_dict, tree_libs_from_directory @@ -40,8 +40,9 @@ def main() -> None: args = parser.parse_args() verbosity_config(args) - multi = len(args.paths) > 1 - for path in args.paths: + paths = list(glob_paths(args.paths)) + multi = len(paths) > 1 + for path in paths: if multi: print(path + ":") indent = " " diff --git a/delocate/cmd/delocate_path.py b/delocate/cmd/delocate_path.py index 7a5ecf15..a2dd101e 100755 --- a/delocate/cmd/delocate_path.py +++ b/delocate/cmd/delocate_path.py @@ -12,6 +12,7 @@ common_parser, delocate_parser, delocate_values, + glob_paths, verbosity_config, ) @@ -38,8 +39,9 @@ def main() -> None: args = parser.parse_args() verbosity_config(args) - multi = len(args.paths) > 1 - for path in args.paths: + paths = list(glob_paths(args.paths)) + multi = len(paths) > 1 + for path in paths: if multi: print(path) # evaluate paths relative to the path we are working on diff --git a/delocate/cmd/delocate_wheel.py b/delocate/cmd/delocate_wheel.py index 3bd24080..ebf29188 100755 --- a/delocate/cmd/delocate_wheel.py +++ b/delocate/cmd/delocate_wheel.py @@ -4,7 +4,7 @@ Overwrites the wheel in-place by default """ # vim: ft=python -from __future__ import absolute_import, division, print_function +from __future__ import annotations import os from argparse import ArgumentParser @@ -17,6 +17,7 @@ common_parser, delocate_parser, delocate_values, + glob_paths, verbosity_config, ) @@ -65,7 +66,8 @@ def main() -> None: args = parser.parse_args() verbosity_config(args) - multi = len(args.wheels) > 1 + wheels = list(glob_paths(args.wheels)) + multi = len(wheels) > 1 if args.wheel_dir: wheel_dir = expanduser(args.wheel_dir) if not exists(wheel_dir): @@ -80,7 +82,7 @@ def main() -> None: else: require_archs = args.require_archs - for wheel in args.wheels: + for wheel in wheels: if multi or args.verbose: print("Fixing: " + wheel) if wheel_dir: diff --git a/delocate/tests/test_scripts.py b/delocate/tests/test_scripts.py index 75c75009..ab0fe025 100644 --- a/delocate/tests/test_scripts.py +++ b/delocate/tests/test_scripts.py @@ -624,3 +624,37 @@ def test_sanitize_command(tmp_path: Path, script_runner: ScriptRunner) -> None: assert "libs/" not in set( get_rpaths(str(unpack_dir / "fakepkg/subpkg/module2.abi3.so")) ) + + +@pytest.mark.xfail( # type: ignore[misc] + sys.platform != "darwin", reason="Needs macOS linkage." +) +def test_glob( + tmp_path: Path, plat_wheel: PlatWheel, script_runner: ScriptRunner +) -> None: + # Test implicit globbing by passing "*.whl" without shell=True + script_runner.run(["delocate-listdeps", "*.whl"], check=True, cwd=tmp_path) + zip2dir(plat_wheel.whl, tmp_path / "plat") + + result = script_runner.run( + ["delocate-wheel", "*.whl", "-v"], check=True, cwd=tmp_path + ) + assert Path(plat_wheel.whl).name in result.stdout + assert "*.whl" not in result.stdout + assert not Path(tmp_path, "*.whl").exists() + + # Delocate literal file "*.whl" instead of expanding glob + shutil.copyfile(plat_wheel.whl, tmp_path / "*.whl") + result = script_runner.run( + ["delocate-wheel", "*.whl", "-v"], check=True, cwd=tmp_path + ) + assert Path(plat_wheel.whl).name not in result.stdout + assert "*.whl" in result.stdout + + Path(plat_wheel.whl).unlink() + Path(tmp_path, "*.whl").unlink() + result = script_runner.run(["delocate-wheel", "*.whl"], cwd=tmp_path) + assert result.returncode == 1 + assert "FileNotFoundError:" in result.stderr + + script_runner.run(["delocate-path", "*/"], check=True, cwd=tmp_path)