Skip to content

Commit f74629e

Browse files
coder-aditiCoderAAAnicoddemus
authored andcommitted
Fix approx usage with decimal.FloatOperation trap set (#13543)
Fixes #13530 --------- Co-authored-by: AD <[email protected]> Co-authored-by: Bruno Oliveira <[email protected]> (cherry picked from commit 111685c)
1 parent 242522a commit f74629e

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

changelog/13530.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a crash when using :func:`pytest.approx` and :class:`decimal.Decimal` instances with the :class:`decimal.FloatOperation` trap set.

src/_pytest/python_api.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,25 @@ class ApproxDecimal(ApproxScalar):
531531
DEFAULT_ABSOLUTE_TOLERANCE = Decimal("1e-12")
532532
DEFAULT_RELATIVE_TOLERANCE = Decimal("1e-6")
533533

534+
def __repr__(self) -> str:
535+
if isinstance(self.rel, float):
536+
rel = Decimal.from_float(self.rel)
537+
else:
538+
rel = self.rel
539+
540+
if isinstance(self.abs, float):
541+
abs_ = Decimal.from_float(self.abs)
542+
else:
543+
abs_ = self.abs
544+
545+
tol_str = "???"
546+
if rel is not None and Decimal("1e-3") <= rel <= Decimal("1e3"):
547+
tol_str = f"{rel:.1e}"
548+
elif abs_ is not None:
549+
tol_str = f"{abs_:.1e}"
550+
551+
return f"{self.expected} ± {tol_str}"
552+
534553

535554
def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:
536555
"""Assert that two numbers (or two ordered sequences of numbers) are equal to each other

testing/python/approx.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from __future__ import annotations
33

44
from contextlib import contextmanager
5+
import decimal
56
from decimal import Decimal
67
from fractions import Fraction
78
from math import sqrt
@@ -1015,6 +1016,11 @@ def __len__(self):
10151016
expected_repr = "approx([1 ± 1.0e-06, 2 ± 2.0e-06, 3 ± 3.0e-06, 4 ± 4.0e-06])"
10161017
assert repr(approx(expected)) == expected_repr
10171018

1019+
def test_decimal_approx_repr(self, monkeypatch) -> None:
1020+
monkeypatch.setitem(decimal.getcontext().traps, decimal.FloatOperation, True)
1021+
approx_obj = pytest.approx(decimal.Decimal("2.60"))
1022+
assert decimal.Decimal("2.600001") == approx_obj
1023+
10181024
def test_allow_ordered_sequences_only(self) -> None:
10191025
"""pytest.approx() should raise an error on unordered sequences (#9692)."""
10201026
with pytest.raises(TypeError, match="only supports ordered sequences"):

0 commit comments

Comments
 (0)