From 6f7f4fb0219017c0db318c0df48a6520f2249425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Weing=C3=A4rtner?= Date: Sat, 26 Sep 2026 09:24:03 -0300 Subject: [PATCH] Address unsupported operand type(s): 'decimal.Decimal' and 'float' This patch address situation around mixed type operations. For instance, the following expression, "(1 + 3 + 2.0 + 6) * 0.00001", when evaluated, causes the following error: ``` >>> from mathparse import mathparse >>> mathparse.parse("(1 + 3 + 2.0 + 6) * 0.00001") Traceback (most recent call last): File "", line 1, in File "/home/rafael/git/mathparse/mathparse/mathparse.py", line 792, in parse tokens = tokenize(string, language) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/rafael/git/mathparse/mathparse/mathparse.py", line 570, in evaluate_postfix total = to_number(a) + to_number(b) ~~~~~~~~~~~~~^~~~~~~~~~~~~~ TypeError: unsupported operand type(s) for *: 'decimal.Decimal' and 'float' ``` This patch normalizes the "to_number" operation, to always return Decimal objects. Therefore, the error will not occur, by mixing Number types. --- mathparse/mathparse.py | 16 ++++++++++------ tests/test_complex_statements.py | 7 +++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/mathparse/mathparse.py b/mathparse/mathparse.py index 8aaab68..7b99b13 100644 --- a/mathparse/mathparse.py +++ b/mathparse/mathparse.py @@ -85,19 +85,23 @@ def to_number(val) -> Union[int, float, str, Decimal]: """ Convert a string to an int or float if possible. """ - # If already a number (int, float, Decimal), return as-is - if isinstance(val, (int, float, Decimal)): - return val + # If already a number (Decimal), return as-is + if isinstance(val, Decimal): + return Decimal(val) + + # Convert other numbers to Decimal + if isinstance(val, (int, float)): + return Decimal(val) # Check if it's a constant and convert if is_constant(val): - return mathwords.CONSTANTS[val] + return Decimal(mathwords.CONSTANTS[val]) # Otherwise, try to convert string to number if is_int(val): - return int(val) + return Decimal(int(val)) elif is_float(val): - return float(val) + return Decimal(float(val)) return val diff --git a/tests/test_complex_statements.py b/tests/test_complex_statements.py index d79b439..0cc2b3c 100644 --- a/tests/test_complex_statements.py +++ b/tests/test_complex_statements.py @@ -78,3 +78,10 @@ def test_unicode_pi_in_expression(self): """ result = mathparse.parse('π + 1') self.assertAlmostEqual(result, 3.141593 + 1, places=5) + + def test_with_operations_and_single_numbers(self): + """ + Test using the unicode π symbol in a complex expression. + """ + result = mathparse.parse("(1 + 3 + 2.0 + 6) * 1") + self.assertAlmostEqual(result, 0.00012, places=5)