Skip to content

Commit f766904

Browse files
authored
Merge pull request #1258 from henryiii/henryiii/chore/dev
chore: nicer tracebacks and dev improvements
2 parents 73a435b + c302a1d commit f766904

19 files changed

+95
-58
lines changed

bin/inspect_all_known_projects.py

+33-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
#!/usr/bin/env python3
2+
3+
"""
4+
Check known projects for usage of requires-python.
5+
6+
Usage:
7+
8+
./bin/inspect_all_known_projects.py --online=$GITHUB_TOKEN
9+
10+
This will cache the results to all_known_setup.yaml; you can reprint
11+
the results without the `--online` setting.
12+
"""
13+
14+
215
from __future__ import annotations
316

417
import ast
@@ -7,7 +20,7 @@
720

821
import click
922
import yaml
10-
from ghapi.core import GhApi, HTTP404NotFoundError
23+
from github import Github, GithubException
1124
from rich import print
1225

1326
from cibuildwheel.projectfiles import Analyzer
@@ -47,33 +60,38 @@ def check_repo(name: str, contents: str) -> str:
4760

4861

4962
class MaybeRemote:
50-
def __init__(self, cached_file: Path | str, *, online: bool) -> None:
51-
self.online = online
52-
if self.online:
53-
self.contents: dict[str, dict[str, str | None]] = {
63+
github: Github | None
64+
contents: dict[str, dict[str, str | None]]
65+
66+
def __init__(self, cached_file: Path | str, *, online: str | None) -> None:
67+
if online is not None:
68+
self.github = Github(online)
69+
self.contents = {
5470
"setup.py": {},
5571
"setup.cfg": {},
5672
"pyproject.toml": {},
5773
}
5874
else:
75+
self.github = None
5976
with open(cached_file) as f:
6077
self.contents = yaml.safe_load(f)
6178

6279
def get(self, repo: str, filename: str) -> str | None:
63-
if self.online:
80+
if self.github:
6481
try:
65-
self.contents[filename][repo] = (
66-
GhApi(*repo.split("/")).get_content(filename).decode()
67-
)
68-
except HTTP404NotFoundError:
82+
gh_file = self.github.get_repo(repo).get_contents(filename)
83+
except GithubException:
6984
self.contents[filename][repo] = None
85+
else:
86+
assert not isinstance(gh_file, list)
87+
self.contents[filename][repo] = gh_file.decoded_content.decode(encoding="utf-8")
88+
7089
return self.contents[filename][repo]
7190
elif repo in self.contents[filename]:
7291
return self.contents[filename][repo]
7392
else:
74-
raise RuntimeError(
75-
f"Trying to access {repo}:{filename} and not in cache, rebuild cache"
76-
)
93+
msg = f"Trying to access {repo}:{filename} and not in cache, rebuild cache"
94+
raise RuntimeError(msg)
7795

7896
def save(self, filename: Path | str) -> None:
7997
with open(filename, "w") as f:
@@ -87,8 +105,8 @@ def on_each(self, repos: list[str]) -> Iterator[tuple[str, str, str | None]]:
87105

88106

89107
@click.command()
90-
@click.option("--online", is_flag=True, help="Remember to set GITHUB_TOKEN")
91-
def main(online: bool) -> None:
108+
@click.option("--online", help="Set to $GITHUB_TOKEN")
109+
def main(online: str | None) -> None:
92110
with open(DIR / "../docs/data/projects.yml") as f:
93111
known = yaml.safe_load(f)
94112

bin/run_example_ci_configs.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ def ci_service_for_config_file(config_file):
8181
if service.name == service_name:
8282
return service
8383

84-
raise ValueError(f"unknown ci service for config file {config_file}")
84+
msg = f"unknown ci service for config file {config_file}"
85+
raise ValueError(msg)
8586

8687

8788
@click.command()
@@ -100,7 +101,8 @@ def run_example_ci_configs(config_files=None):
100101
for config_file in config_files:
101102
service = ci_service_for_config_file(config_file)
102103
if service.name in configs_by_service:
103-
raise Exception("You cannot specify more than one config per CI service")
104+
msg = "You cannot specify more than one config per CI service"
105+
raise Exception(msg)
104106
configs_by_service[service.name] = config_file
105107

106108
if git_repo_has_changes():

bin/update_pythons.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ def update_version_windows(self, spec: Specifier) -> ConfigWinCP:
141141
releases = [r for r in releases if self.get_arch_file(r)]
142142

143143
if not releases:
144-
raise RuntimeError(f"PyPy Win {self.arch} not found for {spec}! {self.releases}")
144+
msg = f"PyPy Win {self.arch} not found for {spec}! {self.releases}"
145+
raise RuntimeError(msg)
145146

146147
version_arch = "win32" if self.arch == "32" else "win_amd64"
147148

@@ -159,13 +160,15 @@ def update_version_windows(self, spec: Specifier) -> ConfigWinCP:
159160

160161
def update_version_macos(self, spec: Specifier) -> ConfigMacOS:
161162
if self.arch != "64":
162-
raise RuntimeError("Other archs not supported yet on macOS")
163+
msg = "Other archs not supported yet on macOS"
164+
raise RuntimeError(msg)
163165

164166
releases = [r for r in self.releases if spec.contains(r["python_version"])]
165167
releases = sorted(releases, key=lambda r: r["pypy_version"]) # type: ignore[no-any-return]
166168

167169
if not releases:
168-
raise RuntimeError(f"PyPy macOS {self.arch} not found for {spec}!")
170+
msg = f"PyPy macOS {self.arch} not found for {spec}!"
171+
raise RuntimeError(msg)
169172

170173
release = releases[-1]
171174
version = release["python_version"]

cibuildwheel/__main__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ def main() -> None:
149149
try:
150150
(project_dir,) = temp_dir.iterdir()
151151
except ValueError:
152-
raise SystemExit("invalid sdist: didn't contain a single dir") from None
152+
msg = "invalid sdist: didn't contain a single dir"
153+
raise SystemExit(msg) from None
153154

154155
# This is now the new package dir
155156
args.package_dir = project_dir.resolve()

cibuildwheel/bashlex_eval.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ def evaluate(
3232
command_node = bashlex.parsesingle(value)
3333

3434
if len(command_node.parts) != 1:
35-
raise ValueError(f'"{value}" has too many parts')
35+
msg = f"{value!r} has too many parts"
36+
raise ValueError(msg)
3637

3738
value_word_node = command_node.parts[0]
3839

@@ -54,7 +55,8 @@ def evaluate_node(node: bashlex.ast.node, context: NodeExecutionContext) -> str:
5455
elif node.kind == "parameter":
5556
return evaluate_parameter_node(node, context=context)
5657
else:
57-
raise ValueError(f'Unsupported bash construct: "{node.kind}"')
58+
msg = f"Unsupported bash construct: {node.kind!r}"
59+
raise ValueError(msg)
5860

5961

6062
def evaluate_word_node(node: bashlex.ast.node, context: NodeExecutionContext) -> str:
@@ -65,10 +67,8 @@ def evaluate_word_node(node: bashlex.ast.node, context: NodeExecutionContext) ->
6567
part_value = evaluate_node(part, context=context)
6668

6769
if part_string not in value:
68-
raise RuntimeError(
69-
f'bash parse failed. part "{part_string}" not found in "{value}". '
70-
f'Word was "{node.word}". Full input was "{context.input}"'
71-
)
70+
msg = f"bash parse failed. part {part_string!r} not found in {value!r}. Word was {node.word!r}. Full input was {context.input!r}"
71+
raise RuntimeError(msg)
7272

7373
value = value.replace(part_string, part_value, 1)
7474

@@ -95,9 +95,11 @@ def evaluate_nodes_as_compound_command(
9595
result += evaluate_command_node(node, context=context)
9696
elif node.kind == "operator":
9797
if node.op != ";":
98-
raise ValueError(f'Unsupported bash operator: "{node.op}"')
98+
msg = f"Unsupported bash operator: {node.op!r}"
99+
raise ValueError(msg)
99100
else:
100-
raise ValueError(f'Unsupported bash node in compound command: "{node.kind}"')
101+
msg = f"Unsupported bash node in compound command: {node.kind!r}"
102+
raise ValueError(msg)
101103

102104
return result
103105

cibuildwheel/functools_cached_property_38.py

+4-7
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ def __set_name__(self, owner: type[Any], name: str) -> None:
2121
if self.attrname is None:
2222
self.attrname = name
2323
elif name != self.attrname:
24-
raise TypeError(
25-
"Cannot assign the same cached_property to two different names "
26-
f"({self.attrname!r} and {name!r})."
27-
)
24+
msg = f"Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r})."
25+
raise TypeError(msg)
2826

2927
@overload
3028
def __get__(self, instance: None, owner: type[Any] | None = ...) -> cached_property[_T]:
@@ -38,9 +36,8 @@ def __get__(self, instance: object | None, owner: type[Any] | None = None) -> An
3836
if instance is None:
3937
return self
4038
if self.attrname is None:
41-
raise TypeError(
42-
"Cannot use cached_property instance without calling __set_name__ on it."
43-
)
39+
msg = "Cannot use cached_property instance without calling __set_name__ on it."
40+
raise TypeError(msg)
4441
try:
4542
cache = instance.__dict__
4643
except AttributeError: # not all objects have __dict__ (e.g. class defines slots)

cibuildwheel/linux.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,8 @@ def build(options: Options, tmp_path: Path) -> None: # pylint: disable=unused-a
367367
cwd = Path.cwd()
368368
abs_package_dir = options.globals.package_dir.resolve()
369369
if cwd != abs_package_dir and cwd not in abs_package_dir.parents:
370-
raise Exception("package_dir must be inside the working directory")
370+
msg = "package_dir must be inside the working directory"
371+
raise Exception(msg)
371372

372373
container_project_path = PurePosixPath("/project")
373374
container_package_dir = container_project_path / abs_package_dir.relative_to(cwd)

cibuildwheel/logger.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,16 @@ def build_description_from_identifier(identifier: str) -> str:
197197
elif python_interpreter == "pp":
198198
build_description += "PyPy"
199199
else:
200-
raise Exception("unknown python")
200+
msg = f"unknown python {python_interpreter!r}"
201+
raise Exception(msg)
201202

202203
build_description += f" {python_version[0]}.{python_version[1:]} "
203204

204205
try:
205206
build_description += PLATFORM_IDENTIFIER_DESCRIPTIONS[platform_identifier]
206207
except KeyError as e:
207-
raise Exception("unknown platform") from e
208+
msg = f"unknown platform {platform_identifier!r}"
209+
raise Exception(msg) from e
208210

209211
return build_description
210212

cibuildwheel/macos.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ def setup_python(
146146
elif implementation_id.startswith("pp"):
147147
base_python = install_pypy(tmp, python_configuration.url)
148148
else:
149-
raise ValueError("Unknown Python implementation")
149+
msg = "Unknown Python implementation"
150+
raise ValueError(msg)
150151
assert base_python.exists()
151152

152153
log.step("Setting up build environment...")
@@ -466,7 +467,8 @@ def build(options: Options, tmp_path: Path) -> None:
466467
)
467468
)
468469
else:
469-
raise RuntimeError("unreachable")
470+
msg = "unreachable"
471+
raise RuntimeError(msg)
470472

471473
# skip this test
472474
continue

cibuildwheel/oci_container.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ def __init__(
5858
engine: ContainerEngine = "docker",
5959
):
6060
if not image:
61-
raise ValueError("Must have a non-empty image to run.")
61+
msg = "Must have a non-empty image to run."
62+
raise ValueError(msg)
6263

6364
self.image = image
6465
self.simulate_32_bit = simulate_32_bit

cibuildwheel/options.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ def _dig_first(*pairs: tuple[Mapping[str, Setting], str], ignore_empty: bool = F
138138
_dig_first((dict1, "key1"), (dict2, "key2"), ...)
139139
"""
140140
if not pairs:
141-
raise ValueError("pairs cannot be empty")
141+
msg = "pairs cannot be empty"
142+
raise ValueError(msg)
142143

143144
for dict_like, key in pairs:
144145
if key in dict_like:
@@ -208,13 +209,15 @@ def __init__(
208209

209210
if config_overrides is not None:
210211
if not isinstance(config_overrides, list):
211-
raise ConfigOptionError("'tool.cibuildwheel.overrides' must be a list")
212+
msg = "'tool.cibuildwheel.overrides' must be a list"
213+
raise ConfigOptionError(msg)
212214

213215
for config_override in config_overrides:
214216
select = config_override.pop("select", None)
215217

216218
if not select:
217-
raise ConfigOptionError("'select' must be set in an override")
219+
msg = "'select' must be set in an override"
220+
raise ConfigOptionError(msg)
218221

219222
if isinstance(select, list):
220223
select = " ".join(select)
@@ -328,14 +331,16 @@ def get(
328331

329332
if isinstance(result, dict):
330333
if table is None:
331-
raise ConfigOptionError(f"{name!r} does not accept a table")
334+
msg = f"{name!r} does not accept a table"
335+
raise ConfigOptionError(msg)
332336
return table["sep"].join(
333337
item for k, v in result.items() for item in _inner_fmt(k, v, table)
334338
)
335339

336340
if isinstance(result, list):
337341
if sep is None:
338-
raise ConfigOptionError(f"{name!r} does not accept a list")
342+
msg = f"{name!r} does not accept a list"
343+
raise ConfigOptionError(msg)
339344
return sep.join(result)
340345

341346
if isinstance(result, int):

cibuildwheel/windows.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ def setup_python(
137137
assert python_configuration.url is not None
138138
base_python = install_pypy(tmp, python_configuration.arch, python_configuration.url)
139139
else:
140-
raise ValueError("Unknown Python implementation")
140+
msg = "Unknown Python implementation"
141+
raise ValueError(msg)
141142
assert base_python.exists()
142143

143144
log.step("Setting up build environment...")

pyproject.toml

-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ module = [
6868
"bashlex",
6969
"bashlex.*",
7070
"importlib_resources",
71-
"ghapi.*",
7271
]
7372
ignore_missing_imports = true
7473

setup.py

-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
],
2121
"bin": [
2222
"click",
23-
"ghapi",
2423
"pip-tools",
2524
"pygithub",
2625
"pyyaml",
@@ -46,6 +45,4 @@
4645
*extras["bin"],
4746
]
4847

49-
extras["all"] = sum(extras.values(), [])
50-
5148
setup(extras_require=extras)

test/test_dependency_versions.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ def test_pinned_versions(tmp_path, python_version, build_frontend_env):
108108
w for w in utils.expected_wheels("spam", "0.1.0") if "-cp39" in w or "-pp39" in w
109109
]
110110
else:
111-
raise ValueError("unhandled python version")
111+
msg = "unhandled python version"
112+
raise ValueError(msg)
112113

113114
assert set(actual_wheels) == set(expected_wheels)
114115

test/utils.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
elif sys.platform in ["win32", "cygwin"]:
2424
platform = "windows"
2525
else:
26-
raise Exception("Unsupported platform")
26+
msg = f"Unsupported platform {sys.platform!r}"
27+
raise Exception(msg)
2728

2829

2930
def cibuildwheel_get_build_identifiers(project_path, env=None, *, prerelease_pythons=False):
@@ -210,7 +211,8 @@ def expected_wheels(
210211
)
211212

212213
else:
213-
raise Exception("unsupported platform")
214+
msg = f"Unsupported platform {platform!r}"
215+
raise Exception(msg)
214216

215217
for platform_tag in platform_tags:
216218
wheels.append(f"{package_name}-{package_version}-{python_abi_tag}-{platform_tag}.whl")

unit_test/main_tests/conftest.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ def mock_protection(monkeypatch):
3131
"""
3232

3333
def fail_on_call(*args, **kwargs):
34-
raise RuntimeError("This should never be called")
34+
msg = "This should never be called"
35+
raise RuntimeError(msg)
3536

3637
def ignore_call(*args, **kwargs):
3738
pass

0 commit comments

Comments
 (0)