Files
RustPython/Lib/test/test_importlib/_path.py
Jeong, YunWon af884cb284 First step for Python 3.12 support (#5078)
* Mark 3.12

* Update importlib from Python 3.12.0

* Update test_importlib from Python3.12

* Mark failings tests from importlib

* Update test.support from Python3.12

* Fix unsupported parser feature

* mark failing test

* Update functools from Python 3.12

* manual type annotation

* slice behavior changed in 3.12

* empty unittest.main returns non-zero

* test_decimal from CPython 3.12

* Mark failing tests

* Update test_unicode from CPython 3.12

* Update test_functools from Python 3.12

* Update enum from Python 3.12

* enum

* Doc format changed

* Update test_module from CPython

---------

Co-authored-by: CPython developers <>
2023-10-22 19:19:05 -07:00

110 lines
2.7 KiB
Python
Vendored

# 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