Mypy: Specifying a default of `None` for `Dict.get()` results in a type of `Any` instead of `Optional[Any]`

Created on 13 Dec 2017  路  5Comments  路  Source: python/mypy

Example:

from typing import Dict

def foo(x: Dict) -> str:
    result = x.get('foo', None)
    reveal_type(result)  # E: Revealed type is 'Any'
    return result
from typing import Dict

def foo(x:Dict) -> str:
    result = x.get('foo')
    reveal_type(result)  # E: Revealed type is 'Union[Any, builtins.None]'
    return result  # E: Incompatible return value type (got "Optional[Any]", expected "str")
bug priority-1-normal topic-type-variables

Most helpful comment

x.get(something, None) should return Optional[Any] under strict-optional, and the first example still returns just Any.

All 5 comments

Interesting. Looking at the stub for mapping
https://github.com/python/typeshed/blob/master/stdlib/3/typing.pyi#L338
it appears that since None is acceptable for Any, the return type is just the value type in this case (just Any).

So I believe this is a bug in type variable deduction.

Interesting. If we declare the arg as Dict[str, str] instead we get Optional[int] in both cases. It looks like overload resolution does something funky here.

When I run this with any version of mypy from the past month, I get

from typing import Dict

def foo(x: Dict) -> str:
    result = x.get('foo', None)
    reveal_type(result)  # E: Revealed type is 'Any'
    return result
from typing import Dict
def foo(x:Dict) -> str:
    result = x.get('foo')
    reveal_type(result)  # E: Revealed type is 'Any'
    return result

So, no errors.

Is this still an issue?

x.get(something, None) should return Optional[Any] under strict-optional, and the first example still returns just Any.

OK, this looks like not really an overload issue, so removing the label.

Was this page helpful?
0 / 5 - 0 ratings