Skip to content

Commit

Permalink
Add getattr overload variants to help mypy type inference
Browse files Browse the repository at this point in the history
These silence errors about missing type annotations for calls
like these:

```
x = getattr(o, 'a', [])
y = getattr(o, 'b', {})
```

This is basically a generalization of #5518 and other overloads we already
have.

This works around #11572. I encountered the issue in several
places when testing recent typeshed against an internal repo.

Manually cherry-picked from python/typeshed#6355.
  • Loading branch information
JukkaL committed Nov 23, 2021
1 parent 5733d29 commit f08d72b
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 6 deletions.
9 changes: 7 additions & 2 deletions mypy/typeshed/stdlib/@python2/__builtin__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -850,13 +850,18 @@ def format(__value: object, __format_spec: str = ...) -> str: ... # TODO unicod
@overload
def getattr(__o: Any, name: Text) -> Any: ...

# While technically covered by the last overload, spelling out the types for None and bool
# help mypy out in some tricky situations involving type context (aka bidirectional inference)
# While technically covered by the last overload, spelling out the types for None, bool
# and basic containers help mypy out in some tricky situations involving type context
# (aka bidirectional inference)
@overload
def getattr(__o: Any, name: Text, __default: None) -> Any | None: ...
@overload
def getattr(__o: Any, name: Text, __default: bool) -> Any | bool: ...
@overload
def getattr(__o: object, name: str, __default: list[Any]) -> Any | list[Any]: ...
@overload
def getattr(__o: object, name: str, __default: dict[Any, Any]) -> Any | dict[Any, Any]: ...
@overload
def getattr(__o: Any, name: Text, __default: _T) -> Any | _T: ...
def globals() -> Dict[str, Any]: ...
def hasattr(__obj: Any, __name: Text) -> bool: ...
Expand Down
9 changes: 7 additions & 2 deletions mypy/typeshed/stdlib/@python2/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -850,13 +850,18 @@ def format(__value: object, __format_spec: str = ...) -> str: ... # TODO unicod
@overload
def getattr(__o: Any, name: Text) -> Any: ...

# While technically covered by the last overload, spelling out the types for None and bool
# help mypy out in some tricky situations involving type context (aka bidirectional inference)
# While technically covered by the last overload, spelling out the types for None, bool
# and basic containers help mypy out in some tricky situations involving type context
# (aka bidirectional inference)
@overload
def getattr(__o: Any, name: Text, __default: None) -> Any | None: ...
@overload
def getattr(__o: Any, name: Text, __default: bool) -> Any | bool: ...
@overload
def getattr(__o: object, name: str, __default: list[Any]) -> Any | list[Any]: ...
@overload
def getattr(__o: object, name: str, __default: dict[Any, Any]) -> Any | dict[Any, Any]: ...
@overload
def getattr(__o: Any, name: Text, __default: _T) -> Any | _T: ...
def globals() -> Dict[str, Any]: ...
def hasattr(__obj: Any, __name: Text) -> bool: ...
Expand Down
9 changes: 7 additions & 2 deletions mypy/typeshed/stdlib/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1023,13 +1023,18 @@ def format(__value: object, __format_spec: str = ...) -> str: ... # TODO unicod
@overload
def getattr(__o: object, name: str) -> Any: ...

# While technically covered by the last overload, spelling out the types for None and bool
# help mypy out in some tricky situations involving type context (aka bidirectional inference)
# While technically covered by the last overload, spelling out the types for None, bool
# and basic containers help mypy out in some tricky situations involving type context
# (aka bidirectional inference)
@overload
def getattr(__o: object, name: str, __default: None) -> Any | None: ...
@overload
def getattr(__o: object, name: str, __default: bool) -> Any | bool: ...
@overload
def getattr(__o: object, name: str, __default: list[Any]) -> Any | list[Any]: ...
@overload
def getattr(__o: object, name: str, __default: dict[Any, Any]) -> Any | dict[Any, Any]: ...
@overload
def getattr(__o: object, name: str, __default: _T) -> Any | _T: ...
def globals() -> dict[str, Any]: ...
def hasattr(__obj: object, __name: str) -> bool: ...
Expand Down

0 comments on commit f08d72b

Please sign in to comment.