Merge pull request #3248 from durocher/master
Fix approx default tolerances for Decimal
This commit is contained in:
commit
264e455410
|
@ -153,6 +153,8 @@ class ApproxScalar(ApproxBase):
|
||||||
"""
|
"""
|
||||||
Perform approximate comparisons for single numbers only.
|
Perform approximate comparisons for single numbers only.
|
||||||
"""
|
"""
|
||||||
|
DEFAULT_ABSOLUTE_TOLERANCE = 1e-12
|
||||||
|
DEFAULT_RELATIVE_TOLERANCE = 1e-6
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""
|
"""
|
||||||
|
@ -223,7 +225,7 @@ class ApproxScalar(ApproxBase):
|
||||||
|
|
||||||
# Figure out what the absolute tolerance should be. ``self.abs`` is
|
# Figure out what the absolute tolerance should be. ``self.abs`` is
|
||||||
# either None or a value specified by the user.
|
# 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:
|
if absolute_tolerance < 0:
|
||||||
raise ValueError("absolute tolerance can't be negative: {}".format(absolute_tolerance))
|
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,
|
# 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
|
# because we don't want to raise errors about the relative tolerance if
|
||||||
# we aren't even going to use it.
|
# 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:
|
if relative_tolerance < 0:
|
||||||
raise ValueError("relative tolerance can't be negative: {}".format(absolute_tolerance))
|
raise ValueError("relative tolerance can't be negative: {}".format(absolute_tolerance))
|
||||||
|
@ -252,6 +254,13 @@ class ApproxScalar(ApproxBase):
|
||||||
return max(relative_tolerance, absolute_tolerance)
|
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):
|
def approx(expected, rel=None, abs=None, nan_ok=False):
|
||||||
"""
|
"""
|
||||||
Assert that two numbers (or two sets of numbers) are equal to each other
|
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 collections import Mapping, Sequence
|
||||||
from _pytest.compat import STRING_TYPES as String
|
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
|
# 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).
|
# 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
|
cls = ApproxMapping
|
||||||
elif isinstance(expected, Sequence) and not isinstance(expected, String):
|
elif isinstance(expected, Sequence) and not isinstance(expected, String):
|
||||||
cls = ApproxSequence
|
cls = ApproxSequence
|
||||||
|
elif isinstance(expected, Decimal):
|
||||||
|
cls = ApproxDecimal
|
||||||
else:
|
else:
|
||||||
cls = ApproxScalar
|
cls = ApproxScalar
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix ``TypeError`` issue when using ``approx`` with a ``Decimal`` value.
|
|
@ -249,6 +249,7 @@ class TestApprox(object):
|
||||||
(Decimal('-1.000001'), Decimal('-1.0')),
|
(Decimal('-1.000001'), Decimal('-1.0')),
|
||||||
]
|
]
|
||||||
for a, x in within_1e6:
|
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-6'), abs=0)
|
||||||
assert a != approx(x, rel=Decimal('5e-7'), abs=0)
|
assert a != approx(x, rel=Decimal('5e-7'), abs=0)
|
||||||
assert approx(x, rel=Decimal('5e-6'), abs=0) == a
|
assert approx(x, rel=Decimal('5e-6'), abs=0) == a
|
||||||
|
|
Loading…
Reference in New Issue