From 18b506e6a41dcf8d947802d74ef983f616c6b2e9 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Thu, 15 Sep 2016 16:31:46 -0700 Subject: [PATCH] Better signature for Mapping.get(). Fixes #278. The approach here is different from what we thought before. According to this commit, there are three valid forms of Mapping[K, V].get(): d.get() # returns Optional[V] d.get(None) # also returns Optional[V] (seen in the wild) d.get(v) # requires v to have type V, and returns V So we don't allow d.get(d) where d is a type unrelated to V. This is a compromise, but I don't think there's much use for d.get(d) with a default that is differently-typed than V, and when I tried it my application code (that didn't use this) wouldn't type-check correctly. --- stdlib/2.7/UserDict.pyi | 7 +++++-- stdlib/2.7/__builtin__.pyi | 6 +++++- stdlib/2.7/typing.pyi | 6 +++++- stdlib/3/builtins.pyi | 5 ++++- stdlib/3/typing.pyi | 6 +++++- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/stdlib/2.7/UserDict.pyi b/stdlib/2.7/UserDict.pyi index 10525fe116cc..fc9e15b796cf 100644 --- a/stdlib/2.7/UserDict.pyi +++ b/stdlib/2.7/UserDict.pyi @@ -1,5 +1,5 @@ from typing import (Any, Container, Dict, Generic, Iterable, Iterator, List, - Mapping, Sized, Tuple, TypeVar, overload) + Mapping, Optional, Sized, Tuple, TypeVar, overload) _KT = TypeVar('_KT') _VT = TypeVar('_VT') @@ -19,7 +19,10 @@ class DictMixin(Sized, Iterable[_KT], Container[_KT], Generic[_KT, _VT]): # From typing.Mapping[_KT, _VT] # (can't inherit because of keys()) - def get(self, k: _KT, default: _VT = ...) -> _VT: ... + @overload + def get(self, k: _KT, default: Optional[None] = ...) -> Optional[_VT]: ... + @overload + def get(self, k: _KT, default: _VT) -> _VT: ... def values(self) -> List[_VT]: ... def items(self) -> List[Tuple[_KT, _VT]]: ... def iterkeys(self) -> Iterator[_KT]: ... diff --git a/stdlib/2.7/__builtin__.pyi b/stdlib/2.7/__builtin__.pyi index e47720477ee8..d4e41b7f9a76 100644 --- a/stdlib/2.7/__builtin__.pyi +++ b/stdlib/2.7/__builtin__.pyi @@ -532,7 +532,11 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): def has_key(self, k: _KT) -> bool: ... def clear(self) -> None: ... def copy(self) -> Dict[_KT, _VT]: ... - def get(self, k: _KT, default: _VT = None) -> _VT: ... + @overload + def get(self, k: _KT, default: Optional[None] = ...) -> Optional[_VT]: + ... + @overload + def get(self, k: _KT, default: _VT) -> _VT: ... def pop(self, k: _KT, default: _VT = ...) -> _VT: ... def popitem(self) -> Tuple[_KT, _VT]: ... def setdefault(self, k: _KT, default: _VT = ...) -> _VT: ... diff --git a/stdlib/2.7/typing.pyi b/stdlib/2.7/typing.pyi index 90a22292df24..9415e2aebc08 100644 --- a/stdlib/2.7/typing.pyi +++ b/stdlib/2.7/typing.pyi @@ -180,7 +180,11 @@ class Mapping(Sized, Iterable[_KT], Container[_KT], Generic[_KT, _VT_co]): def __getitem__(self, k: _KT) -> _VT_co: ... # Mixin methods - def get(self, k: _KT, default: _VT_co = ...) -> _VT_co: # type: ignore + @overload + def get(self, k: _KT, default: Optional[None] = ...) -> Optional[_VT_co]: # type: ignore + ... + @overload # type: ignore + def get(self, k: _KT, default: _VT_co) -> _VT_co: # type: ignore ... def keys(self) -> list[_KT]: ... def values(self) -> list[_VT_co]: ... diff --git a/stdlib/3/builtins.pyi b/stdlib/3/builtins.pyi index 774b90808605..bf18d5601c24 100644 --- a/stdlib/3/builtins.pyi +++ b/stdlib/3/builtins.pyi @@ -517,7 +517,10 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): def __init__(self, iterable: Iterable[Tuple[_KT, _VT]], **kwargs: _VT) -> None: ... def clear(self) -> None: ... def copy(self) -> Dict[_KT, _VT]: ... - def get(self, k: _KT, default: _VT = None) -> _VT: ... + @overload + def get(self, k: _KT, default: Optional[None] = ...) -> Optional[_VT]: ... + @overload + def get(self, k: _KT, default: _VT) -> _VT: ... def pop(self, k: _KT, default: _VT = None) -> _VT: ... def popitem(self) -> Tuple[_KT, _VT]: ... def setdefault(self, k: _KT, default: _VT = None) -> _VT: ... diff --git a/stdlib/3/typing.pyi b/stdlib/3/typing.pyi index 9629020a366d..ab5172f0eef9 100644 --- a/stdlib/3/typing.pyi +++ b/stdlib/3/typing.pyi @@ -230,7 +230,11 @@ class Mapping(Iterable[_KT], Container[_KT], Sized, Generic[_KT, _VT_co]): def __getitem__(self, k: _KT) -> _VT_co: ... # Mixin methods - def get(self, k: _KT, default: _VT_co = ...) -> _VT_co: # type: ignore + @overload + def get(self, k: _KT, default: Optional[None] = ...) -> Optional[_VT_co]: # type: ignore + ... + @overload # type: ignore + def get(self, k: _KT, default: _VT_co) -> _VT_co: # type: ignore ... def items(self) -> AbstractSet[Tuple[_KT, _VT_co]]: ... def keys(self) -> AbstractSet[_KT]: ...