Skip to content

Commit 25649bc

Browse files
authored
Add getattr overload variants to help mypy type inference (#6355)
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 python/mypy#11572. I encountered the issue in several places when testing recent typeshed against an internal repo.
1 parent 848753a commit 25649bc

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

stdlib/@python2/__builtin__.pyi

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,13 +850,18 @@ def format(__value: object, __format_spec: str = ...) -> str: ... # TODO unicod
850850
@overload
851851
def getattr(__o: Any, name: Text) -> Any: ...
852852

853-
# While technically covered by the last overload, spelling out the types for None and bool
854-
# help mypy out in some tricky situations involving type context (aka bidirectional inference)
853+
# While technically covered by the last overload, spelling out the types for None, bool
854+
# and basic containers help mypy out in some tricky situations involving type context
855+
# (aka bidirectional inference)
855856
@overload
856857
def getattr(__o: Any, name: Text, __default: None) -> Any | None: ...
857858
@overload
858859
def getattr(__o: Any, name: Text, __default: bool) -> Any | bool: ...
859860
@overload
861+
def getattr(__o: object, name: str, __default: list[Any]) -> Any | list[Any]: ...
862+
@overload
863+
def getattr(__o: object, name: str, __default: dict[Any, Any]) -> Any | dict[Any, Any]: ...
864+
@overload
860865
def getattr(__o: Any, name: Text, __default: _T) -> Any | _T: ...
861866
def globals() -> Dict[str, Any]: ...
862867
def hasattr(__obj: Any, __name: Text) -> bool: ...

stdlib/@python2/builtins.pyi

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,13 +850,18 @@ def format(__value: object, __format_spec: str = ...) -> str: ... # TODO unicod
850850
@overload
851851
def getattr(__o: Any, name: Text) -> Any: ...
852852

853-
# While technically covered by the last overload, spelling out the types for None and bool
854-
# help mypy out in some tricky situations involving type context (aka bidirectional inference)
853+
# While technically covered by the last overload, spelling out the types for None, bool
854+
# and basic containers help mypy out in some tricky situations involving type context
855+
# (aka bidirectional inference)
855856
@overload
856857
def getattr(__o: Any, name: Text, __default: None) -> Any | None: ...
857858
@overload
858859
def getattr(__o: Any, name: Text, __default: bool) -> Any | bool: ...
859860
@overload
861+
def getattr(__o: object, name: str, __default: list[Any]) -> Any | list[Any]: ...
862+
@overload
863+
def getattr(__o: object, name: str, __default: dict[Any, Any]) -> Any | dict[Any, Any]: ...
864+
@overload
860865
def getattr(__o: Any, name: Text, __default: _T) -> Any | _T: ...
861866
def globals() -> Dict[str, Any]: ...
862867
def hasattr(__obj: Any, __name: Text) -> bool: ...

stdlib/builtins.pyi

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,13 +1057,18 @@ def format(__value: object, __format_spec: str = ...) -> str: ... # TODO unicod
10571057
@overload
10581058
def getattr(__o: object, __name: str) -> Any: ...
10591059

1060-
# While technically covered by the last overload, spelling out the types for None and bool
1061-
# help mypy out in some tricky situations involving type context (aka bidirectional inference)
1060+
# While technically covered by the last overload, spelling out the types for None, bool
1061+
# and basic containers help mypy out in some tricky situations involving type context
1062+
# (aka bidirectional inference)
10621063
@overload
10631064
def getattr(__o: object, __name: str, __default: None) -> Any | None: ...
10641065
@overload
10651066
def getattr(__o: object, __name: str, __default: bool) -> Any | bool: ...
10661067
@overload
1068+
def getattr(__o: object, name: str, __default: list[Any]) -> Any | list[Any]: ...
1069+
@overload
1070+
def getattr(__o: object, name: str, __default: dict[Any, Any]) -> Any | dict[Any, Any]: ...
1071+
@overload
10671072
def getattr(__o: object, __name: str, __default: _T) -> Any | _T: ...
10681073
def globals() -> dict[str, Any]: ...
10691074
def hasattr(__obj: object, __name: str) -> bool: ...

0 commit comments

Comments
 (0)