From ec7f4019589a8db76c614d840ddec5ce8008426b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Diridollou?= Date: Tue, 11 Nov 2025 21:18:20 -0500 Subject: [PATCH 1/5] GH1411 Add __and__ for BooleanArray and tests --- pandas-stubs/_typing.pyi | 3 +-- pandas-stubs/core/arrays/boolean.pyi | 2 ++ tests/test_extension.py | 9 +++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pandas-stubs/_typing.pyi b/pandas-stubs/_typing.pyi index 5ba453ecd..c798dd295 100644 --- a/pandas-stubs/_typing.pyi +++ b/pandas-stubs/_typing.pyi @@ -21,7 +21,6 @@ from typing import ( SupportsIndex, TypeAlias, TypedDict, - Union, overload, ) @@ -554,7 +553,7 @@ IndexKeyFunc: TypeAlias = Callable[[Index], Index | AnyArrayLike] | None # types of `func` kwarg for DataFrame.aggregate and Series.aggregate # More specific than what is in pandas # following Union is here to make it ty compliant https://github.com/astral-sh/ty/issues/591 -AggFuncTypeBase: TypeAlias = Union[Callable, str, np.ufunc] # noqa: UP007 +AggFuncTypeBase: TypeAlias = Callable | str | np.ufunc AggFuncTypeDictSeries: TypeAlias = Mapping[HashableT, AggFuncTypeBase] AggFuncTypeDictFrame: TypeAlias = Mapping[ HashableT, AggFuncTypeBase | list[AggFuncTypeBase] diff --git a/pandas-stubs/core/arrays/boolean.pyi b/pandas-stubs/core/arrays/boolean.pyi index ed0b61477..715b13455 100644 --- a/pandas-stubs/core/arrays/boolean.pyi +++ b/pandas-stubs/core/arrays/boolean.pyi @@ -1,6 +1,7 @@ from typing import Any from pandas.core.arrays.masked import BaseMaskedArray as BaseMaskedArray +from typing_extensions import Self from pandas._libs.missing import NAType from pandas._typing import ( @@ -25,3 +26,4 @@ class BooleanArray(BaseMaskedArray): def __setitem__(self, key, value) -> None: ... def any(self, *, skipna: bool = ..., **kwargs: Any): ... def all(self, *, skipna: bool = ..., **kwargs: Any): ... + def __and__(self, other: BooleanArray) -> Self: ... diff --git a/tests/test_extension.py b/tests/test_extension.py index 0f8653386..d5c0ca5a1 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -3,6 +3,7 @@ import numpy as np import pandas as pd from pandas.arrays import IntegerArray +from pandas.core.arrays.boolean import BooleanArray from pandas.core.indexers import check_array_indexer from typing_extensions import assert_type @@ -56,3 +57,11 @@ def test_array_indexer() -> None: check(assert_type(check_array_indexer(arr, 1), int), int) check(assert_type(check_array_indexer(arr, slice(0, 1, 1)), slice), slice) + + +def test_boolean_array() -> None: + """Test creation of and operations on BooleanArray GH1411.""" + arr = pd.array([True], dtype="boolean") + check(assert_type(arr, BooleanArray), BooleanArray) + arr_and = arr.__and__(arr) + check(assert_type(arr_and, BooleanArray), BooleanArray) From 6376849ca85d7c04c99cd5bac70fabfb699e35ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Diridollou?= Date: Tue, 11 Nov 2025 21:21:33 -0500 Subject: [PATCH 2/5] GH1411 Add __and__ for BooleanArray and tests --- pandas-stubs/_typing.pyi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas-stubs/_typing.pyi b/pandas-stubs/_typing.pyi index c798dd295..5ba453ecd 100644 --- a/pandas-stubs/_typing.pyi +++ b/pandas-stubs/_typing.pyi @@ -21,6 +21,7 @@ from typing import ( SupportsIndex, TypeAlias, TypedDict, + Union, overload, ) @@ -553,7 +554,7 @@ IndexKeyFunc: TypeAlias = Callable[[Index], Index | AnyArrayLike] | None # types of `func` kwarg for DataFrame.aggregate and Series.aggregate # More specific than what is in pandas # following Union is here to make it ty compliant https://github.com/astral-sh/ty/issues/591 -AggFuncTypeBase: TypeAlias = Callable | str | np.ufunc +AggFuncTypeBase: TypeAlias = Union[Callable, str, np.ufunc] # noqa: UP007 AggFuncTypeDictSeries: TypeAlias = Mapping[HashableT, AggFuncTypeBase] AggFuncTypeDictFrame: TypeAlias = Mapping[ HashableT, AggFuncTypeBase | list[AggFuncTypeBase] From da88cab21ab37bd76ac93dda9b74e717045876de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Diridollou?= Date: Tue, 11 Nov 2025 21:27:21 -0500 Subject: [PATCH 3/5] GH1411 Change __and__ method to & --- tests/test_extension.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_extension.py b/tests/test_extension.py index d5c0ca5a1..9360867a1 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -63,5 +63,5 @@ def test_boolean_array() -> None: """Test creation of and operations on BooleanArray GH1411.""" arr = pd.array([True], dtype="boolean") check(assert_type(arr, BooleanArray), BooleanArray) - arr_and = arr.__and__(arr) + arr_and = arr & arr check(assert_type(arr_and, BooleanArray), BooleanArray) From 1139133d683f18d2e5dd1b108d2767736065a863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Diridollou?= Date: Wed, 12 Nov 2025 07:30:16 -0500 Subject: [PATCH 4/5] GH1411 PR Feedback --- pandas-stubs/core/arrays/boolean.pyi | 28 +++++++++++++++++++++++++++- tests/test_extension.py | 13 +++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/pandas-stubs/core/arrays/boolean.pyi b/pandas-stubs/core/arrays/boolean.pyi index 715b13455..478ef8f9a 100644 --- a/pandas-stubs/core/arrays/boolean.pyi +++ b/pandas-stubs/core/arrays/boolean.pyi @@ -1,5 +1,8 @@ +from collections.abc import Sequence from typing import Any +import numpy as np +from pandas.core.arrays.integer import IntegerArray from pandas.core.arrays.masked import BaseMaskedArray as BaseMaskedArray from typing_extensions import Self @@ -26,4 +29,27 @@ class BooleanArray(BaseMaskedArray): def __setitem__(self, key, value) -> None: ... def any(self, *, skipna: bool = ..., **kwargs: Any): ... def all(self, *, skipna: bool = ..., **kwargs: Any): ... - def __and__(self, other: BooleanArray) -> Self: ... + def __and__( + self, + other: ( + bool + | np.bool + | NAType + | Sequence[bool | np.bool] + | np_ndarray_bool + | IntegerArray + | Self + ), + ) -> Self: ... + def __rand__( + self, + other: ( + bool + | np.bool + | NAType + | Sequence[bool | np.bool] + | np_ndarray_bool + | IntegerArray + | Self + ), + ) -> Self: ... diff --git a/tests/test_extension.py b/tests/test_extension.py index 9360867a1..b2c0d8182 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -62,6 +62,19 @@ def test_array_indexer() -> None: def test_boolean_array() -> None: """Test creation of and operations on BooleanArray GH1411.""" arr = pd.array([True], dtype="boolean") + arr_bool = pd.array([True, False]) + arr_int = pd.array([3, 5]) check(assert_type(arr, BooleanArray), BooleanArray) arr_and = arr & arr check(assert_type(arr_and, BooleanArray), BooleanArray) + + check(assert_type(arr_bool & True, BooleanArray), BooleanArray) + check(assert_type(arr_bool & np.bool(True), BooleanArray), BooleanArray) + check(assert_type(arr_bool & pd.NA, BooleanArray), BooleanArray) + check(assert_type(arr_bool & [True, False], BooleanArray), BooleanArray) + check(assert_type(arr_bool & [np.bool(True), False], BooleanArray), BooleanArray) + # TODO: andas-dev/pandas#63095 + # check(assert_type(b & [pd.NA, False]) # not working, maybe worthy reporting + check(assert_type(arr_bool & np.array([True, False]), BooleanArray), BooleanArray) + check(assert_type(arr_bool & arr_int, BooleanArray), BooleanArray) + check(assert_type(arr_bool & arr_bool, BooleanArray), BooleanArray) From f58e63ff8f01ff1a014559a2c66d973f5436a4b5 Mon Sep 17 00:00:00 2001 From: Loic Diridollou Date: Wed, 12 Nov 2025 13:57:49 +0000 Subject: [PATCH 5/5] Update tests/test_extension.py Co-authored-by: Yi-Fan Wang --- tests/test_extension.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_extension.py b/tests/test_extension.py index b2c0d8182..3ae383334 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -73,8 +73,8 @@ def test_boolean_array() -> None: check(assert_type(arr_bool & pd.NA, BooleanArray), BooleanArray) check(assert_type(arr_bool & [True, False], BooleanArray), BooleanArray) check(assert_type(arr_bool & [np.bool(True), False], BooleanArray), BooleanArray) - # TODO: andas-dev/pandas#63095 - # check(assert_type(b & [pd.NA, False]) # not working, maybe worthy reporting + # TODO: pandas-dev/pandas#63095 + # check(assert_type(b & [pd.NA, False]) check(assert_type(arr_bool & np.array([True, False]), BooleanArray), BooleanArray) check(assert_type(arr_bool & arr_int, BooleanArray), BooleanArray) check(assert_type(arr_bool & arr_bool, BooleanArray), BooleanArray)