Improve constructor for builtins.dict (#8517)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Nikita Sobolev
2022-08-10 21:04:07 +03:00
committed by GitHub
parent 5cc966cc57
commit 510feeb3fc
4 changed files with 67 additions and 6 deletions

View File

@@ -1021,9 +1021,13 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]):
@overload
def __init__(self: dict[str, _VT], **kwargs: _VT) -> None: ...
@overload
def __init__(self, __map: SupportsKeysAndGetItem[_KT, _VT], **kwargs: _VT) -> None: ...
def __init__(self, __map: SupportsKeysAndGetItem[_KT, _VT]) -> None: ...
@overload
def __init__(self, __iterable: Iterable[tuple[_KT, _VT]], **kwargs: _VT) -> None: ...
def __init__(self: dict[str, _VT], __map: SupportsKeysAndGetItem[str, _VT], **kwargs: _VT) -> None: ...
@overload
def __init__(self, __iterable: Iterable[tuple[_KT, _VT]]) -> None: ...
@overload
def __init__(self: dict[str, _VT], __iterable: Iterable[tuple[str, _VT]], **kwargs: _VT) -> None: ...
# Next overload is for dict(string.split(sep) for string in iterable)
# Cannot be Iterable[Sequence[_T]] or otherwise dict(["foo", "bar", "baz"]) is not an error
@overload

View File

@@ -41,9 +41,13 @@ class UserDict(MutableMapping[_KT, _VT], Generic[_KT, _VT]):
@overload
def __init__(self: UserDict[str, _VT], __dict: None = ..., **kwargs: _VT) -> None: ...
@overload
def __init__(self, __dict: SupportsKeysAndGetItem[_KT, _VT], **kwargs: _VT) -> None: ...
def __init__(self, __dict: SupportsKeysAndGetItem[_KT, _VT]) -> None: ...
@overload
def __init__(self, __iterable: Iterable[tuple[_KT, _VT]], **kwargs: _VT) -> None: ...
def __init__(self: UserDict[str, _VT], __dict: SupportsKeysAndGetItem[str, _VT], **kwargs: _VT) -> None: ...
@overload
def __init__(self, __iterable: Iterable[tuple[_KT, _VT]]) -> None: ...
@overload
def __init__(self: UserDict[str, _VT], __iterable: Iterable[tuple[str, _VT]], **kwargs: _VT) -> None: ...
@overload
def __init__(self: UserDict[str, str], __iterable: Iterable[list[str]]) -> None: ...
def __len__(self) -> int: ...

View File

@@ -183,9 +183,13 @@ class SyncManager(BaseManager):
@overload
def dict(self, **kwargs: _VT) -> DictProxy[str, _VT]: ...
@overload
def dict(self, __map: SupportsKeysAndGetItem[_KT, _VT], **kwargs: _VT) -> DictProxy[_KT, _VT]: ...
def dict(self, __map: SupportsKeysAndGetItem[_KT, _VT]) -> DictProxy[_KT, _VT]: ...
@overload
def dict(self, __iterable: Iterable[tuple[_KT, _VT]], **kwargs: _VT) -> DictProxy[_KT, _VT]: ...
def dict(self, __map: SupportsKeysAndGetItem[str, _VT], **kwargs: _VT) -> DictProxy[str, _VT]: ...
@overload
def dict(self, __iterable: Iterable[tuple[_KT, _VT]]) -> DictProxy[_KT, _VT]: ...
@overload
def dict(self, __iterable: Iterable[tuple[str, _VT]], **kwargs: _VT) -> DictProxy[str, _VT]: ...
@overload
def dict(self, __iterable: Iterable[list[str]]) -> DictProxy[str, str]: ...
@overload

View File

@@ -0,0 +1,49 @@
# pyright: reportUnnecessaryTypeIgnoreComment=true
from typing import Dict, Generic, Iterable, Tuple, TypeVar
from typing_extensions import assert_type
# These do follow `__init__` overloads order:
# mypy and pyright have different opinions about this one:
# mypy raises: 'Need type annotation for "bad"'
# pyright is fine with it.
# bad = dict()
good: Dict[str, str] = dict()
assert_type(good, Dict[str, str])
assert_type(dict(arg=1), Dict[str, int])
_KT = TypeVar("_KT")
_VT = TypeVar("_VT")
class KeysAndGetItem(Generic[_KT, _VT]):
def keys(self) -> Iterable[_KT]:
...
def __getitem__(self, __k: _KT) -> _VT:
...
kt1: KeysAndGetItem[int, str] = KeysAndGetItem()
assert_type(dict(kt1), Dict[int, str])
dict(kt1, arg="a") # type: ignore
kt2: KeysAndGetItem[str, int] = KeysAndGetItem()
assert_type(dict(kt2, arg=1), Dict[str, int])
def test_iterable_tuple_overload(x: Iterable[Tuple[int, str]]) -> Dict[int, str]:
return dict(x)
i1: Iterable[Tuple[int, str]] = [(1, "a"), (2, "b")]
test_iterable_tuple_overload(i1)
dict(i1, arg="a") # type: ignore
i2: Iterable[Tuple[str, int]] = [("a", 1), ("b", 2)]
assert_type(dict(i2, arg=1), Dict[str, int])
i3: Iterable[str] = ["a.b"]
assert_type(dict(string.split(".") for string in i3), Dict[str, str])
dict(["foo", "bar", "baz"]) # type: ignore