gh-132947: Apply changes from importlib_metadata 8.7 (#137885)

* Copied files from python/importlib_metadata@b67ac80c49.
This commit is contained in:
Jason R. Coombs 2025-08-18 10:54:10 -07:00 committed by GitHub
parent 918e3ba6c0
commit 5292fc00f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 294 additions and 122 deletions

View file

@ -1,9 +1,14 @@
# from jaraco.path 3.7
# from jaraco.path 3.7.2
from __future__ import annotations
import functools
import pathlib
from typing import Dict, Protocol, Union
from typing import runtime_checkable
from collections.abc import Mapping
from typing import TYPE_CHECKING, Protocol, Union, runtime_checkable
if TYPE_CHECKING:
from typing_extensions import Self
class Symlink(str):
@ -12,29 +17,25 @@ class Symlink(str):
"""
FilesSpec = Dict[str, Union[str, bytes, Symlink, 'FilesSpec']] # type: ignore
FilesSpec = Mapping[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 __truediv__(self, other, /) -> Self: ...
def mkdir(self, *, exist_ok) -> object: ...
def write_text(self, content, /, *, encoding) -> object: ...
def write_bytes(self, content, /) -> object: ...
def symlink_to(self, target, /) -> object: ...
def _ensure_tree_maker(obj: Union[str, TreeMaker]) -> TreeMaker:
return obj if isinstance(obj, TreeMaker) else pathlib.Path(obj) # type: ignore
def _ensure_tree_maker(obj: str | TreeMaker) -> TreeMaker:
return obj if isinstance(obj, TreeMaker) else pathlib.Path(obj)
def build(
spec: FilesSpec,
prefix: Union[str, TreeMaker] = pathlib.Path(), # type: ignore
prefix: str | TreeMaker = pathlib.Path(),
):
"""
Build a set of files/directories, as described by the spec.
@ -66,23 +67,24 @@ def build(
@functools.singledispatch
def create(content: Union[str, bytes, FilesSpec], path):
def create(content: str | bytes | FilesSpec, path: TreeMaker) -> None:
path.mkdir(exist_ok=True)
build(content, prefix=path) # type: ignore
# Mypy only looks at the signature of the main singledispatch method. So it must contain the complete Union
build(content, prefix=path) # type: ignore[arg-type] # python/mypy#11727
@create.register
def _(content: bytes, path):
def _(content: bytes, path: TreeMaker) -> None:
path.write_bytes(content)
@create.register
def _(content: str, path):
def _(content: str, path: TreeMaker) -> None:
path.write_text(content, encoding='utf-8')
@create.register
def _(content: Symlink, path):
def _(content: Symlink, path: TreeMaker) -> None:
path.symlink_to(content)