Skip to content

Commit 81d30a5

Browse files
committed
refactor: use run-like syntax
1 parent 63bb5e6 commit 81d30a5

File tree

3 files changed

+100
-76
lines changed

3 files changed

+100
-76
lines changed

cibuildwheel/macos.py

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import os
22
import platform
33
import re
4-
import shlex
54
import shutil
65
import subprocess
76
import sys
87
import tempfile
98
from pathlib import Path
10-
from typing import Any, Dict, List, NamedTuple, Optional, Sequence, Set, Tuple, cast
9+
from typing import Any, Dict, List, NamedTuple, Sequence, Set, Tuple, cast
1110

1211
from .architecture import Architecture
1312
from .environment import ParsedEnvironment
@@ -23,25 +22,11 @@
2322
install_certifi_script,
2423
prepare_command,
2524
read_python_configs,
25+
run,
2626
unwrap,
2727
)
2828

2929

30-
def call(
31-
args: Sequence[PathOrStr],
32-
env: Optional[Dict[str, str]] = None,
33-
cwd: Optional[str] = None,
34-
shell: bool = False,
35-
) -> None:
36-
# print the command executing for the logs
37-
if shell:
38-
print(f"+ {args}")
39-
else:
40-
print("+ " + " ".join(shlex.quote(str(a)) for a in args))
41-
42-
subprocess.run(args, env=env, cwd=cwd, shell=shell, check=True)
43-
44-
4530
def get_macos_version() -> Tuple[int, int]:
4631
"""
4732
Returns the macOS major/minor version, as a tuple, e.g. (10, 15) or (11, 0)
@@ -147,8 +132,11 @@ def install_cpython(version: str, url: str) -> Path:
147132
# download the pkg
148133
download(url, Path("/tmp/Python.pkg"))
149134
# install
150-
call(["sudo", "installer", "-pkg", "/tmp/Python.pkg", "-target", "/"])
151-
call(["sudo", str(installation_bin_path / python_executable), str(install_certifi_script)])
135+
run(["sudo", "installer", "-pkg", "/tmp/Python.pkg", "-target", "/"], check=True)
136+
run(
137+
["sudo", str(installation_bin_path / python_executable), str(install_certifi_script)],
138+
check=True,
139+
)
152140

153141
pip_executable = "pip3"
154142
make_symlinks(installation_bin_path, python_executable, pip_executable)
@@ -165,7 +153,7 @@ def install_pypy(version: str, url: str) -> Path:
165153
if not installation_path.exists():
166154
downloaded_tar_bz2 = Path("/tmp") / pypy_tar_bz2
167155
download(url, downloaded_tar_bz2)
168-
call(["tar", "-C", "/tmp", "-xf", downloaded_tar_bz2])
156+
run(["tar", "-C", "/tmp", "-xf", downloaded_tar_bz2], check=True)
169157

170158
installation_bin_path = installation_path / "bin"
171159
python_executable = "pypy3"
@@ -216,8 +204,8 @@ def setup_python(
216204
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
217205

218206
# check what version we're on
219-
call(["which", "python"], env=env)
220-
call(["python", "--version"], env=env)
207+
run(["which", "python"], env=env, check=True)
208+
run(["python", "--version"], env=env, check=True)
221209
which_python = subprocess.run(
222210
["which", "python"], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE
223211
).stdout.strip()
@@ -229,10 +217,10 @@ def setup_python(
229217
sys.exit(1)
230218

231219
# install pip & wheel
232-
call(["python", get_pip_script, *dependency_constraint_flags], env=env, cwd="/tmp")
220+
run(["python", get_pip_script, *dependency_constraint_flags], env=env, cwd="/tmp", check=True)
233221
assert (installation_bin_path / "pip").exists()
234-
call(["which", "pip"], env=env)
235-
call(["pip", "--version"], env=env)
222+
run(["which", "pip"], env=env, check=True)
223+
run(["pip", "--version"], env=env, check=True)
236224
which_pip = subprocess.run(
237225
["which", "pip"], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE
238226
).stdout.strip()
@@ -290,7 +278,7 @@ def setup_python(
290278
env.setdefault("SDKROOT", arm64_compatible_sdks[0])
291279

292280
log.step("Installing build tools...")
293-
call(
281+
run(
294282
[
295283
"pip",
296284
"install",
@@ -301,6 +289,7 @@ def setup_python(
301289
*dependency_constraint_flags,
302290
],
303291
env=env,
292+
check=True,
304293
)
305294

306295
return env
@@ -319,7 +308,7 @@ def build(options: BuildOptions) -> None:
319308
before_all_prepared = prepare_command(
320309
options.before_all, project=".", package=options.package_dir
321310
)
322-
call([before_all_prepared], shell=True, env=env)
311+
run([before_all_prepared], shell=True, env=env, check=True)
323312

324313
python_configurations = get_python_configurations(
325314
options.build_selector, options.architectures
@@ -345,7 +334,7 @@ def build(options: BuildOptions) -> None:
345334
before_build_prepared = prepare_command(
346335
options.before_build, project=".", package=options.package_dir
347336
)
348-
call(before_build_prepared, env=env, shell=True)
337+
run(before_build_prepared, env=env, shell=True, check=True)
349338

350339
log.step("Building wheel...")
351340
if built_wheel_dir.exists():
@@ -354,7 +343,7 @@ def build(options: BuildOptions) -> None:
354343

355344
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
356345
# see https://github.com/joerick/cibuildwheel/pull/369
357-
call(
346+
run(
358347
[
359348
"pip",
360349
"wheel",
@@ -365,6 +354,7 @@ def build(options: BuildOptions) -> None:
365354
*get_build_verbosity_extra_flags(options.build_verbosity),
366355
],
367356
env=env,
357+
check=True,
368358
)
369359

370360
built_wheel = next(built_wheel_dir.glob("*.whl"))
@@ -392,7 +382,7 @@ def build(options: BuildOptions) -> None:
392382
dest_dir=repaired_wheel_dir,
393383
delocate_archs=delocate_archs,
394384
)
395-
call(repair_command_prepared, env=env, shell=True)
385+
run(repair_command_prepared, env=env, shell=True, check=True)
396386
else:
397387
shutil.move(str(built_wheel), repaired_wheel_dir)
398388

@@ -457,7 +447,11 @@ def build(options: BuildOptions) -> None:
457447

458448
# set up a virtual environment to install and test from, to make sure
459449
# there are no dependencies that were pulled in at build time.
460-
call(["pip", "install", "virtualenv", *dependency_constraint_flags], env=env)
450+
run(
451+
["pip", "install", "virtualenv", *dependency_constraint_flags],
452+
env=env,
453+
check=True,
454+
)
461455
venv_dir = Path(tempfile.mkdtemp())
462456

463457
arch_prefix = []
@@ -470,18 +464,20 @@ def build(options: BuildOptions) -> None:
470464
"don't know how to emulate {testing_arch} on {machine_arch}"
471465
)
472466

473-
# define a custom 'call' function that adds the arch prefix each time
474-
def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
467+
# define a custom 'run' function that adds the arch prefix each time
468+
def run_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
475469
if isinstance(args, str):
476470
args = " ".join(arch_prefix) + " " + args
477471
else:
478472
args = [*arch_prefix, *args]
479-
call(args, **kwargs)
473+
run(args, **kwargs)
480474

481475
# Use --no-download to ensure determinism by using seed libraries
482476
# built into virtualenv
483-
call_with_arch(
484-
["python", "-m", "virtualenv", "--no-download", venv_dir], env=env
477+
run_with_arch(
478+
["python", "-m", "virtualenv", "--no-download", venv_dir],
479+
env=env,
480+
check=True,
485481
)
486482

487483
virtualenv_env = env.copy()
@@ -493,24 +489,29 @@ def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
493489
)
494490

495491
# check that we are using the Python from the virtual environment
496-
call_with_arch(["which", "python"], env=virtualenv_env)
492+
run_with_arch(["which", "python"], env=virtualenv_env, check=True)
497493

498494
if options.before_test:
499495
before_test_prepared = prepare_command(
500496
options.before_test, project=".", package=options.package_dir
501497
)
502-
call_with_arch(before_test_prepared, env=virtualenv_env, shell=True)
498+
run_with_arch(
499+
before_test_prepared, env=virtualenv_env, shell=True, check=True
500+
)
503501

504502
# install the wheel
505-
call_with_arch(
503+
run_with_arch(
506504
["pip", "install", f"{repaired_wheel}{options.test_extras}"],
507505
env=virtualenv_env,
506+
check=True,
508507
)
509508

510509
# test the wheel
511510
if options.test_requires:
512-
call_with_arch(
513-
["pip", "install"] + options.test_requires, env=virtualenv_env
511+
run_with_arch(
512+
["pip", "install"] + options.test_requires,
513+
env=virtualenv_env,
514+
check=True,
514515
)
515516

516517
# run the tests from $HOME, with an absolute path in the command
@@ -521,11 +522,12 @@ def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
521522
project=Path(".").resolve(),
522523
package=options.package_dir.resolve(),
523524
)
524-
call_with_arch(
525+
run_with_arch(
525526
test_command_prepared,
526527
cwd=os.environ["HOME"],
527528
env=virtualenv_env,
528529
shell=True,
530+
check=True,
529531
)
530532

531533
# clean up

cibuildwheel/util.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
import itertools
44
import os
55
import re
6+
import shlex
67
import ssl
8+
import subprocess
9+
import sys
710
import textwrap
811
import time
912
import urllib.request
1013
from enum import Enum
1114
from pathlib import Path
1215
from time import sleep
13-
from typing import Dict, Iterator, List, NamedTuple, Optional, Set
16+
from typing import Any, Dict, Iterator, List, NamedTuple, Optional, Sequence, Set, Union
1417

1518
import bracex
1619
import certifi
@@ -26,6 +29,25 @@
2629

2730
get_pip_script = resources_dir / "get-pip.py"
2831
install_certifi_script = resources_dir / "install_certifi.py"
32+
IS_WIN = sys.platform.startswith("win")
33+
34+
35+
def run(
36+
args: Union[Sequence[PathOrStr], str],
37+
shell: bool = IS_WIN,
38+
**kwargs: Any,
39+
) -> subprocess.CompletedProcess[str]:
40+
"""
41+
Run subprocess.run, but print the commands first. Takes the commands as
42+
*args. Should use shell=True on Windows due to a bug
43+
https://bugs.python.org/issue8557
44+
"""
45+
print(
46+
f"+ {args}"
47+
if isinstance(args, str)
48+
else ("+ " + " ".join(shlex.quote(str(a)) for a in args))
49+
)
50+
return subprocess.run(args, shell=shell, **kwargs)
2951

3052

3153
def prepare_command(command: str, **kwargs: PathOrStr) -> str:

0 commit comments

Comments
 (0)