summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_importlib/_path.py
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2023-04-21 02:12:48 (GMT)
committerGitHub <noreply@github.com>2023-04-21 02:12:48 (GMT)
commit3e0fec7e07a71bdeeab7554e980110fbc47763b9 (patch)
treec95fc47a9ee48d5606f4eb6cc45703f7be568769 /Lib/test/test_importlib/_path.py
parent5c00a6224d55f8818ef567b93f484b5429e2ae80 (diff)
downloadcpython-3e0fec7e07a71bdeeab7554e980110fbc47763b9.zip
cpython-3e0fec7e07a71bdeeab7554e980110fbc47763b9.tar.gz
cpython-3e0fec7e07a71bdeeab7554e980110fbc47763b9.tar.bz2
Sync with importlib_metadata 6.5 (GH-103584)
Diffstat (limited to 'Lib/test/test_importlib/_path.py')
-rw-r--r--Lib/test/test_importlib/_path.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/Lib/test/test_importlib/_path.py b/Lib/test/test_importlib/_path.py
new file mode 100644
index 0000000..71a7043
--- /dev/null
+++ b/Lib/test/test_importlib/_path.py
@@ -0,0 +1,109 @@
+# from jaraco.path 3.5
+
+import functools
+import pathlib
+from typing import Dict, Union
+
+try:
+ from typing import Protocol, runtime_checkable
+except ImportError: # pragma: no cover
+ # Python 3.7
+ from typing_extensions import Protocol, runtime_checkable # type: ignore
+
+
+FilesSpec = Dict[str, Union[str, bytes, 'FilesSpec']] # type: ignore
+
+
+@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 _ensure_tree_maker(obj: Union[str, TreeMaker]) -> TreeMaker:
+ return obj if isinstance(obj, TreeMaker) else pathlib.Path(obj) # type: ignore
+
+
+def build(
+ spec: FilesSpec,
+ prefix: Union[str, TreeMaker] = pathlib.Path(), # type: ignore
+):
+ """
+ Build a set of files/directories, as described by the spec.
+
+ Each key represents a pathname, and the value represents
+ the content. Content may be a nested directory.
+
+ >>> spec = {
+ ... 'README.txt': "A README file",
+ ... "foo": {
+ ... "__init__.py": "",
+ ... "bar": {
+ ... "__init__.py": "",
+ ... },
+ ... "baz.py": "# Some code",
+ ... }
+ ... }
+ >>> target = getfixture('tmp_path')
+ >>> build(spec, target)
+ >>> target.joinpath('foo/baz.py').read_text(encoding='utf-8')
+ '# Some code'
+ """
+ for name, contents in spec.items():
+ 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
+
+
+@create.register
+def _(content: bytes, path):
+ path.write_bytes(content)
+
+
+@create.register
+def _(content: str, path):
+ path.write_text(content, encoding='utf-8')
+
+
+@create.register
+def _(content: str, path):
+ path.write_text(content, encoding='utf-8')
+
+
+class Recording:
+ """
+ A TreeMaker object that records everything that would be written.
+
+ >>> r = Recording()
+ >>> build({'foo': {'foo1.txt': 'yes'}, 'bar.txt': 'abc'}, r)
+ >>> r.record
+ ['foo/foo1.txt', 'bar.txt']
+ """
+
+ def __init__(self, loc=pathlib.PurePosixPath(), record=None):
+ self.loc = loc
+ self.record = record if record is not None else []
+
+ def __truediv__(self, other):
+ return Recording(self.loc / other, self.record)
+
+ def write_text(self, content, **kwargs):
+ self.record.append(str(self.loc))
+
+ write_bytes = write_text
+
+ def mkdir(self, **kwargs):
+ return