diff --git a/python/pyspark/pandas/data_type_ops/boolean_ops.py b/python/pyspark/pandas/data_type_ops/boolean_ops.py index d8fccb9d18847..d9a24dee08028 100644 --- a/python/pyspark/pandas/data_type_ops/boolean_ops.py +++ b/python/pyspark/pandas/data_type_ops/boolean_ops.py @@ -237,6 +237,12 @@ def rmod(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: def __and__(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: _sanitize_list_like(right) + if ( + is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) + and self.dtype == bool + and right is None + ): + raise TypeError("AND can not be applied to given types.") if isinstance(right, IndexOpsMixin) and isinstance(right.dtype, extension_dtypes): return right.__and__(left) else: @@ -256,6 +262,12 @@ def and_func(left: PySparkColumn, right: Any) -> PySparkColumn: def xor(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: _sanitize_list_like(right) + if ( + is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) + and self.dtype == bool + and right is None + ): + raise TypeError("XOR can not be applied to given types.") if isinstance(right, IndexOpsMixin) and isinstance(right.dtype, extension_dtypes): return right ^ left elif _is_valid_for_logical_operator(right): @@ -277,6 +289,12 @@ def xor_func(left: PySparkColumn, right: Any) -> PySparkColumn: def __or__(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: _sanitize_list_like(right) + if ( + is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) + and self.dtype == bool + and right is None + ): + raise TypeError("OR can not be applied to given types.") if isinstance(right, IndexOpsMixin) and isinstance(right.dtype, extension_dtypes): return right.__or__(left) else: diff --git a/python/pyspark/pandas/tests/data_type_ops/test_boolean_ops.py b/python/pyspark/pandas/tests/data_type_ops/test_boolean_ops.py index c4430fa33f19e..10ce6d5c9858b 100644 --- a/python/pyspark/pandas/tests/data_type_ops/test_boolean_ops.py +++ b/python/pyspark/pandas/tests/data_type_ops/test_boolean_ops.py @@ -24,6 +24,7 @@ from pyspark import pandas as ps from pyspark.pandas import option_context +from pyspark.testing.utils import is_ansi_mode_test from pyspark.testing.pandasutils import PandasOnSparkTestCase from pyspark.pandas.tests.data_type_ops.testing_utils import OpsTestBase from pyspark.pandas.typedef.typehints import ( @@ -255,11 +256,15 @@ def test_and(self): self.assert_eq(pser & pser, psser & psser) self.assert_eq(pser & other_pser, psser & other_psser) self.assert_eq(other_pser & pser, other_psser & psser) + if is_ansi_mode_test: + self.assertRaises(TypeError, lambda: psser & None) def test_rand(self): pser, psser = self.pdf["bool"], self.psdf["bool"] self.assert_eq(True & pser, True & psser) self.assert_eq(False & pser, False & psser) + if is_ansi_mode_test: + self.assertRaises(TypeError, lambda: None & psser) def test_or(self): pdf, psdf = self.bool_pdf, self.bool_psdf @@ -269,16 +274,18 @@ def test_or(self): self.assert_eq(pser | True, psser | True) self.assert_eq(pser | False, psser | False) self.assert_eq(pser | pser, psser | psser) - self.assert_eq(True | pser, True | psser) - self.assert_eq(False | pser, False | psser) self.assert_eq(pser | other_pser, psser | other_psser) self.assert_eq(other_pser | pser, other_psser | psser) + if is_ansi_mode_test: + self.assertRaises(TypeError, lambda: psser | None) def test_ror(self): pser, psser = self.pdf["bool"], self.psdf["bool"] self.assert_eq(True | pser, True | psser) self.assert_eq(False | pser, False | psser) + if is_ansi_mode_test: + self.assertRaises(TypeError, lambda: None | psser) def test_xor(self): pdf, psdf = self.bool_pdf, self.bool_psdf @@ -293,6 +300,8 @@ def test_xor(self): with self.assertRaisesRegex(TypeError, "XOR can not be applied to given types."): psser ^ "a" + if is_ansi_mode_test: + self.assertRaises(TypeError, lambda: psser ^ None) with option_context("compute.ops_on_diff_frames", True): pser, other_pser = self.pdf["bool"], self.integral_pdf["this"] @@ -305,6 +314,8 @@ def test_rxor(self): self.assert_eq(True ^ pser, True ^ psser) self.assert_eq(False ^ pser, False ^ psser) self.assert_eq(1 ^ pser, 1 ^ psser) + if is_ansi_mode_test: + self.assertRaises(TypeError, lambda: None ^ psser) def test_isnull(self): self.assert_eq(self.pdf["bool"].isnull(), self.psdf["bool"].isnull()) @@ -721,8 +732,8 @@ def test_xor(self): def test_rxor(self): pser, psser = self.boolean_pdf["this"], self.boolean_psdf["this"] - self.check_extension(True | pser, True | psser) - self.check_extension(False | pser, False | psser) + self.check_extension(True ^ pser, True ^ psser) + self.check_extension(False ^ pser, False ^ psser) with self.assertRaisesRegex(TypeError, "XOR can not be applied to given types."): 1 ^ psser