7
7
from _pytest .outcomes import fail
8
8
import _pytest ._code
9
9
10
+
11
+ def _cmp_raises_type_error (self , other ):
12
+ """__cmp__ implementation which raises TypeError. Used
13
+ by Approx base classes to implement only == and != and raise a
14
+ TypeError for other comparisons.
15
+
16
+ Needed in Python 2 only, Python 3 all it takes is not implementing the
17
+ other operators at all.
18
+ """
19
+ __tracebackhide__ = True
20
+ raise TypeError ('Comparison operators other than == and != not supported by approx objects' )
21
+
22
+
10
23
# builtin pytest.approx helper
11
24
12
25
@@ -35,6 +48,9 @@ def __eq__(self, actual):
35
48
def __ne__ (self , actual ):
36
49
return not (actual == self )
37
50
51
+ if sys .version_info [0 ] == 2 :
52
+ __cmp__ = _cmp_raises_type_error
53
+
38
54
def _approx_scalar (self , x ):
39
55
return ApproxScalar (x , rel = self .rel , abs = self .abs , nan_ok = self .nan_ok )
40
56
@@ -60,6 +76,9 @@ def __repr__(self):
60
76
return "approx({0!r})" .format (list (
61
77
self ._approx_scalar (x ) for x in self .expected ))
62
78
79
+ if sys .version_info [0 ] == 2 :
80
+ __cmp__ = _cmp_raises_type_error
81
+
63
82
def __eq__ (self , actual ):
64
83
import numpy as np
65
84
@@ -358,6 +377,24 @@ def approx(expected, rel=None, abs=None, nan_ok=False):
358
377
is asymmetric and you can think of ``b`` as the reference value. In the
359
378
special case that you explicitly specify an absolute tolerance but not a
360
379
relative tolerance, only the absolute tolerance is considered.
380
+
381
+ .. warning::
382
+
383
+ .. versionchanged:: 3.2
384
+
385
+ In order to avoid inconsistent behavior, ``TypeError`` is
386
+ raised for ``>``, ``>=``, ``<`` and ``<=`` comparisons.
387
+ The example below illustrates the problem::
388
+
389
+ assert approx(0.1) > 0.1 + 1e-10 # calls approx(0.1).__gt__(0.1 + 1e-10)
390
+ assert 0.1 + 1e-10 > approx(0.1) # calls approx(0.1).__lt__(0.1 + 1e-10)
391
+
392
+ In the second example one expects ``approx(0.1).__le__(0.1 + 1e-10)``
393
+ to be called. But instead, ``approx(0.1).__lt__(0.1 + 1e-10)`` is used to
394
+ comparison. This is because the call hierarchy of rich comparisons
395
+ follows a fixed behavior. `More information...`__
396
+
397
+ __ https://docs.python.org/3/reference/datamodel.html#object.__ge__
361
398
"""
362
399
363
400
from collections import Mapping , Sequence
0 commit comments