From 6a2bd1fce029696f4703d2ee0fc658441ab8116e Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Sat, 15 Jul 2023 22:49:10 +0200 Subject: [PATCH 1/8] Make bool.__new__ more specific --- stdlib/builtins.pyi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index ea917bddb799..647923cf091e 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -898,8 +898,19 @@ class memoryview(Sequence[int]): def __buffer__(self, __flags: int) -> memoryview: ... def __release_buffer__(self, __buffer: memoryview) -> None: ... +class _Truthy(Protocol): + def __bool__(self) -> Literal[True]: ... + +class _Falsy(Protocol): + def __bool__(self) -> Literal[False]: ... + @final class bool(int): + @overload + def __new__(cls, __o: _Truthy) -> Literal[True]: ... + @overload + def __new__(cls, __o: _Falsy) -> Literal[False]: ... + @overload def __new__(cls, __o: object = ...) -> Self: ... # The following overloads could be represented more elegantly with a TypeVar("_B", bool, int), # however mypy has a bug regarding TypeVar constraints (https://github.com/python/mypy/issues/11880). From d62cae40c79b45c545a8b88f4332094225672116 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Wed, 19 Jul 2023 11:24:35 +0100 Subject: [PATCH 2/8] Add no-arg literal cases --- stdlib/builtins.pyi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 647923cf091e..e11b06025b6d 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -214,6 +214,8 @@ _NegativeInteger: TypeAlias = Literal[-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, - _LiteralInteger = _PositiveInteger | _NegativeInteger | Literal[0] # noqa: Y026 # TODO: Use TypeAlias once mypy bugs are fixed class int: + @overload + def __new__(cls) -> Literal[0]: ... @overload def __new__(cls, __x: str | ReadableBuffer | SupportsInt | SupportsIndex | SupportsTrunc = ...) -> Self: ... @overload @@ -432,6 +434,8 @@ class _TranslateTable(Protocol): def __getitem__(self, __key: int) -> str | int | None: ... class str(Sequence[str]): + @overload + def __new__(cls) -> Literal[""]: ... @overload def __new__(cls, object: object = ...) -> Self: ... @overload @@ -612,6 +616,8 @@ class str(Sequence[str]): def __getnewargs__(self) -> tuple[str]: ... class bytes(Sequence[int]): + @overload + def __new__(cls) -> Literal[b""]: ... @overload def __new__(cls, __o: Iterable[SupportsIndex] | SupportsIndex | SupportsBytes | ReadableBuffer) -> Self: ... @overload @@ -906,6 +912,8 @@ class _Falsy(Protocol): @final class bool(int): + @overload + def __new__(cls) -> Literal[False]: ... @overload def __new__(cls, __o: _Truthy) -> Literal[True]: ... @overload From d2541c92df74c5cea63dac7c877f4506153eb239 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Wed, 19 Jul 2023 11:44:23 +0100 Subject: [PATCH 3/8] Remove changes to str, int and bytes --- stdlib/builtins.pyi | 6 ------ 1 file changed, 6 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index e11b06025b6d..149b1146f91a 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -214,8 +214,6 @@ _NegativeInteger: TypeAlias = Literal[-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, - _LiteralInteger = _PositiveInteger | _NegativeInteger | Literal[0] # noqa: Y026 # TODO: Use TypeAlias once mypy bugs are fixed class int: - @overload - def __new__(cls) -> Literal[0]: ... @overload def __new__(cls, __x: str | ReadableBuffer | SupportsInt | SupportsIndex | SupportsTrunc = ...) -> Self: ... @overload @@ -434,8 +432,6 @@ class _TranslateTable(Protocol): def __getitem__(self, __key: int) -> str | int | None: ... class str(Sequence[str]): - @overload - def __new__(cls) -> Literal[""]: ... @overload def __new__(cls, object: object = ...) -> Self: ... @overload @@ -616,8 +612,6 @@ class str(Sequence[str]): def __getnewargs__(self) -> tuple[str]: ... class bytes(Sequence[int]): - @overload - def __new__(cls) -> Literal[b""]: ... @overload def __new__(cls, __o: Iterable[SupportsIndex] | SupportsIndex | SupportsBytes | ReadableBuffer) -> Self: ... @overload From 3b645bf7ec3f4021aebb35a100ad0b24da50aa7d Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Wed, 19 Jul 2023 11:52:45 +0100 Subject: [PATCH 4/8] Simplify overloads Co-authored-by: Alex Waygood --- stdlib/builtins.pyi | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 149b1146f91a..ec077976610f 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -906,14 +906,12 @@ class _Falsy(Protocol): @final class bool(int): - @overload - def __new__(cls) -> Literal[False]: ... @overload def __new__(cls, __o: _Truthy) -> Literal[True]: ... @overload - def __new__(cls, __o: _Falsy) -> Literal[False]: ... + def __new__(cls, __o: _Falsy = ...) -> Literal[False]: ... @overload - def __new__(cls, __o: object = ...) -> Self: ... + def __new__(cls, __o: object) -> Self: ... # The following overloads could be represented more elegantly with a TypeVar("_B", bool, int), # however mypy has a bug regarding TypeVar constraints (https://github.com/python/mypy/issues/11880). @overload From 376e10c231910bedb7d0ab74fbdedb2c93d6f324 Mon Sep 17 00:00:00 2001 From: James Hilton-Balfe Date: Mon, 13 Oct 2025 11:27:19 +0100 Subject: [PATCH 5/8] Update mypy dependency to specific git version --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 31c12c50bc2b..aac6873bc6da 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -1,6 +1,6 @@ # Type checkers that we test our stubs against. These should always # be pinned to a specific version to make failure reproducible. -mypy==1.18.2 +mypy @ git+https://github.com/python/mypy@6aa44da pyright==1.1.406 # Libraries used by our various scripts. From b44f1823ebfcbd2578ee4e73a9169bc00d6be5bd Mon Sep 17 00:00:00 2001 From: Gobot1234 Date: Thu, 15 Jan 2026 16:26:44 +0000 Subject: [PATCH 6/8] idk why you'd do this tbh --- stdlib/builtins.pyi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 176dad8bd1a1..97d08dc2ce65 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -980,6 +980,10 @@ class bool(int): def __new__(cls, o: _Falsy = False, /) -> Literal[False]: ... @overload def __new__(cls, o: object, /) -> Self: ... + @overload + def __bool__(self: Literal[True]) -> Literal[True]: ... + @overload + def __bool__(self: Literal[False]) -> Literal[False]: ... # The following overloads could be represented more elegantly with a TypeVar("_B", bool, int), # however mypy has a bug regarding TypeVar constraints (https://github.com/python/mypy/issues/11880). @overload From b0d65d527d1606c407cdc84b30a8014d21996fdd Mon Sep 17 00:00:00 2001 From: Gobot1234 Date: Thu, 15 Jan 2026 16:27:18 +0000 Subject: [PATCH 7/8] add some checks for all this --- .../@tests/test_cases/builtins/check_bool.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 stdlib/@tests/test_cases/builtins/check_bool.py diff --git a/stdlib/@tests/test_cases/builtins/check_bool.py b/stdlib/@tests/test_cases/builtins/check_bool.py new file mode 100644 index 000000000000..d1850383f863 --- /dev/null +++ b/stdlib/@tests/test_cases/builtins/check_bool.py @@ -0,0 +1,21 @@ +from typing_extensions import Literal, assert_type + + +assert_type(bool(), Literal[False]) +assert_type(bool(False), Literal[False]) +assert_type(bool(True), Literal[True]) +assert_type(bool(42), bool) + + +class Truthy: + def __bool__(self) -> Literal[True]: + return True + + +class Falsy: + def __bool__(self) -> Literal[False]: + return False + + +assert_type(bool(Truthy()), Literal[True]) +assert_type(bool(Falsy()), Literal[False]) From 4c7890456add80326e92e1901cff187bc3785ee6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 16:29:45 +0000 Subject: [PATCH 8/8] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/@tests/test_cases/builtins/check_bool.py | 1 - 1 file changed, 1 deletion(-) diff --git a/stdlib/@tests/test_cases/builtins/check_bool.py b/stdlib/@tests/test_cases/builtins/check_bool.py index d1850383f863..25f83c98e901 100644 --- a/stdlib/@tests/test_cases/builtins/check_bool.py +++ b/stdlib/@tests/test_cases/builtins/check_bool.py @@ -1,6 +1,5 @@ from typing_extensions import Literal, assert_type - assert_type(bool(), Literal[False]) assert_type(bool(False), Literal[False]) assert_type(bool(True), Literal[True])