Skip to content

Commit 9e18cb8

Browse files
authored
refactor: Use utils.call & utils.shell in macos.py & windows.py (#978)
1 parent 73b7de0 commit 9e18cb8

File tree

3 files changed

+196
-206
lines changed

3 files changed

+196
-206
lines changed

cibuildwheel/macos.py

Lines changed: 69 additions & 108 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
@@ -18,31 +17,18 @@
1817
BuildFrontend,
1918
BuildSelector,
2019
NonPlatformWheelError,
20+
call,
2121
download,
2222
get_build_verbosity_extra_flags,
2323
get_pip_version,
2424
install_certifi_script,
2525
prepare_command,
2626
read_python_configs,
27+
shell,
2728
unwrap,
2829
)
2930

3031

31-
def call(
32-
args: Sequence[PathOrStr],
33-
env: Optional[Dict[str, str]] = None,
34-
cwd: Optional[str] = None,
35-
shell: bool = False,
36-
) -> None:
37-
# print the command executing for the logs
38-
if shell:
39-
print(f"+ {args}")
40-
else:
41-
print("+ " + " ".join(shlex.quote(str(a)) for a in args))
42-
43-
subprocess.run(args, env=env, cwd=cwd, shell=shell, check=True)
44-
45-
4632
def get_macos_version() -> Tuple[int, int]:
4733
"""
4834
Returns the macOS major/minor version, as a tuple, e.g. (10, 15) or (11, 0)
@@ -58,13 +44,7 @@ def get_macos_version() -> Tuple[int, int]:
5844

5945

6046
def get_macos_sdks() -> List[str]:
61-
output = subprocess.run(
62-
["xcodebuild", "-showsdks"],
63-
universal_newlines=True,
64-
check=True,
65-
stdout=subprocess.PIPE,
66-
).stdout
67-
47+
output = call("xcodebuild", "-showsdks", capture_stdout=True)
6848
return [m.group(1) for m in re.finditer(r"-sdk (macosx\S+)", output)]
6949

7050

@@ -114,9 +94,7 @@ def make_symlinks(installation_bin_path: Path, python_executable: str, pip_execu
11494

11595

11696
def install_cpython(version: str, url: str) -> Path:
117-
installed_system_packages = subprocess.run(
118-
["pkgutil", "--pkgs"], universal_newlines=True, check=True, stdout=subprocess.PIPE
119-
).stdout.splitlines()
97+
installed_system_packages = call("pkgutil", "--pkgs", capture_stdout=True).splitlines()
12098

12199
# if this version of python isn't installed, get it from python.org and install
122100
python_package_identifier = f"org.python.Python.PythonFramework-{version}"
@@ -127,10 +105,10 @@ def install_cpython(version: str, url: str) -> Path:
127105
# download the pkg
128106
download(url, Path("/tmp/Python.pkg"))
129107
# install
130-
call(["sudo", "installer", "-pkg", "/tmp/Python.pkg", "-target", "/"])
108+
call("sudo", "installer", "-pkg", "/tmp/Python.pkg", "-target", "/")
131109
env = os.environ.copy()
132110
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
133-
call([str(installation_bin_path / python_executable), str(install_certifi_script)], env=env)
111+
call(str(installation_bin_path / python_executable), str(install_certifi_script), env=env)
134112

135113
pip_executable = "pip3"
136114
make_symlinks(installation_bin_path, python_executable, pip_executable)
@@ -147,7 +125,7 @@ def install_pypy(version: str, url: str) -> Path:
147125
if not installation_path.exists():
148126
downloaded_tar_bz2 = Path("/tmp") / pypy_tar_bz2
149127
download(url, downloaded_tar_bz2)
150-
call(["tar", "-C", "/tmp", "-xf", downloaded_tar_bz2])
128+
call("tar", "-C", "/tmp", "-xf", downloaded_tar_bz2)
151129

152130
installation_bin_path = installation_path / "bin"
153131
python_executable = "pypy3"
@@ -203,20 +181,18 @@ def setup_python(
203181
requires_reinstall = not (installation_bin_path / "pip").exists()
204182
if requires_reinstall:
205183
# maybe pip isn't installed at all. ensurepip resolves that.
206-
call(["python", "-m", "ensurepip"], env=env, cwd="/tmp")
184+
call("python", "-m", "ensurepip", env=env, cwd="/tmp")
207185

208186
# upgrade pip to the version matching our constraints
209187
# if necessary, reinstall it to ensure that it's available on PATH as 'pip'
210188
call(
211-
[
212-
"python",
213-
"-m",
214-
"pip",
215-
"install",
216-
"--force-reinstall" if requires_reinstall else "--upgrade",
217-
"pip",
218-
*dependency_constraint_flags,
219-
],
189+
"python",
190+
"-m",
191+
"pip",
192+
"install",
193+
"--force-reinstall" if requires_reinstall else "--upgrade",
194+
"pip",
195+
*dependency_constraint_flags,
220196
env=env,
221197
cwd="/tmp",
222198
)
@@ -226,11 +202,9 @@ def setup_python(
226202

227203
# check what pip version we're on
228204
assert (installation_bin_path / "pip").exists()
229-
call(["which", "pip"], env=env)
230-
call(["pip", "--version"], env=env)
231-
which_pip = subprocess.run(
232-
["which", "pip"], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE
233-
).stdout.strip()
205+
call("which", "pip", env=env)
206+
call("pip", "--version", env=env)
207+
which_pip = call("which", "pip", env=env, capture_stdout=True).strip()
234208
if which_pip != "/tmp/cibw_bin/pip":
235209
print(
236210
"cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.",
@@ -239,11 +213,9 @@ def setup_python(
239213
sys.exit(1)
240214

241215
# check what Python version we're on
242-
call(["which", "python"], env=env)
243-
call(["python", "--version"], env=env)
244-
which_python = subprocess.run(
245-
["which", "python"], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE
246-
).stdout.strip()
216+
call("which", "python", env=env)
217+
call("python", "--version", env=env)
218+
which_python = call("which", "python", env=env, capture_stdout=True).strip()
247219
if which_python != "/tmp/cibw_bin/python":
248220
print(
249221
"cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
@@ -298,27 +270,23 @@ def setup_python(
298270
log.step("Installing build tools...")
299271
if build_frontend == "pip":
300272
call(
301-
[
302-
"pip",
303-
"install",
304-
"--upgrade",
305-
"setuptools",
306-
"wheel",
307-
"delocate",
308-
*dependency_constraint_flags,
309-
],
273+
"pip",
274+
"install",
275+
"--upgrade",
276+
"setuptools",
277+
"wheel",
278+
"delocate",
279+
*dependency_constraint_flags,
310280
env=env,
311281
)
312282
elif build_frontend == "build":
313283
call(
314-
[
315-
"pip",
316-
"install",
317-
"--upgrade",
318-
"delocate",
319-
"build[virtualenv]",
320-
*dependency_constraint_flags,
321-
],
284+
"pip",
285+
"install",
286+
"--upgrade",
287+
"delocate",
288+
"build[virtualenv]",
289+
*dependency_constraint_flags,
322290
env=env,
323291
)
324292
else:
@@ -347,7 +315,7 @@ def build(options: Options) -> None:
347315
before_all_prepared = prepare_command(
348316
before_all_options.before_all, project=".", package=before_all_options.package_dir
349317
)
350-
call([before_all_prepared], shell=True, env=env)
318+
shell(before_all_prepared, env=env)
351319

352320
for config in python_configurations:
353321
build_options = options.build_options(config.identifier)
@@ -375,7 +343,7 @@ def build(options: Options) -> None:
375343
before_build_prepared = prepare_command(
376344
build_options.before_build, project=".", package=build_options.package_dir
377345
)
378-
call(before_build_prepared, env=env, shell=True)
346+
shell(before_build_prepared, env=env)
379347

380348
log.step("Building wheel...")
381349
if built_wheel_dir.exists():
@@ -388,16 +356,14 @@ def build(options: Options) -> None:
388356
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
389357
# see https://github.com/pypa/cibuildwheel/pull/369
390358
call(
391-
[
392-
"python",
393-
"-m",
394-
"pip",
395-
"wheel",
396-
build_options.package_dir.resolve(),
397-
f"--wheel-dir={built_wheel_dir}",
398-
"--no-deps",
399-
*verbosity_flags,
400-
],
359+
"python",
360+
"-m",
361+
"pip",
362+
"wheel",
363+
build_options.package_dir.resolve(),
364+
f"--wheel-dir={built_wheel_dir}",
365+
"--no-deps",
366+
*verbosity_flags,
401367
env=env,
402368
)
403369
elif build_options.build_frontend == "build":
@@ -410,15 +376,13 @@ def build(options: Options) -> None:
410376
build_env["PIP_CONSTRAINT"] = constraint_path.as_uri()
411377
build_env["VIRTUALENV_PIP"] = get_pip_version(env)
412378
call(
413-
[
414-
"python",
415-
"-m",
416-
"build",
417-
build_options.package_dir,
418-
"--wheel",
419-
f"--outdir={built_wheel_dir}",
420-
f"--config-setting={config_setting}",
421-
],
379+
"python",
380+
"-m",
381+
"build",
382+
build_options.package_dir,
383+
"--wheel",
384+
f"--outdir={built_wheel_dir}",
385+
f"--config-setting={config_setting}",
422386
env=build_env,
423387
)
424388
else:
@@ -449,7 +413,7 @@ def build(options: Options) -> None:
449413
dest_dir=repaired_wheel_dir,
450414
delocate_archs=delocate_archs,
451415
)
452-
call(repair_command_prepared, env=env, shell=True)
416+
shell(repair_command_prepared, env=env)
453417
else:
454418
shutil.move(str(built_wheel), repaired_wheel_dir)
455419

@@ -514,7 +478,7 @@ def build(options: Options) -> None:
514478

515479
# set up a virtual environment to install and test from, to make sure
516480
# there are no dependencies that were pulled in at build time.
517-
call(["pip", "install", "virtualenv", *dependency_constraint_flags], env=env)
481+
call("pip", "install", "virtualenv", *dependency_constraint_flags, env=env)
518482
venv_dir = Path(tempfile.mkdtemp())
519483

520484
arch_prefix = []
@@ -528,18 +492,16 @@ def build(options: Options) -> None:
528492
)
529493

530494
# define a custom 'call' function that adds the arch prefix each time
531-
def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
532-
if isinstance(args, str):
533-
args = " ".join(arch_prefix) + " " + args
534-
else:
535-
args = [*arch_prefix, *args]
536-
call(args, **kwargs)
495+
def call_with_arch(*args: PathOrStr, **kwargs: Any) -> None:
496+
call(*arch_prefix, *args, **kwargs)
497+
498+
def shell_with_arch(command: str, **kwargs: Any) -> None:
499+
command = " ".join(arch_prefix) + " " + command
500+
shell(command, **kwargs)
537501

538502
# Use --no-download to ensure determinism by using seed libraries
539503
# built into virtualenv
540-
call_with_arch(
541-
["python", "-m", "virtualenv", "--no-download", venv_dir], env=env
542-
)
504+
call_with_arch("python", "-m", "virtualenv", "--no-download", venv_dir, env=env)
543505

544506
virtualenv_env = env.copy()
545507
virtualenv_env["PATH"] = os.pathsep.join(
@@ -550,26 +512,28 @@ def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
550512
)
551513

552514
# check that we are using the Python from the virtual environment
553-
call_with_arch(["which", "python"], env=virtualenv_env)
515+
call_with_arch("which", "python", env=virtualenv_env)
554516

555517
if build_options.before_test:
556518
before_test_prepared = prepare_command(
557519
build_options.before_test,
558520
project=".",
559521
package=build_options.package_dir,
560522
)
561-
call_with_arch(before_test_prepared, env=virtualenv_env, shell=True)
523+
shell_with_arch(before_test_prepared, env=virtualenv_env)
562524

563525
# install the wheel
564526
call_with_arch(
565-
["pip", "install", f"{repaired_wheel}{build_options.test_extras}"],
527+
"pip",
528+
"install",
529+
f"{repaired_wheel}{build_options.test_extras}",
566530
env=virtualenv_env,
567531
)
568532

569533
# test the wheel
570534
if build_options.test_requires:
571535
call_with_arch(
572-
["pip", "install"] + build_options.test_requires, env=virtualenv_env
536+
"pip", "install", *build_options.test_requires, env=virtualenv_env
573537
)
574538

575539
# run the tests from $HOME, with an absolute path in the command
@@ -580,11 +544,8 @@ def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
580544
project=Path(".").resolve(),
581545
package=build_options.package_dir.resolve(),
582546
)
583-
call_with_arch(
584-
test_command_prepared,
585-
cwd=os.environ["HOME"],
586-
env=virtualenv_env,
587-
shell=True,
547+
shell_with_arch(
548+
test_command_prepared, cwd=os.environ["HOME"], env=virtualenv_env
588549
)
589550

590551
# clean up

0 commit comments

Comments
 (0)