Skip to content

Commit

Permalink
Simplify Traversable signature (#10934)
Browse files Browse the repository at this point in the history
Simplify Traversable.open() signature. This is necessary so that implentors can
reasonanbly implement this method. For example `zipfile.Path.open()` (which
is considered a `Traversable`) only supports this subset.

Make `Traversable.__truediv__` and `joinpath` arguments pos-only. The
arguments are named differently in both `pathlib.Path` and `zipfile.Path`.
  • Loading branch information
srittau authored Oct 26, 2023
1 parent a08d4c8 commit 1c184fe
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 70 deletions.
82 changes: 12 additions & 70 deletions stdlib/importlib/abc.pyi
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import _ast
import sys
import types
from _typeshed import (
OpenBinaryMode,
OpenBinaryModeReading,
OpenBinaryModeUpdating,
OpenBinaryModeWriting,
OpenTextMode,
ReadableBuffer,
StrPath,
)
from _typeshed import ReadableBuffer, StrPath
from abc import ABCMeta, abstractmethod
from collections.abc import Iterator, Mapping, Sequence
from importlib.machinery import ModuleSpec
from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper
from typing import IO, Any, BinaryIO, Protocol, overload, runtime_checkable
from io import BufferedReader
from typing import IO, Any, Protocol, overload, runtime_checkable
from typing_extensions import Literal

if sys.version_info >= (3, 11):
Expand Down Expand Up @@ -139,75 +131,25 @@ if sys.version_info >= (3, 9):
def joinpath(self, *descendants: str) -> Traversable: ...
else:
@abstractmethod
def joinpath(self, child: str) -> Traversable: ...
# The .open method comes from pathlib.pyi and should be kept in sync.
@overload
@abstractmethod
def open(
self,
mode: OpenTextMode = "r",
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 = None, errors: None = None, newline: None = None
) -> FileIO: ...
# Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter
@overload
@abstractmethod
def open(
self,
mode: OpenBinaryModeUpdating,
buffering: Literal[-1, 1] = ...,
encoding: None = None,
errors: None = None,
newline: None = None,
) -> BufferedRandom: ...
@overload
@abstractmethod
def open(
self,
mode: OpenBinaryModeWriting,
buffering: Literal[-1, 1] = ...,
encoding: None = None,
errors: None = None,
newline: None = None,
) -> BufferedWriter: ...
@overload
@abstractmethod
def open(
self,
mode: OpenBinaryModeReading,
buffering: Literal[-1, 1] = ...,
encoding: None = None,
errors: None = None,
newline: None = None,
) -> BufferedReader: ...
# Buffering cannot be determined: fall back to BinaryIO
def joinpath(self, __child: str) -> Traversable: ...

# The documentation and runtime protocol allows *args, **kwargs arguments,
# but this would mean that all implementors would have to support them,
# which is not the case.
@overload
@abstractmethod
def open(
self, mode: OpenBinaryMode, buffering: int = ..., encoding: None = None, errors: None = None, newline: None = None
) -> BinaryIO: ...
# Fallback if mode is not specified
def open(self, mode: Literal["r", "w"] = "r", *, encoding: str | None = None, errors: str | None = None) -> IO[str]: ...
@overload
@abstractmethod
def open(
self, mode: str, buffering: int = ..., encoding: str | None = ..., errors: str | None = ..., newline: str | None = ...
) -> IO[Any]: ...
def open(self, mode: Literal["rb", "wb"]) -> IO[bytes]: ...
@property
@abstractmethod
def name(self) -> str: ...
if sys.version_info >= (3, 10):
def __truediv__(self, child: str) -> Traversable: ...
def __truediv__(self, __child: str) -> Traversable: ...
else:
@abstractmethod
def __truediv__(self, child: str) -> Traversable: ...
def __truediv__(self, __child: str) -> Traversable: ...

@abstractmethod
def read_bytes(self) -> bytes: ...
Expand Down
13 changes: 13 additions & 0 deletions test_cases/stdlib/check_importlib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import importlib.abc
import pathlib
import sys
import zipfile

# Assert that some Path classes are Traversable.
if sys.version_info >= (3, 9):

def traverse(t: importlib.abc.Traversable) -> None:
pass

traverse(pathlib.Path())
traverse(zipfile.Path(""))
4 changes: 4 additions & 0 deletions tests/stubtest_allowlists/py310.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ typing.ParamSpec(Args|Kwargs).__origin__
# https://github.com/python/mypy/issues/15302
typing.NewType.__call__

# Problematic protocol signatures at runtime, see source code comments.
importlib.abc.Traversable.joinpath
importlib.abc.Traversable.open

# Super-special typing primitives
typing\.NamedTuple
typing\.Annotated
Expand Down
4 changes: 4 additions & 0 deletions tests/stubtest_allowlists/py311.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ platform.uname_result.processor
unittest.TestCase.__init_subclass__
unittest.case.TestCase.__init_subclass__

# Problematic protocol signature at runtime, see source code comments.
importlib.abc.Traversable.open
importlib.resources.abc.Traversable.open

# Super-special typing primitives
typing\._SpecialForm.*
typing\.NamedTuple
Expand Down
4 changes: 4 additions & 0 deletions tests/stubtest_allowlists/py312.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ platform.uname_result.processor
unittest.TestCase.__init_subclass__
unittest.case.TestCase.__init_subclass__

# Problematic protocol signature at runtime, see source code comments.
importlib.abc.Traversable.open
importlib.resources.abc.Traversable.open

# Super-special typing primitives
typing\._SpecialForm.*
typing\.NamedTuple
Expand Down
3 changes: 3 additions & 0 deletions tests/stubtest_allowlists/py39.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ types.MemberDescriptorType.__get__
types.MethodDescriptorType.__get__
types.WrapperDescriptorType.__get__

# Problematic protocol signature at runtime, see source code comments.
importlib.abc.Traversable.open

# Super-special typing primitives
typing\.NamedTuple
typing\.Annotated
Expand Down

0 comments on commit 1c184fe

Please sign in to comment.