mirror of
https://github.com/davidhalter/typeshed.git
synced 2026-01-09 13:02:22 +08:00
Introduce Mapping-like protocols (#4325)
typing.Mapping is not a protocol, which has caused problems in the past. (E.g. python/typeshed#3569, see also python/typeshed#3576.) This introduces a few narrow protocols to _typeshed.pyi that can be used in place of Mapping. Not all uses of Mapping can be replaced. For example, cgi.FieldStorage explictly checks whether the supplied headers argument is a Mapping instance.
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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: ...
|
||||
|
||||
@@ -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: ...
|
||||
|
||||
Reference in New Issue
Block a user