Suppose that I have a Python Data Class that I'd like to test with pytest:
@dataclass
class ExamplePoint:
x: float
y: float
With simple mathematical operations all is well:
p1 = ExamplePoint(1,2)
p2 = ExamplePoint(0.5 + 0.5, 2)
p1 == p2 # True
But floating point arithmetic quickly causes problems:
p3 = ExamplePoint(1, math.sqrt(2) * math.sqrt(2))
p1 == p3 # False
Using pytest you can get round this with the approx() function:
2.0 == approx(math.sqrt(2) * math.sqrt(2)) # True
You can't simplemindedly extend this to the Data Class:
p1 = approx(p3) # Results error: TypeError: cannot make approximate comparisons to non-numeric values: ExamplePoint(x=1, y=2.0000000000000004)
My current solution to fix this is to write an approx() function on the Data Class as:
from dataclasses import astuple, dataclass
import pytest
@dataclass
class ExamplePoint:
x: float
y: float
def approx(self, other):
return astuple(self) == pytest.approx(astuple(other))
p1 = ExamplePoint(1,2)
p3 = ExamplePoint(1, math.sqrt(2) * math.sqrt(2))
p1.approx(p3) # True
I don't like this solution as ExamplePoint now depends on pytest. That seems wrong.
How can I extend pytest so that approx() works with my Data Class without having the Data Class know about pytest?