From 94ab32ba597e98e84f8201e52d68fdfbc12cbad3 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 16 Jun 2018 10:18:54 -0700 Subject: [PATCH] Fix abstract classes for Python 3 (#2239) * add metaclass=ABCMeta to some classes * mark some more classes as explicitly abstract * make some more classes concrete --- stdlib/2and3/_csv.pyi | 1 + stdlib/3.4/asyncio/events.pyi | 2 +- stdlib/3.7/contextvars.pyi | 2 +- stdlib/3/collections/__init__.pyi | 9 ++++++--- stdlib/3/importlib/abc.pyi | 4 ++-- stdlib/3/os/__init__.pyi | 7 +++++++ stdlib/3/typing.pyi | 4 ++-- .../2and3/google/protobuf/internal/containers.pyi | 8 ++++++-- third_party/2and3/requests/packages/urllib3/response.pyi | 5 +++-- third_party/3/pkg_resources.pyi | 5 +++-- 10 files changed, 32 insertions(+), 15 deletions(-) diff --git a/stdlib/2and3/_csv.pyi b/stdlib/2and3/_csv.pyi index d5119aea8..59d895d49 100644 --- a/stdlib/2and3/_csv.pyi +++ b/stdlib/2and3/_csv.pyi @@ -23,6 +23,7 @@ class Dialect: class _reader(Iterator[List[str]]): dialect = ... # type: Dialect line_num = ... # type: int + def __next__(self) -> List[str]: ... class _writer: dialect = ... # type: Dialect diff --git a/stdlib/3.4/asyncio/events.pyi b/stdlib/3.4/asyncio/events.pyi index c0b447aec..b03d81432 100644 --- a/stdlib/3.4/asyncio/events.pyi +++ b/stdlib/3.4/asyncio/events.pyi @@ -204,7 +204,7 @@ class AbstractEventLoopPolicy(metaclass=ABCMeta): @abstractmethod def set_child_watcher(self, watcher: Any) -> None: ... # TODO: unix_events.AbstractChildWatcher -class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy): +class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy, metaclass=ABCMeta): def __init__(self) -> None: ... def get_event_loop(self) -> AbstractEventLoop: ... def set_event_loop(self, loop: AbstractEventLoop) -> None: ... diff --git a/stdlib/3.7/contextvars.pyi b/stdlib/3.7/contextvars.pyi index 6fe499e34..ab2ae9e5f 100644 --- a/stdlib/3.7/contextvars.pyi +++ b/stdlib/3.7/contextvars.pyi @@ -27,4 +27,4 @@ class Context(Mapping[ContextVar[Any], Any]): def copy(self) -> Context: ... def __getitem__(self, key: ContextVar[Any]) -> Any: ... def __iter__(self) -> Iterator[ContextVar[Any]]: ... - def __len___(self) -> int: ... + def __len__(self) -> int: ... diff --git a/stdlib/3/collections/__init__.pyi b/stdlib/3/collections/__init__.pyi index 6672d434c..2289e4212 100644 --- a/stdlib/3/collections/__init__.pyi +++ b/stdlib/3/collections/__init__.pyi @@ -286,9 +286,12 @@ class Counter(Dict[_T, int], Generic[_T]): _OrderedDictT = TypeVar('_OrderedDictT', bound=OrderedDict) -class _OrderedDictKeysView(KeysView[_KT], Reversible[_KT]): ... -class _OrderedDictItemsView(ItemsView[_KT, _VT], Reversible[Tuple[_KT, _VT]]): ... -class _OrderedDictValuesView(ValuesView[_VT], Reversible[_VT]): ... +class _OrderedDictKeysView(KeysView[_KT], Reversible[_KT]): + def __reversed__(self) -> Iterator[_KT]: ... +class _OrderedDictItemsView(ItemsView[_KT, _VT], Reversible[Tuple[_KT, _VT]]): + def __reversed__(self) -> Iterator[Tuple[_KT, _VT]]: ... +class _OrderedDictValuesView(ValuesView[_VT], Reversible[_VT]): + def __reversed__(self) -> Iterator[_VT]: ... class OrderedDict(Dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]): def popitem(self, last: bool = ...) -> Tuple[_KT, _VT]: ... diff --git a/stdlib/3/importlib/abc.pyi b/stdlib/3/importlib/abc.pyi index 0e13fa2c1..00deb6832 100644 --- a/stdlib/3/importlib/abc.pyi +++ b/stdlib/3/importlib/abc.pyi @@ -47,7 +47,7 @@ class ExecutionLoader(InspectLoader): def get_filename(self, fullname: str) -> _Path: ... def get_code(self, fullname: str) -> Optional[types.CodeType]: ... -class SourceLoader(ResourceLoader, ExecutionLoader): +class SourceLoader(ResourceLoader, ExecutionLoader, metaclass=ABCMeta): def path_mtime(self, path: _Path) -> Union[int, float]: ... def set_data(self, path: _Path, data: bytes) -> None: ... def get_source(self, fullname: str) -> Optional[str]: ... @@ -82,7 +82,7 @@ if sys.version_info >= (3, 3): target: Optional[types.ModuleType] = ... ) -> Optional[ModuleSpec]: ... - class FileLoader(ResourceLoader, ExecutionLoader): + class FileLoader(ResourceLoader, ExecutionLoader, metaclass=ABCMeta): name = ... # type: str path = ... # type: _Path def __init__(self, fullname: str, path: _Path) -> None: ... diff --git a/stdlib/3/os/__init__.pyi b/stdlib/3/os/__init__.pyi index 35e5af149..a375cd65b 100644 --- a/stdlib/3/os/__init__.pyi +++ b/stdlib/3/os/__init__.pyi @@ -139,6 +139,11 @@ X_OK: int class _Environ(MutableMapping[AnyStr, AnyStr], Generic[AnyStr]): def copy(self) -> Dict[AnyStr, AnyStr]: ... + def __delitem__(self, key: AnyStr) -> None: ... + def __getitem__(self, key: AnyStr) -> AnyStr: ... + def __setitem__(self, key: AnyStr, value: AnyStr) -> None: ... + def __iter__(self) -> Iterator[AnyStr]: ... + def __len__(self) -> int: ... environ: _Environ[str] if sys.version_info >= (3, 2): @@ -456,6 +461,7 @@ else: def rmdir(path: _PathType) -> None: ... if sys.version_info >= (3, 7): class _ScandirIterator(Iterator[DirEntry[AnyStr]], ContextManager[_ScandirIterator[AnyStr]]): + def __next__(self) -> DirEntry[AnyStr]: ... def close(self) -> None: ... @overload def scandir() -> _ScandirIterator[str]: ... @@ -465,6 +471,7 @@ if sys.version_info >= (3, 7): def scandir(path: Union[AnyStr, PathLike[AnyStr]]) -> _ScandirIterator[AnyStr]: ... elif sys.version_info >= (3, 6): class _ScandirIterator(Iterator[DirEntry[AnyStr]], ContextManager[_ScandirIterator[AnyStr]]): + def __next__(self) -> DirEntry[AnyStr]: ... def close(self) -> None: ... @overload def scandir() -> _ScandirIterator[str]: ... diff --git a/stdlib/3/typing.pyi b/stdlib/3/typing.pyi index d680a1605..5512f7f26 100644 --- a/stdlib/3/typing.pyi +++ b/stdlib/3/typing.pyi @@ -178,7 +178,7 @@ class Coroutine(Awaitable[_V_co], Generic[_T_co, _T_contra, _V_co]): # NOTE: This type does not exist in typing.py or PEP 484. # The parameters corrrespond to Generator, but the 4th is the original type. class AwaitableGenerator(Awaitable[_V_co], Generator[_T_co, _T_contra, _V_co], - Generic[_T_co, _T_contra, _V_co, _S]): + Generic[_T_co, _T_contra, _V_co, _S], metaclass=ABCMeta): pass @runtime @@ -465,7 +465,7 @@ class TextIO(IO[str]): @abstractmethod def __enter__(self) -> TextIO: ... -class ByteString(Sequence[int]): ... +class ByteString(Sequence[int], metaclass=ABCMeta): ... class Match(Generic[AnyStr]): pos = 0 diff --git a/third_party/2and3/google/protobuf/internal/containers.pyi b/third_party/2and3/google/protobuf/internal/containers.pyi index c78fadf55..b09ffd99c 100644 --- a/third_party/2and3/google/protobuf/internal/containers.pyi +++ b/third_party/2and3/google/protobuf/internal/containers.pyi @@ -3,17 +3,21 @@ from google.protobuf.internal.message_listener import MessageListener from google.protobuf.message import Message from typing import ( MutableSequence, Sequence, TypeVar, Generic, Any, Iterator, Iterable, - Union, Optional, Callable + Union, Optional, Callable, overload, List ) _T = TypeVar('_T') -class BaseContainer(Generic[_T], MutableSequence[_T]): +class BaseContainer(Sequence[_T]): def __init__(self, message_listener: MessageListener) -> None: ... def __len__(self) -> int: ... def __ne__(self, other: object) -> bool: ... def __hash__(self) -> int: ... def __repr__(self) -> str: ... def sort(self, *, key: Optional[Callable[[_T], Any]] = ..., reverse: bool = ...) -> None: ... + @overload + def __getitem__(self, key: int) -> _T: ... + @overload + def __getitem__(self, key: slice) -> List[_T]: ... class RepeatedScalarFieldContainer(Generic[_T], BaseContainer[_T]): def __init__(self, message_listener: MessageListener, message_descriptor: Descriptor) -> None: ... diff --git a/third_party/2and3/requests/packages/urllib3/response.pyi b/third_party/2and3/requests/packages/urllib3/response.pyi index aca950711..8a8099147 100644 --- a/third_party/2and3/requests/packages/urllib3/response.pyi +++ b/third_party/2and3/requests/packages/urllib3/response.pyi @@ -1,4 +1,5 @@ -from typing import Any, IO +from typing import Any +import io from . import _collections from . import exceptions from .connection import HTTPException as HTTPException, BaseSSLError as BaseSSLError @@ -22,7 +23,7 @@ class GzipDecoder: def __getattr__(self, name): ... def decompress(self, data): ... -class HTTPResponse(IO[Any]): +class HTTPResponse(io.IOBase): CONTENT_DECODERS = ... # type: Any REDIRECT_STATUSES = ... # type: Any headers = ... # type: Any diff --git a/third_party/3/pkg_resources.pyi b/third_party/3/pkg_resources.pyi index fe0c10159..042f55fec 100644 --- a/third_party/3/pkg_resources.pyi +++ b/third_party/3/pkg_resources.pyi @@ -5,6 +5,7 @@ from typing import ( List, Union, TypeVar, overload, ) +from abc import ABCMeta import importlib.abc import sys import types @@ -248,9 +249,9 @@ class ExtractionError(Exception): if sys.version_info >= (3, 3): - class _Importer(importlib.abc.MetaPathFinder, importlib.abc.InspectLoader): ... + class _Importer(importlib.abc.MetaPathFinder, importlib.abc.InspectLoader, metaclass=ABCMeta): ... else: - class _Importer(importlib.abc.InspectLoader): ... + class _Importer(importlib.abc.InspectLoader, metaclass=ABCMeta): ... def register_finder(importer_type: type, distribution_finder: _DistFinderType) -> None: ...