From bb23fc4efb03c6708cacddfce9bed22297e53b20 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 11:48:32 +0000 Subject: [PATCH 01/17] Reduce use of `Any` in builtins --- stdlib/builtins.pyi | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 2393f3c9583b..7cdde610af56 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -105,14 +105,14 @@ class object: def __repr__(self) -> str: ... def __hash__(self) -> int: ... def __format__(self, __format_spec: str) -> str: ... - def __getattribute__(self, __name: str) -> Any: ... + def __getattribute__(self, __name: str) -> object: ... def __delattr__(self, __name: str) -> None: ... def __sizeof__(self) -> int: ... - def __reduce__(self) -> str | Tuple[Any, ...]: ... + def __reduce__(self) -> str | Tuple[object, ...]: ... if sys.version_info >= (3, 8): - def __reduce_ex__(self, __protocol: SupportsIndex) -> str | Tuple[Any, ...]: ... + def __reduce_ex__(self, __protocol: SupportsIndex) -> str | Tuple[object, ...]: ... else: - def __reduce_ex__(self, __protocol: int) -> str | Tuple[Any, ...]: ... + def __reduce_ex__(self, __protocol: int) -> str | Tuple[object, ...]: ... def __dir__(self) -> Iterable[str]: ... def __init_subclass__(cls) -> None: ... @@ -169,7 +169,7 @@ class type(object): def __instancecheck__(self, __instance: Any) -> bool: ... def __subclasscheck__(self, __subclass: type) -> bool: ... @classmethod - def __prepare__(metacls, __name: str, __bases: Tuple[type, ...], **kwds: Any) -> Mapping[str, Any]: ... + def __prepare__(metacls, __name: str, __bases: Tuple[type, ...], **kwds: Any) -> Mapping[str, object]: ... if sys.version_info >= (3, 10): def __or__(self, __t: Any) -> types.UnionType: ... def __ror__(self, __t: Any) -> types.UnionType: ... @@ -847,7 +847,7 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): def items(self) -> _dict_items[_KT, _VT]: ... @classmethod @overload - def fromkeys(cls, __iterable: Iterable[_T], __value: None = ...) -> dict[_T, Any | None]: ... + def fromkeys(cls, __iterable: Iterable[_T], __value: None = ...) -> dict[_T, object | None]: ... @classmethod @overload def fromkeys(cls, __iterable: Iterable[_T], __value: _S) -> dict[_T, _S]: ... @@ -1018,7 +1018,7 @@ if sys.version_info >= (3, 8): optimize: int = ..., *, _feature_version: int = ..., - ) -> Any: ... + ) -> object: ... else: def compile( @@ -1028,11 +1028,11 @@ else: flags: int = ..., dont_inherit: int = ..., optimize: int = ..., - ) -> Any: ... + ) -> object: ... def copyright() -> None: ... def credits() -> None: ... -def delattr(__obj: Any, __name: str) -> None: ... +def delattr(__obj: object, __name: str) -> None: ... def dir(__o: object = ...) -> list[str]: ... @overload def divmod(__x: SupportsDivMod[_T_contra, _T_co], __y: _T_contra) -> _T_co: ... @@ -1040,10 +1040,10 @@ def divmod(__x: SupportsDivMod[_T_contra, _T_co], __y: _T_contra) -> _T_co: ... def divmod(__x: _T_contra, __y: SupportsRDivMod[_T_contra, _T_co]) -> _T_co: ... def eval( __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, Any] | None = ... -) -> Any: ... +) -> object: ... def exec( __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, Any] | None = ... -) -> Any: ... +) -> object: ... def exit(code: object = ...) -> NoReturn: ... class filter(Iterator[_T], Generic[_T]): @@ -1056,29 +1056,29 @@ class filter(Iterator[_T], Generic[_T]): def format(__value: object, __format_spec: str = ...) -> str: ... # TODO unicode @overload -def getattr(__o: object, __name: str) -> Any: ... +def getattr(__o: object, __name: str) -> object: ... # 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) @overload -def getattr(__o: object, __name: str, __default: None) -> Any | None: ... +def getattr(__o: object, __name: str, __default: None) -> object | None: ... @overload -def getattr(__o: object, __name: str, __default: bool) -> Any | bool: ... +def getattr(__o: object, __name: str, __default: bool) -> object | bool: ... @overload -def getattr(__o: object, __name: str, __default: _T) -> Any | _T: ... -def globals() -> dict[str, Any]: ... +def getattr(__o: object, __name: str, __default: _T) -> object | _T: ... +def globals() -> dict[str, object]: ... def hasattr(__obj: object, __name: str) -> bool: ... def hash(__obj: object) -> int: ... def help(*args: Any, **kwds: Any) -> None: ... def hex(__number: int | SupportsIndex) -> str: ... def id(__obj: object) -> int: ... -def input(__prompt: Any = ...) -> str: ... +def input(__prompt: object = ...) -> str: ... @overload def iter(__iterable: Iterable[_T]) -> Iterator[_T]: ... @overload def iter(__function: Callable[[], _T | None], __sentinel: None) -> Iterator[_T]: ... @overload -def iter(__function: Callable[[], _T], __sentinel: Any) -> Iterator[_T]: ... +def iter(__function: Callable[[], _T], __sentinel: object) -> Iterator[_T]: ... if sys.version_info >= (3, 10): def isinstance( @@ -1094,7 +1094,7 @@ else: def len(__obj: Sized) -> int: ... def license() -> None: ... -def locals() -> dict[str, Any]: ... +def locals() -> dict[str, object]: ... class map(Iterator[_S], Generic[_S]): @overload @@ -1329,7 +1329,7 @@ def round(number: SupportsRound[Any]) -> int: ... def round(number: SupportsRound[Any], ndigits: None) -> int: ... @overload def round(number: SupportsRound[_T], ndigits: SupportsIndex) -> _T: ... -def setattr(__obj: object, __name: str, __value: Any) -> None: ... +def setattr(__obj: object, __name: str, __value: object) -> None: ... @overload def sorted(__iterable: Iterable[SupportsLessThanT], *, key: None = ..., reverse: bool = ...) -> list[SupportsLessThanT]: ... @overload @@ -1347,7 +1347,7 @@ else: @overload def sum(__iterable: Iterable[_T], __start: _S) -> _T | _S: ... -def vars(__object: Any = ...) -> dict[str, Any]: ... +def vars(__object: object = ...) -> dict[str, object]: ... class zip(Iterator[_T_co], Generic[_T_co]): if sys.version_info >= (3, 10): @@ -1428,8 +1428,8 @@ class zip(Iterator[_T_co], Generic[_T_co]): def __import__( name: str, - globals: Mapping[str, Any] | None = ..., - locals: Mapping[str, Any] | None = ..., + globals: Mapping[str, object] | None = ..., + locals: Mapping[str, object] | None = ..., fromlist: Sequence[str] = ..., level: int = ..., ) -> Any: ... From 262b52aa63774fb855f8032c7faca07b78d52739 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 12:21:01 +0000 Subject: [PATCH 02/17] Remove more Anys --- stdlib/builtins.pyi | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 7cdde610af56..749481423b45 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1039,10 +1039,10 @@ def divmod(__x: SupportsDivMod[_T_contra, _T_co], __y: _T_contra) -> _T_co: ... @overload def divmod(__x: _T_contra, __y: SupportsRDivMod[_T_contra, _T_co]) -> _T_co: ... def eval( - __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, Any] | None = ... + __source: str | bytes | CodeType, __globals: dict[str, object] | None = ..., __locals: Mapping[str, object] | None = ... ) -> object: ... def exec( - __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, Any] | None = ... + __source: str | bytes | CodeType, __globals: dict[str, object] | None = ..., __locals: Mapping[str, object] | None = ... ) -> object: ... def exit(code: object = ...) -> NoReturn: ... @@ -1082,15 +1082,15 @@ def iter(__function: Callable[[], _T], __sentinel: object) -> Iterator[_T]: ... if sys.version_info >= (3, 10): def isinstance( - __obj: object, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[Any, ...], ...] + __obj: object, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[object, ...], ...] ) -> bool: ... def issubclass( - __cls: type, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[Any, ...], ...] + __cls: type, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[object, ...], ...] ) -> bool: ... else: - def isinstance(__obj: object, __class_or_tuple: type | Tuple[type | Tuple[Any, ...], ...]) -> bool: ... - def issubclass(__cls: type, __class_or_tuple: type | Tuple[type | Tuple[Any, ...], ...]) -> bool: ... + def isinstance(__obj: object, __class_or_tuple: type | Tuple[type | Tuple[object, ...], ...]) -> bool: ... + def issubclass(__cls: type, __class_or_tuple: type | Tuple[type | Tuple[object, ...], ...]) -> bool: ... def len(__obj: Sized) -> int: ... def license() -> None: ... @@ -1432,7 +1432,7 @@ def __import__( locals: Mapping[str, object] | None = ..., fromlist: Sequence[str] = ..., level: int = ..., -) -> Any: ... +) -> object: ... # Actually the type of Ellipsis is , but since it's # not exposed anywhere under that name, we make it private here. From f5cde740d15f566538e4182e2dddfd7d9f1cec40 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 12:37:55 +0000 Subject: [PATCH 03/17] Revert change to `getattr` return type --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 749481423b45..c4acb0379f93 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1056,7 +1056,7 @@ class filter(Iterator[_T], Generic[_T]): def format(__value: object, __format_spec: str = ...) -> str: ... # TODO unicode @overload -def getattr(__o: object, __name: str) -> object: ... +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) From 6a35ca2bd9da5821b8f0a7874f1fa5073764572a Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 13:35:48 +0000 Subject: [PATCH 04/17] Revert `getattr` return changes for realz this time --- stdlib/builtins.pyi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index c4acb0379f93..c2cfa098f501 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1061,11 +1061,11 @@ 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) @overload -def getattr(__o: object, __name: str, __default: None) -> object | None: ... +def getattr(__o: object, __name: str, __default: None) -> Any | None: ... @overload -def getattr(__o: object, __name: str, __default: bool) -> object | bool: ... +def getattr(__o: object, __name: str, __default: bool) -> Any | bool: ... @overload -def getattr(__o: object, __name: str, __default: _T) -> object | _T: ... +def getattr(__o: object, __name: str, __default: _T) -> Any | _T: ... def globals() -> dict[str, object]: ... def hasattr(__obj: object, __name: str) -> bool: ... def hash(__obj: object) -> int: ... From 87c4fcc2f8df14d49f18609d095f0d37ba119163 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 13:50:01 +0000 Subject: [PATCH 05/17] Revert changes to `vars()` return type --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index c2cfa098f501..861c722684d7 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1347,7 +1347,7 @@ else: @overload def sum(__iterable: Iterable[_T], __start: _S) -> _T | _S: ... -def vars(__object: object = ...) -> dict[str, object]: ... +def vars(__object: object = ...) -> dict[str, Any]: ... class zip(Iterator[_T_co], Generic[_T_co]): if sys.version_info >= (3, 10): From 9b709efa3a6faca84c5c92e65dc0c7372de06d2f Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 14:03:45 +0000 Subject: [PATCH 06/17] Revert change to `__import__` return type --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 861c722684d7..57fbe0259c65 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1432,7 +1432,7 @@ def __import__( locals: Mapping[str, object] | None = ..., fromlist: Sequence[str] = ..., level: int = ..., -) -> object: ... +) -> Any: ... # Actually the type of Ellipsis is , but since it's # not exposed anywhere under that name, we make it private here. From ce956d38ed2e7af047cd05909407981bcf7cde31 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 14:16:54 +0000 Subject: [PATCH 07/17] Revert changes to `eval` return type --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 57fbe0259c65..c5c9941f679f 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1040,7 +1040,7 @@ def divmod(__x: SupportsDivMod[_T_contra, _T_co], __y: _T_contra) -> _T_co: ... def divmod(__x: _T_contra, __y: SupportsRDivMod[_T_contra, _T_co]) -> _T_co: ... def eval( __source: str | bytes | CodeType, __globals: dict[str, object] | None = ..., __locals: Mapping[str, object] | None = ... -) -> object: ... +) -> Any: ... def exec( __source: str | bytes | CodeType, __globals: dict[str, object] | None = ..., __locals: Mapping[str, object] | None = ... ) -> object: ... From 8209d1900a9bc9ad79699935f4b717d634e7bc69 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 14:29:23 +0000 Subject: [PATCH 08/17] Revert change to return type of `object.__getattribute__` --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index c5c9941f679f..3c949c8df0e6 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -105,7 +105,7 @@ class object: def __repr__(self) -> str: ... def __hash__(self) -> int: ... def __format__(self, __format_spec: str) -> str: ... - def __getattribute__(self, __name: str) -> object: ... + def __getattribute__(self, __name: str) -> Any: ... def __delattr__(self, __name: str) -> None: ... def __sizeof__(self) -> int: ... def __reduce__(self) -> str | Tuple[object, ...]: ... From 69060a99815440013e2a0950baab61f2d7e1e87a Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 14:52:26 +0000 Subject: [PATCH 09/17] Address review --- stdlib/builtins.pyi | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 3c949c8df0e6..2984b6fc9593 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1008,6 +1008,7 @@ if sys.version_info >= (3, 10): @overload async def anext(__i: SupportsAnext[_T], default: _VT) -> _T | _VT: ... +# TODO: `compile` has a more precise return type in reality; work on a way of expressing that? if sys.version_info >= (3, 8): def compile( source: str | bytes | mod | AST, @@ -1018,7 +1019,7 @@ if sys.version_info >= (3, 8): optimize: int = ..., *, _feature_version: int = ..., - ) -> object: ... + ) -> Any: ... else: def compile( @@ -1028,7 +1029,7 @@ else: flags: int = ..., dont_inherit: int = ..., optimize: int = ..., - ) -> object: ... + ) -> Any: ... def copyright() -> None: ... def credits() -> None: ... @@ -1038,8 +1039,11 @@ def dir(__o: object = ...) -> list[str]: ... def divmod(__x: SupportsDivMod[_T_contra, _T_co], __y: _T_contra) -> _T_co: ... @overload def divmod(__x: _T_contra, __y: SupportsRDivMod[_T_contra, _T_co]) -> _T_co: ... + +# The `globals` argument to `eval` has to be `dict[str, Any]` rather than `dict[str, object]` due to invariance. +# (The `globals` argument has to be a "real dict", rather than any old mapping, unlike the `locals` argument.) def eval( - __source: str | bytes | CodeType, __globals: dict[str, object] | None = ..., __locals: Mapping[str, object] | None = ... + __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, object] | None = ... ) -> Any: ... def exec( __source: str | bytes | CodeType, __globals: dict[str, object] | None = ..., __locals: Mapping[str, object] | None = ... @@ -1080,17 +1084,18 @@ def iter(__function: Callable[[], _T | None], __sentinel: None) -> Iterator[_T]: @overload def iter(__function: Callable[[], _T], __sentinel: object) -> Iterator[_T]: ... +# We need recursive types to express the type of the second argument to `isinstance` properly, hence the use of `Any` if sys.version_info >= (3, 10): def isinstance( - __obj: object, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[object, ...], ...] + __obj: object, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[Any, ...], ...] ) -> bool: ... def issubclass( - __cls: type, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[object, ...], ...] + __cls: type, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[Any, ...], ...] ) -> bool: ... else: - def isinstance(__obj: object, __class_or_tuple: type | Tuple[type | Tuple[object, ...], ...]) -> bool: ... - def issubclass(__cls: type, __class_or_tuple: type | Tuple[type | Tuple[object, ...], ...]) -> bool: ... + def isinstance(__obj: object, __class_or_tuple: type | Tuple[type | Tuple[Any, ...], ...]) -> bool: ... + def issubclass(__cls: type, __class_or_tuple: type | Tuple[type | Tuple[Any, ...], ...]) -> bool: ... def len(__obj: Sized) -> int: ... def license() -> None: ... From dca0a240e668e1ec6950b5601fee40e386533c26 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 15:06:19 +0000 Subject: [PATCH 10/17] Revert change to `globals()` return type --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 2984b6fc9593..73cdc881800c 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1070,7 +1070,7 @@ def getattr(__o: object, __name: str, __default: None) -> Any | None: ... def getattr(__o: object, __name: str, __default: bool) -> Any | bool: ... @overload def getattr(__o: object, __name: str, __default: _T) -> Any | _T: ... -def globals() -> dict[str, object]: ... +def globals() -> dict[str, Any]: ... def hasattr(__obj: object, __name: str) -> bool: ... def hash(__obj: object) -> int: ... def help(*args: Any, **kwds: Any) -> None: ... From 6dee19808e633a73e58b457a7f886028d5d94d17 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 15:19:55 +0000 Subject: [PATCH 11/17] `dict` invariance applies to `exec` as well as `eval` --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 73cdc881800c..dd0f70253387 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1046,7 +1046,7 @@ def eval( __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, object] | None = ... ) -> Any: ... def exec( - __source: str | bytes | CodeType, __globals: dict[str, object] | None = ..., __locals: Mapping[str, object] | None = ... + __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, object] | None = ... ) -> object: ... def exit(code: object = ...) -> NoReturn: ... From ae18109b6ecbbb6002bc077f082c2a3556fb1cd2 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 15:22:31 +0000 Subject: [PATCH 12/17] Revert changes to `locals` so Sebastian doesn't complain ;) --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index dd0f70253387..99be1db3c903 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1099,7 +1099,7 @@ else: def len(__obj: Sized) -> int: ... def license() -> None: ... -def locals() -> dict[str, object]: ... +def locals() -> dict[str, Any]: ... class map(Iterator[_S], Generic[_S]): @overload From a0d5af561e4078821f05ef6cd7edf55064c4ed27 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 15:24:04 +0000 Subject: [PATCH 13/17] Add comment --- stdlib/builtins.pyi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 99be1db3c903..d314d4a5e9b9 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1045,9 +1045,11 @@ def divmod(__x: _T_contra, __y: SupportsRDivMod[_T_contra, _T_co]) -> _T_co: ... def eval( __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, object] | None = ... ) -> Any: ... +# Comment above regarding `eval` applies to `exec` as well def exec( __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, object] | None = ... ) -> object: ... + def exit(code: object = ...) -> NoReturn: ... class filter(Iterator[_T], Generic[_T]): From bd5455f51298f03f0f468d84566b2fd0c5eb298e Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 15:28:11 +0000 Subject: [PATCH 14/17] Apply black --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index d314d4a5e9b9..839a5209077c 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1045,11 +1045,11 @@ def divmod(__x: _T_contra, __y: SupportsRDivMod[_T_contra, _T_co]) -> _T_co: ... def eval( __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, object] | None = ... ) -> Any: ... + # Comment above regarding `eval` applies to `exec` as well def exec( __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, object] | None = ... ) -> object: ... - def exit(code: object = ...) -> NoReturn: ... class filter(Iterator[_T], Generic[_T]): From e37753bb372dd4fc806be5bb39b9f074d8f684e6 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 15:37:17 +0000 Subject: [PATCH 15/17] Revert change to `dict.fromkeys` --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 839a5209077c..34b5c0738cfe 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -847,7 +847,7 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): def items(self) -> _dict_items[_KT, _VT]: ... @classmethod @overload - def fromkeys(cls, __iterable: Iterable[_T], __value: None = ...) -> dict[_T, object | None]: ... + def fromkeys(cls, __iterable: Iterable[_T], __value: None = ...) -> dict[_T, Any | None]: ... @classmethod @overload def fromkeys(cls, __iterable: Iterable[_T], __value: _S) -> dict[_T, _S]: ... From 4ef36d33edfe65bbfbe7aa1b76e3cdeb766503a7 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 16:12:04 +0000 Subject: [PATCH 16/17] Revert return type of exec() Would've been weird to have eval() return Any and exec() return object. --- stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 34b5c0738cfe..393550f12c92 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1049,7 +1049,7 @@ def eval( # Comment above regarding `eval` applies to `exec` as well def exec( __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, object] | None = ... -) -> object: ... +) -> Any: ... def exit(code: object = ...) -> NoReturn: ... class filter(Iterator[_T], Generic[_T]): From 570c014ddbc5dec05b00735974dfe9ccbaa329e1 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 14 Nov 2021 16:29:19 +0000 Subject: [PATCH 17/17] Address review --- stdlib/builtins.pyi | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 839a5209077c..a185fe48bd3f 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1049,7 +1049,7 @@ def eval( # Comment above regarding `eval` applies to `exec` as well def exec( __source: str | bytes | CodeType, __globals: dict[str, Any] | None = ..., __locals: Mapping[str, object] | None = ... -) -> object: ... +) -> None: ... def exit(code: object = ...) -> NoReturn: ... class filter(Iterator[_T], Generic[_T]): @@ -1336,7 +1336,11 @@ def round(number: SupportsRound[Any]) -> int: ... def round(number: SupportsRound[Any], ndigits: None) -> int: ... @overload def round(number: SupportsRound[_T], ndigits: SupportsIndex) -> _T: ... -def setattr(__obj: object, __name: str, __value: object) -> None: ... + +# See https://github.com/python/typeshed/pull/6292#discussion_r748875189 +# for why arg 3 of `setattr` should be annotated with `Any` and not `object` +def setattr(__obj: object, __name: str, __value: Any) -> None: ... + @overload def sorted(__iterable: Iterable[SupportsLessThanT], *, key: None = ..., reverse: bool = ...) -> list[SupportsLessThanT]: ... @overload @@ -1354,7 +1358,9 @@ else: @overload def sum(__iterable: Iterable[_T], __start: _S) -> _T | _S: ... -def vars(__object: object = ...) -> dict[str, Any]: ... +# The argument to `vars()` has to have a `__dict__` attribute, so can't be annotated with `object` +# (A "SupportsDunderDict" protocol doesn't work) +def vars(__object: Any = ...) -> dict[str, Any]: ... class zip(Iterator[_T_co], Generic[_T_co]): if sys.version_info >= (3, 10):