From 6e14585ca20d27db81f122d2c3a76135e4192fc4 Mon Sep 17 00:00:00 2001 From: mike Date: Tue, 20 Feb 2018 22:51:22 +0100 Subject: [PATCH 1/2] Fix approx default tolerances for Decimal --- _pytest/python_api.py | 16 ++++++++++++++-- changelog/3247.bugfix.rst | 1 + testing/python/approx.py | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 changelog/3247.bugfix.rst diff --git a/_pytest/python_api.py b/_pytest/python_api.py index 89ef9e0a9..541371449 100644 --- a/_pytest/python_api.py +++ b/_pytest/python_api.py @@ -153,6 +153,8 @@ class ApproxScalar(ApproxBase): """ Perform approximate comparisons for single numbers only. """ + DEFAULT_ABSOLUTE_TOLERANCE = 1e-12 + DEFAULT_RELATIVE_TOLERANCE = 1e-6 def __repr__(self): """ @@ -223,7 +225,7 @@ class ApproxScalar(ApproxBase): # Figure out what the absolute tolerance should be. ``self.abs`` is # either None or a value specified by the user. - absolute_tolerance = set_default(self.abs, 1e-12) + absolute_tolerance = set_default(self.abs, self.DEFAULT_ABSOLUTE_TOLERANCE) if absolute_tolerance < 0: raise ValueError("absolute tolerance can't be negative: {}".format(absolute_tolerance)) @@ -241,7 +243,7 @@ class ApproxScalar(ApproxBase): # we've made sure the user didn't ask for an absolute tolerance only, # because we don't want to raise errors about the relative tolerance if # we aren't even going to use it. - relative_tolerance = set_default(self.rel, 1e-6) * abs(self.expected) + relative_tolerance = set_default(self.rel, self.DEFAULT_RELATIVE_TOLERANCE) * abs(self.expected) if relative_tolerance < 0: raise ValueError("relative tolerance can't be negative: {}".format(absolute_tolerance)) @@ -252,6 +254,13 @@ class ApproxScalar(ApproxBase): return max(relative_tolerance, absolute_tolerance) +class ApproxDecimal(ApproxScalar): + from decimal import Decimal + + DEFAULT_ABSOLUTE_TOLERANCE = Decimal('1e-12') + DEFAULT_RELATIVE_TOLERANCE = Decimal('1e-6') + + def approx(expected, rel=None, abs=None, nan_ok=False): """ Assert that two numbers (or two sets of numbers) are equal to each other @@ -401,6 +410,7 @@ def approx(expected, rel=None, abs=None, nan_ok=False): from collections import Mapping, Sequence from _pytest.compat import STRING_TYPES as String + from decimal import Decimal # Delegate the comparison to a class that knows how to deal with the type # of the expected value (e.g. int, float, list, dict, numpy.array, etc). @@ -422,6 +432,8 @@ def approx(expected, rel=None, abs=None, nan_ok=False): cls = ApproxMapping elif isinstance(expected, Sequence) and not isinstance(expected, String): cls = ApproxSequence + elif isinstance(expected, Decimal): + cls = ApproxDecimal else: cls = ApproxScalar diff --git a/changelog/3247.bugfix.rst b/changelog/3247.bugfix.rst new file mode 100644 index 000000000..e8091f4e5 --- /dev/null +++ b/changelog/3247.bugfix.rst @@ -0,0 +1 @@ +Fix issue with approx on Decimal value. \ No newline at end of file diff --git a/testing/python/approx.py b/testing/python/approx.py index 300e1ce86..341e5fcff 100644 --- a/testing/python/approx.py +++ b/testing/python/approx.py @@ -249,6 +249,7 @@ class TestApprox(object): (Decimal('-1.000001'), Decimal('-1.0')), ] for a, x in within_1e6: + assert a == approx(x) assert a == approx(x, rel=Decimal('5e-6'), abs=0) assert a != approx(x, rel=Decimal('5e-7'), abs=0) assert approx(x, rel=Decimal('5e-6'), abs=0) == a From 147b43f83216c612ab0122c8a3961895c4222abe Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 21 Feb 2018 20:31:33 -0300 Subject: [PATCH 2/2] Small changelog tweak --- changelog/3247.bugfix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/3247.bugfix.rst b/changelog/3247.bugfix.rst index e8091f4e5..9483ceeea 100644 --- a/changelog/3247.bugfix.rst +++ b/changelog/3247.bugfix.rst @@ -1 +1 @@ -Fix issue with approx on Decimal value. \ No newline at end of file +Fix ``TypeError`` issue when using ``approx`` with a ``Decimal`` value.