diff --git a/stdlib/importlib/abc.pyi b/stdlib/importlib/abc.pyi index 69608c57c..6737912fc 100644 --- a/stdlib/importlib/abc.pyi +++ b/stdlib/importlib/abc.pyi @@ -1,9 +1,18 @@ import sys import types -from _typeshed import StrOrBytesPath +from _typeshed import ( + OpenBinaryMode, + OpenBinaryModeReading, + OpenBinaryModeUpdating, + OpenBinaryModeWriting, + OpenTextMode, + StrOrBytesPath, + StrPath, +) from abc import ABCMeta, abstractmethod from importlib.machinery import ModuleSpec -from typing import IO, Any, Iterator, Mapping, Protocol, Sequence, Tuple, Union +from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper +from typing import IO, Any, BinaryIO, Iterator, Mapping, Protocol, Sequence, Tuple, Union, overload from typing_extensions import Literal, runtime_checkable _Path = Union[bytes, str] @@ -84,22 +93,79 @@ if sys.version_info >= (3, 7): if sys.version_info >= (3, 9): @runtime_checkable class Traversable(Protocol): - @abstractmethod - def iterdir(self) -> Iterator[Traversable]: ... - @abstractmethod - def read_bytes(self) -> bytes: ... - @abstractmethod - def read_text(self, encoding: str | None = ...) -> str: ... @abstractmethod def is_dir(self) -> bool: ... @abstractmethod def is_file(self) -> bool: ... @abstractmethod - def joinpath(self, child: _Path) -> Traversable: ... + def iterdir(self) -> Iterator[Traversable]: ... @abstractmethod - def __truediv__(self, child: _Path) -> Traversable: ... + def joinpath(self, child: StrPath) -> Traversable: ... + # The .open method comes from pathlib.pyi and should be kept in sync. + @overload @abstractmethod - def open(self, mode: Literal["r", "rb"] = ..., *args: Any, **kwargs: Any) -> IO[Any]: ... + def open( + self, + mode: OpenTextMode = ..., + buffering: int = ..., + encoding: str | None = ..., + errors: str | None = ..., + newline: str | None = ..., + ) -> TextIOWrapper: ... + # Unbuffered binary mode: returns a FileIO + @overload + @abstractmethod + def open( + self, mode: OpenBinaryMode, buffering: Literal[0], encoding: None = ..., errors: None = ..., newline: None = ... + ) -> FileIO: ... + # Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter + @overload + @abstractmethod + def open( + self, + mode: OpenBinaryModeUpdating, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedRandom: ... + @overload + @abstractmethod + def open( + self, + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedWriter: ... + @overload + @abstractmethod + def open( + self, + mode: OpenBinaryModeReading, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedReader: ... + # Buffering cannot be determined: fall back to BinaryIO + @overload + @abstractmethod + def open( + self, mode: OpenBinaryMode, buffering: int, encoding: None = ..., errors: None = ..., newline: None = ... + ) -> BinaryIO: ... + # Fallback if mode is not specified + @overload + @abstractmethod + def open( + self, mode: str, buffering: int = ..., encoding: str | None = ..., errors: str | None = ..., newline: str | None = ... + ) -> IO[Any]: ... @property - @abstractmethod def name(self) -> str: ... + @abstractmethod + def __truediv__(self, key: StrPath) -> Traversable: ... + @abstractmethod + def read_bytes(self) -> bytes: ... + @abstractmethod + def read_text(self, encoding: str | None = ...) -> str: ... diff --git a/stdlib/pathlib.pyi b/stdlib/pathlib.pyi index db1dff36b..e8577ebc1 100644 --- a/stdlib/pathlib.pyi +++ b/stdlib/pathlib.pyi @@ -88,6 +88,7 @@ class Path(PurePath): def mkdir(self, mode: int = ..., parents: bool = ..., exist_ok: bool = ...) -> None: ... # Adapted from builtins.open # Text mode: always returns a TextIOWrapper + # The Traversable .open in stdlib/importlib/abc.pyi should be kept in sync with this. @overload def open( self,