Overload signature of get to return an Optional value and to allow default to take any type to match runtime behavior.

This chage more closely matches the behavior of `get` at runtime.  Users can pass whatever they want in to the default
parameter and it will be returned if the key is absent.  Additionally, `get` should return an `Optional` if called with
only one parameter.

```python
z = {'a': 22}
reveal_type(z.get('b'))
reveal_type(z.get('b', 22))
reveal_type(z.get('b', 'hello'))
```

Before:
```shell
test_get_default.py:2: error: Revealed type is 'builtins.int*'
test_get_default.py:3: error: Revealed type is 'builtins.int*'
test_get_default.py:4: error: Revealed type is 'builtins.int*'
test_get_default.py:4: error: Argument 2 to "get" of "dict" has incompatible type "str"; expected "int"
```

After:
```shell
test_get_default.py:2: error: Revealed type is 'Union[builtins.int*, builtins.None]'
test_get_default.py:3: error: Revealed type is 'builtins.int'
test_get_default.py:4: error: Revealed type is 'Union[builtins.int, builtins.str*]'
```
This commit is contained in:
Roy Williams
2017-01-11 15:36:32 -08:00
committed by Łukasz Langa
parent 05c6c66fa4
commit 6008b9dbb1
4 changed files with 17 additions and 7 deletions

View File

@@ -250,8 +250,10 @@ 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 # type: ignore
def get(self, k: _KT) -> Optional[_VT_co]: ...
@overload # type: ignore
def get(self, k: _KT, default: _T) -> Union[_VT_co, _T]: ...
def items(self) -> AbstractSet[Tuple[_KT, _VT_co]]: ...
def keys(self) -> AbstractSet[_KT]: ...
def values(self) -> ValuesView[_VT_co]: ...