From e353eacb728b60539e4a4cdeb0ce7ea4183e254e Mon Sep 17 00:00:00 2001 From: Devin Petersohn Date: Tue, 3 Mar 2026 11:21:21 -0600 Subject: [PATCH] [SPARK-55818][PS] Decimal-float mixed arithmetic should always raise TypeError Co-authored-by: Devin Petersohn Signed-off-by: Devin Petersohn --- .../pyspark/pandas/data_type_ops/num_ops.py | 21 +++----- .../tests/data_type_ops/test_num_mul_div.py | 53 +++++++++---------- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/python/pyspark/pandas/data_type_ops/num_ops.py b/python/pyspark/pandas/data_type_ops/num_ops.py index 17f17cd76d8ad..7c2eddd36e7c7 100644 --- a/python/pyspark/pandas/data_type_ops/num_ops.py +++ b/python/pyspark/pandas/data_type_ops/num_ops.py @@ -461,7 +461,7 @@ def mul(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: raise TypeError("Multiplication can not be applied to given types.") is_ansi = is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) - if is_ansi and _is_decimal_float_mixed(left, right): + if _is_decimal_float_mixed(left, right): raise TypeError("Multiplication can not be applied to given types.") new_right = transform_boolean_operand_to_numeric(right, spark_type=left.spark.data_type) @@ -474,8 +474,7 @@ def wrapped_mul(lc: PySparkColumn, rc: Any) -> PySparkColumn: return column_op(wrapped_mul)(left, new_right) def mod(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: - is_ansi = is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) - if is_ansi and _is_decimal_float_mixed(left, right): + if _is_decimal_float_mixed(left, right): raise TypeError("Modulo can not be applied to given types.") return super().mod(left, right) @@ -485,7 +484,7 @@ def truediv(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: if not is_valid_operand_for_numeric_arithmetic(right): raise TypeError("True division can not be applied to given types.") is_ansi = is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) - if is_ansi and _is_decimal_float_mixed(left, right): + if _is_decimal_float_mixed(left, right): raise TypeError("True division can not be applied to given types.") new_right = transform_boolean_operand_to_numeric(right, spark_type=left.spark.data_type) left_dtype = left.dtype @@ -516,7 +515,7 @@ def floordiv(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: if not is_valid_operand_for_numeric_arithmetic(right): raise TypeError("Floor division can not be applied to given types.") is_ansi = is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) - if is_ansi and _is_decimal_float_mixed(left, right): + if _is_decimal_float_mixed(left, right): raise TypeError("Floor division can not be applied to given types.") left_dtype = left.dtype @@ -548,8 +547,7 @@ def rtruediv(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: if not isinstance(right, numbers.Number): raise TypeError("True division can not be applied to given types.") - is_ansi = is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) - if is_ansi and _is_decimal_float_mixed(left, right): + if _is_decimal_float_mixed(left, right): raise TypeError("True division can not be applied to given types.") def rtruediv(left: PySparkColumn, right: Any) -> PySparkColumn: @@ -565,8 +563,7 @@ def rfloordiv(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: if not isinstance(right, numbers.Number): raise TypeError("Floor division can not be applied to given types.") - is_ansi = is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) - if is_ansi and _is_decimal_float_mixed(left, right): + if _is_decimal_float_mixed(left, right): raise TypeError("Floor division can not be applied to given types.") def rfloordiv(left: PySparkColumn, right: Any) -> PySparkColumn: @@ -578,14 +575,12 @@ def rfloordiv(left: PySparkColumn, right: Any) -> PySparkColumn: return numpy_column_op(rfloordiv)(left, right) def rmul(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: - is_ansi = is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) - if is_ansi and _is_decimal_float_mixed(left, right): + if _is_decimal_float_mixed(left, right): raise TypeError("Multiplication can not be applied to given types.") return super().rmul(left, right) def rmod(self, left: IndexOpsLike, right: Any) -> SeriesOrIndex: - is_ansi = is_ansi_mode_enabled(left._internal.spark_frame.sparkSession) - if is_ansi and _is_decimal_float_mixed(left, right): + if _is_decimal_float_mixed(left, right): raise TypeError("Modulo can not be applied to given types.") return super().rmod(left, right) diff --git a/python/pyspark/pandas/tests/data_type_ops/test_num_mul_div.py b/python/pyspark/pandas/tests/data_type_ops/test_num_mul_div.py index 61721410bab4a..6ff6660d0b8fc 100644 --- a/python/pyspark/pandas/tests/data_type_ops/test_num_mul_div.py +++ b/python/pyspark/pandas/tests/data_type_ops/test_num_mul_div.py @@ -20,7 +20,6 @@ import numpy as np from pyspark import pandas as ps -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 @@ -62,13 +61,12 @@ def test_mul(self): self.assertRaises(TypeError, lambda: psser * psdf["date"]) self.assertRaises(TypeError, lambda: psser * psdf["categorical"]) - if is_ansi_mode_test: - self.assertRaises(TypeError, lambda: psdf["decimal"] * psdf["float"]) - self.assertRaises(TypeError, lambda: psdf["float"] * psdf["decimal"]) - self.assertRaises(TypeError, lambda: psdf["decimal"] * psdf["float32"]) - self.assertRaises(TypeError, lambda: psdf["float32"] * psdf["decimal"]) - self.assertRaises(TypeError, lambda: psdf["decimal"] * 0.1) - self.assertRaises(TypeError, lambda: 0.1 * psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] * psdf["float"]) + self.assertRaises(TypeError, lambda: psdf["float"] * psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] * psdf["float32"]) + self.assertRaises(TypeError, lambda: psdf["float32"] * psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] * 0.1) + self.assertRaises(TypeError, lambda: 0.1 * psdf["decimal"]) def test_truediv(self): pdf, psdf = self.pdf, self.psdf @@ -86,13 +84,12 @@ def test_truediv(self): else: self.assertRaises(TypeError, lambda: psser / psdf[n_col]) - if is_ansi_mode_test: - self.assertRaises(TypeError, lambda: psdf["decimal"] / psdf["float"]) - self.assertRaises(TypeError, lambda: psdf["float"] / psdf["decimal"]) - self.assertRaises(TypeError, lambda: psdf["decimal"] / psdf["float32"]) - self.assertRaises(TypeError, lambda: psdf["float32"] / psdf["decimal"]) - self.assertRaises(TypeError, lambda: psdf["decimal"] / 0.1) - self.assertRaises(TypeError, lambda: 0.1 / psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] / psdf["float"]) + self.assertRaises(TypeError, lambda: psdf["float"] / psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] / psdf["float32"]) + self.assertRaises(TypeError, lambda: psdf["float32"] / psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] / 0.1) + self.assertRaises(TypeError, lambda: 0.1 / psdf["decimal"]) def test_floordiv(self): pdf, psdf = self.pdf, self.psdf @@ -110,13 +107,12 @@ def test_floordiv(self): psser = psdf[col] self.assertRaises(TypeError, lambda: psser // psdf[n_col]) - if is_ansi_mode_test: - self.assertRaises(TypeError, lambda: psdf["decimal"] // psdf["float"]) - self.assertRaises(TypeError, lambda: psdf["float"] // psdf["decimal"]) - self.assertRaises(TypeError, lambda: psdf["decimal"] // psdf["float32"]) - self.assertRaises(TypeError, lambda: psdf["float32"] // psdf["decimal"]) - self.assertRaises(TypeError, lambda: psdf["decimal"] // 0.1) - self.assertRaises(TypeError, lambda: 0.1 // psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] // psdf["float"]) + self.assertRaises(TypeError, lambda: psdf["float"] // psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] // psdf["float32"]) + self.assertRaises(TypeError, lambda: psdf["float32"] // psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] // 0.1) + self.assertRaises(TypeError, lambda: 0.1 // psdf["decimal"]) def test_mod(self): pdf, psdf = self.pdf, self.psdf @@ -139,13 +135,12 @@ def test_mod(self): else: self.assertRaises(TypeError, lambda: psser % psdf[n_col]) - if is_ansi_mode_test: - self.assertRaises(TypeError, lambda: psdf["decimal"] % psdf["float"]) - self.assertRaises(TypeError, lambda: psdf["float"] % psdf["decimal"]) - self.assertRaises(TypeError, lambda: psdf["decimal"] % psdf["float32"]) - self.assertRaises(TypeError, lambda: psdf["float32"] % psdf["decimal"]) - self.assertRaises(TypeError, lambda: psdf["decimal"] % 0.1) - self.assertRaises(TypeError, lambda: 0.1 % psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] % psdf["float"]) + self.assertRaises(TypeError, lambda: psdf["float"] % psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] % psdf["float32"]) + self.assertRaises(TypeError, lambda: psdf["float32"] % psdf["decimal"]) + self.assertRaises(TypeError, lambda: psdf["decimal"] % 0.1) + self.assertRaises(TypeError, lambda: 0.1 % psdf["decimal"]) class NumMulDivTests(