mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-123987: Fix NotADirectoryError in NamespaceReader when sentinel present (#124018)
This commit is contained in:
parent
fccbfc40b5
commit
b543b32eff
7 changed files with 93 additions and 18 deletions
|
@ -2,15 +2,44 @@ import pathlib
|
|||
import functools
|
||||
|
||||
from typing import Dict, Union
|
||||
from typing import runtime_checkable
|
||||
from typing import Protocol
|
||||
|
||||
|
||||
####
|
||||
# from jaraco.path 3.4.1
|
||||
|
||||
FilesSpec = Dict[str, Union[str, bytes, 'FilesSpec']] # type: ignore
|
||||
# from jaraco.path 3.7.1
|
||||
|
||||
|
||||
def build(spec: FilesSpec, prefix=pathlib.Path()):
|
||||
class Symlink(str):
|
||||
"""
|
||||
A string indicating the target of a symlink.
|
||||
"""
|
||||
|
||||
|
||||
FilesSpec = Dict[str, Union[str, bytes, Symlink, 'FilesSpec']]
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class TreeMaker(Protocol):
|
||||
def __truediv__(self, *args, **kwargs): ... # pragma: no cover
|
||||
|
||||
def mkdir(self, **kwargs): ... # pragma: no cover
|
||||
|
||||
def write_text(self, content, **kwargs): ... # pragma: no cover
|
||||
|
||||
def write_bytes(self, content): ... # pragma: no cover
|
||||
|
||||
def symlink_to(self, target): ... # pragma: no cover
|
||||
|
||||
|
||||
def _ensure_tree_maker(obj: Union[str, TreeMaker]) -> TreeMaker:
|
||||
return obj if isinstance(obj, TreeMaker) else pathlib.Path(obj) # type: ignore[return-value]
|
||||
|
||||
|
||||
def build(
|
||||
spec: FilesSpec,
|
||||
prefix: Union[str, TreeMaker] = pathlib.Path(), # type: ignore[assignment]
|
||||
):
|
||||
"""
|
||||
Build a set of files/directories, as described by the spec.
|
||||
|
||||
|
@ -25,21 +54,25 @@ def build(spec: FilesSpec, prefix=pathlib.Path()):
|
|||
... "__init__.py": "",
|
||||
... },
|
||||
... "baz.py": "# Some code",
|
||||
... }
|
||||
... "bar.py": Symlink("baz.py"),
|
||||
... },
|
||||
... "bing": Symlink("foo"),
|
||||
... }
|
||||
>>> target = getfixture('tmp_path')
|
||||
>>> build(spec, target)
|
||||
>>> target.joinpath('foo/baz.py').read_text(encoding='utf-8')
|
||||
'# Some code'
|
||||
>>> target.joinpath('bing/bar.py').read_text(encoding='utf-8')
|
||||
'# Some code'
|
||||
"""
|
||||
for name, contents in spec.items():
|
||||
create(contents, pathlib.Path(prefix) / name)
|
||||
create(contents, _ensure_tree_maker(prefix) / name)
|
||||
|
||||
|
||||
@functools.singledispatch
|
||||
def create(content: Union[str, bytes, FilesSpec], path):
|
||||
path.mkdir(exist_ok=True)
|
||||
build(content, prefix=path) # type: ignore
|
||||
build(content, prefix=path) # type: ignore[arg-type]
|
||||
|
||||
|
||||
@create.register
|
||||
|
@ -52,5 +85,10 @@ def _(content: str, path):
|
|||
path.write_text(content, encoding='utf-8')
|
||||
|
||||
|
||||
@create.register
|
||||
def _(content: Symlink, path):
|
||||
path.symlink_to(content)
|
||||
|
||||
|
||||
# end from jaraco.path
|
||||
####
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue