diff --git a/stdlib/2and3/_typeshed/__init__.pyi b/stdlib/2and3/_typeshed/__init__.pyi index b2368a980784..ed5154364e6a 100644 --- a/stdlib/2and3/_typeshed/__init__.pyi +++ b/stdlib/2and3/_typeshed/__init__.pyi @@ -15,12 +15,28 @@ import array import mmap import sys -from typing import Protocol, Text, TypeVar, Union +from typing import AbstractSet, Container, Protocol, Text, Tuple, TypeVar, Union from typing_extensions import Literal +_KT_co = TypeVar("_KT_co", covariant=True) +_KT_contra = TypeVar("_KT_contra", contravariant=True) +_VT = TypeVar("_VT") +_VT_co = TypeVar("_VT_co", covariant=True) _T_co = TypeVar("_T_co", covariant=True) _T_contra = TypeVar("_T_contra", contravariant=True) +# Mapping-like protocols + +class SupportsItems(Protocol[_KT_co, _VT_co]): + def items(self) -> AbstractSet[Tuple[_KT_co, _VT_co]]: ... + +class SupportsGetItem(Container[_KT_contra], Protocol[_KT_contra, _VT_co]): + def __getitem__(self, __k: _KT_contra) -> _VT_co: ... + +class SupportsItemAccess(SupportsGetItem[_KT_contra, _VT], Protocol[_KT_contra, _VT]): + def __setitem__(self, __k: _KT_contra, __v: _VT) -> None: ... + def __delitem__(self, __v: _KT_contra) -> None: ... + # StrPath and AnyPath can be used in places where a # path can be used instead of a string, starting with Python 3.6. if sys.version_info >= (3, 6): diff --git a/stdlib/2and3/cgi.pyi b/stdlib/2and3/cgi.pyi index a081b1b642ad..31f03cc623c2 100644 --- a/stdlib/2and3/cgi.pyi +++ b/stdlib/2and3/cgi.pyi @@ -1,10 +1,14 @@ import sys -from typing import IO, Any, AnyStr, Dict, Iterator, List, Mapping, Optional, Tuple, TypeVar, Union +from _typeshed import SupportsGetItem, SupportsItemAccess +from typing import IO, Any, AnyStr, Dict, Iterable, Iterator, List, Mapping, Optional, Protocol, Tuple, TypeVar, Union _T = TypeVar("_T", bound=FieldStorage) def parse( - fp: Optional[IO[Any]] = ..., environ: Mapping[str, str] = ..., keep_blank_values: bool = ..., strict_parsing: bool = ... + fp: Optional[IO[Any]] = ..., + environ: SupportsItemAccess[str, str] = ..., + keep_blank_values: bool = ..., + strict_parsing: bool = ..., ) -> Dict[str, List[str]]: ... if sys.version_info < (3, 8): @@ -13,15 +17,19 @@ if sys.version_info < (3, 8): if sys.version_info >= (3, 7): def parse_multipart( - fp: IO[Any], pdict: Mapping[str, bytes], encoding: str = ..., errors: str = ... + fp: IO[Any], pdict: SupportsGetItem[str, bytes], encoding: str = ..., errors: str = ... ) -> Dict[str, List[Any]]: ... else: - def parse_multipart(fp: IO[Any], pdict: Mapping[str, bytes]) -> Dict[str, List[bytes]]: ... + def parse_multipart(fp: IO[Any], pdict: SupportsGetItem[str, bytes]) -> Dict[str, List[bytes]]: ... + +class _Environ(Protocol): + def __getitem__(self, __k: str) -> str: ... + def keys(self) -> Iterable[str]: ... def parse_header(line: str) -> Tuple[str, Dict[str, str]]: ... -def test(environ: Mapping[str, str] = ...) -> None: ... -def print_environ(environ: Mapping[str, str] = ...) -> None: ... +def test(environ: _Environ = ...) -> None: ... +def print_environ(environ: _Environ = ...) -> None: ... def print_form(form: Dict[str, Any]) -> None: ... def print_directory() -> None: ... def print_environ_usage() -> None: ... @@ -77,7 +85,7 @@ class FieldStorage(object): fp: Optional[IO[Any]] = ..., headers: Optional[Mapping[str, str]] = ..., outerboundary: bytes = ..., - environ: Mapping[str, str] = ..., + environ: SupportsGetItem[str, str] = ..., keep_blank_values: int = ..., strict_parsing: int = ..., limit: Optional[int] = ..., @@ -91,7 +99,7 @@ class FieldStorage(object): fp: Optional[IO[Any]] = ..., headers: Optional[Mapping[str, str]] = ..., outerboundary: bytes = ..., - environ: Mapping[str, str] = ..., + environ: SupportsGetItem[str, str] = ..., keep_blank_values: int = ..., strict_parsing: int = ..., limit: Optional[int] = ..., @@ -104,7 +112,7 @@ class FieldStorage(object): fp: IO[Any] = ..., headers: Mapping[str, str] = ..., outerboundary: bytes = ..., - environ: Mapping[str, str] = ..., + environ: SupportsGetItem[str, str] = ..., keep_blank_values: int = ..., strict_parsing: int = ..., ) -> None: ... diff --git a/stdlib/3.9/graphlib.pyi b/stdlib/3.9/graphlib.pyi index d1ecb62a900a..ca21b42329d2 100644 --- a/stdlib/3.9/graphlib.pyi +++ b/stdlib/3.9/graphlib.pyi @@ -1,9 +1,10 @@ -from typing import Generic, Iterable, Mapping, Optional, Tuple, TypeVar +from _typeshed import SupportsItems +from typing import Generic, Iterable, Optional, Tuple, TypeVar _T = TypeVar("_T") class TopologicalSorter(Generic[_T]): - def __init__(self, graph: Optional[Mapping[_T, Iterable[_T]]] = ...) -> None: ... + def __init__(self, graph: Optional[SupportsItems[_T, Iterable[_T]]] = ...) -> None: ... def add(self, node: _T, *predecessors: _T) -> None: ... def prepare(self) -> None: ... def is_active(self) -> bool: ...