Skip to content

Commit 25ae655

Browse files
committed
typing: allow PathLike objects in addition to strs
Some projects use pathlib or other libraries to encapsulate file system paths instead of working with strs (or bytes) directly. These classes implement the os.PathLike interface which the functions in `os.path` support in addition to strs. This changes all functions that accept paths to accept PathLike objects in addition to strings. The way the backend_path attribute is set in `BuildBackendHookCaller.__init__()` was also modified so the typing was correct.
1 parent 0b036b5 commit 25ae655

File tree

1 file changed

+37
-24
lines changed

1 file changed

+37
-24
lines changed

src/pyproject_hooks/_impl.py

+37-24
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,21 @@
66
from os.path import abspath
77
from os.path import join as pjoin
88
from subprocess import STDOUT, check_call, check_output
9-
from typing import TYPE_CHECKING, Any, Iterator, Mapping, Optional, Sequence
9+
from typing import (
10+
TYPE_CHECKING,
11+
Any,
12+
Iterator,
13+
List,
14+
Mapping,
15+
Optional,
16+
Sequence,
17+
Union,
18+
)
1019

1120
from ._in_process import _in_proc_script_path
1221

22+
StrPath = Union[str, "os.PathLike[str]"]
23+
1324
if TYPE_CHECKING:
1425
from typing import Protocol
1526

@@ -18,19 +29,19 @@ class SubprocessRunner(Protocol):
1829

1930
def __call__(
2031
self,
21-
cmd: Sequence[str],
22-
cwd: Optional[str] = None,
32+
cmd: Sequence[StrPath],
33+
cwd: Optional[StrPath] = None,
2334
extra_environ: Optional[Mapping[str, str]] = None,
2435
) -> None:
2536
...
2637

2738

28-
def write_json(obj: Mapping[str, Any], path: str, **kwargs) -> None:
39+
def write_json(obj: Mapping[str, Any], path: StrPath, **kwargs) -> None:
2940
with open(path, "w", encoding="utf-8") as f:
3041
json.dump(obj, f, **kwargs)
3142

3243

33-
def read_json(path: str) -> Mapping[str, Any]:
44+
def read_json(path: StrPath) -> Mapping[str, Any]:
3445
with open(path, encoding="utf-8") as f:
3546
return json.load(f)
3647

@@ -43,7 +54,7 @@ def __init__(
4354
traceback: str,
4455
message: Optional[str] = None,
4556
backend_name: Optional[str] = None,
46-
backend_path: Optional[Sequence[str]] = None,
57+
backend_path: Optional[Sequence[StrPath]] = None,
4758
) -> None:
4859
# Preserving arg order for the sake of API backward compatibility.
4960
self.backend_name = backend_name
@@ -68,8 +79,8 @@ def __init__(self, traceback: str) -> None:
6879

6980

7081
def default_subprocess_runner(
71-
cmd: Sequence[str],
72-
cwd: Optional[str] = None,
82+
cmd: Sequence[StrPath],
83+
cwd: Optional[StrPath] = None,
7384
extra_environ: Optional[Mapping[str, str]] = None,
7485
) -> None:
7586
"""The default method of calling the wrapper subprocess.
@@ -84,8 +95,8 @@ def default_subprocess_runner(
8495

8596

8697
def quiet_subprocess_runner(
87-
cmd: Sequence[str],
88-
cwd: Optional[str] = None,
98+
cmd: Sequence[StrPath],
99+
cwd: Optional[StrPath] = None,
89100
extra_environ: Optional[Mapping[str, str]] = None,
90101
) -> None:
91102
"""Call the subprocess while suppressing output.
@@ -99,7 +110,7 @@ def quiet_subprocess_runner(
99110
check_output(cmd, cwd=cwd, env=env, stderr=STDOUT)
100111

101112

102-
def norm_and_check(source_tree: str, requested: str) -> str:
113+
def norm_and_check(source_tree: StrPath, requested: StrPath) -> str:
103114
"""Normalise and check a backend path.
104115
105116
Ensure that the requested backend path is specified as a relative path,
@@ -128,11 +139,11 @@ class BuildBackendHookCaller:
128139

129140
def __init__(
130141
self,
131-
source_dir: str,
142+
source_dir: StrPath,
132143
build_backend: str,
133-
backend_path: Optional[Sequence[str]] = None,
144+
backend_path: Optional[Sequence[StrPath]] = None,
134145
runner: Optional["SubprocessRunner"] = None,
135-
python_executable: Optional[str] = None,
146+
python_executable: Optional[StrPath] = None,
136147
) -> None:
137148
"""
138149
:param source_dir: The source directory to invoke the build backend for
@@ -147,9 +158,11 @@ def __init__(
147158

148159
self.source_dir = abspath(source_dir)
149160
self.build_backend = build_backend
150-
if backend_path:
151-
backend_path = [norm_and_check(self.source_dir, p) for p in backend_path]
152-
self.backend_path = backend_path
161+
self.backend_path: Optional[List[str]] = (
162+
[norm_and_check(self.source_dir, p) for p in backend_path]
163+
if backend_path is not None
164+
else None
165+
)
153166
self._subprocess_runner = runner
154167
if not python_executable:
155168
python_executable = sys.executable
@@ -199,7 +212,7 @@ def get_requires_for_build_wheel(
199212

200213
def prepare_metadata_for_build_wheel(
201214
self,
202-
metadata_directory: str,
215+
metadata_directory: StrPath,
203216
config_settings: Optional[Mapping[str, Any]] = None,
204217
_allow_fallback: bool = True,
205218
) -> str:
@@ -232,9 +245,9 @@ def prepare_metadata_for_build_wheel(
232245

233246
def build_wheel(
234247
self,
235-
wheel_directory: str,
248+
wheel_directory: StrPath,
236249
config_settings: Optional[Mapping[str, Any]] = None,
237-
metadata_directory: Optional[str] = None,
250+
metadata_directory: Optional[StrPath] = None,
238251
) -> str:
239252
"""Build a wheel from this project.
240253
@@ -282,7 +295,7 @@ def get_requires_for_build_editable(
282295

283296
def prepare_metadata_for_build_editable(
284297
self,
285-
metadata_directory: str,
298+
metadata_directory: StrPath,
286299
config_settings: Optional[Mapping[str, Any]] = None,
287300
_allow_fallback: bool = True,
288301
) -> Optional[str]:
@@ -314,9 +327,9 @@ def prepare_metadata_for_build_editable(
314327

315328
def build_editable(
316329
self,
317-
wheel_directory: str,
330+
wheel_directory: StrPath,
318331
config_settings: Optional[Mapping[str, Any]] = None,
319-
metadata_directory: Optional[str] = None,
332+
metadata_directory: Optional[StrPath] = None,
320333
) -> str:
321334
"""Build an editable wheel from this project.
322335
@@ -359,7 +372,7 @@ def get_requires_for_build_sdist(
359372

360373
def build_sdist(
361374
self,
362-
sdist_directory: str,
375+
sdist_directory: StrPath,
363376
config_settings: Optional[Mapping[str, Any]] = None,
364377
) -> str:
365378
"""Build an sdist from this project.

0 commit comments

Comments
 (0)