Assert that two numbers (or two ordered sequences of numbers) are equal to each other within some tolerance. Due to the :doc:`python:tutorial/floatingpoint`, numbers that we would intuitively expect to be equal are not always so:: >>> 0.1 + 0.2 == 0.3 False This pr
(
expected: Any,
rel: float | Decimal | timedelta | None = None,
abs: float | Decimal | timedelta | None = None,
nan_ok: bool = False,
)
| 644 | |
| 645 | |
| 646 | def approx( |
| 647 | expected: Any, |
| 648 | rel: float | Decimal | timedelta | None = None, |
| 649 | abs: float | Decimal | timedelta | None = None, |
| 650 | nan_ok: bool = False, |
| 651 | ) -> ApproxBase: |
| 652 | """Assert that two numbers (or two ordered sequences of numbers) are equal to each other |
| 653 | within some tolerance. |
| 654 | |
| 655 | Due to the :doc:`python:tutorial/floatingpoint`, numbers that we |
| 656 | would intuitively expect to be equal are not always so:: |
| 657 | |
| 658 | >>> 0.1 + 0.2 == 0.3 |
| 659 | False |
| 660 | |
| 661 | This problem is commonly encountered when writing tests, e.g. when making |
| 662 | sure that floating-point values are what you expect them to be. One way to |
| 663 | deal with this problem is to assert that two floating-point numbers are |
| 664 | equal to within some appropriate tolerance:: |
| 665 | |
| 666 | >>> abs((0.1 + 0.2) - 0.3) < 1e-6 |
| 667 | True |
| 668 | |
| 669 | However, comparisons like this are tedious to write and difficult to |
| 670 | understand. Furthermore, absolute comparisons like the one above are |
| 671 | usually discouraged because there's no tolerance that works well for all |
| 672 | situations. ``1e-6`` is good for numbers around ``1``, but too small for |
| 673 | very big numbers and too big for very small ones. It's better to express |
| 674 | the tolerance as a fraction of the expected value, but relative comparisons |
| 675 | like that are even more difficult to write correctly and concisely. |
| 676 | |
| 677 | The ``approx`` class performs floating-point comparisons using a syntax |
| 678 | that's as intuitive as possible:: |
| 679 | |
| 680 | >>> from pytest import approx |
| 681 | >>> 0.1 + 0.2 == approx(0.3) |
| 682 | True |
| 683 | |
| 684 | The same syntax also works for ordered sequences of numbers:: |
| 685 | |
| 686 | >>> (0.1 + 0.2, 0.2 + 0.4) == approx((0.3, 0.6)) |
| 687 | True |
| 688 | |
| 689 | ``numpy`` arrays:: |
| 690 | |
| 691 | >>> import numpy as np # doctest: +SKIP |
| 692 | >>> np.array([0.1, 0.2]) + np.array([0.2, 0.4]) == approx(np.array([0.3, 0.6])) # doctest: +SKIP |
| 693 | True |
| 694 | |
| 695 | And for a ``numpy`` array against a scalar:: |
| 696 | |
| 697 | >>> import numpy as np # doctest: +SKIP |
| 698 | >>> np.array([0.1, 0.2]) + np.array([0.2, 0.1]) == approx(0.3) # doctest: +SKIP |
| 699 | True |
| 700 | |
| 701 | Only ordered sequences are supported, because ``approx`` needs |
| 702 | to infer the relative position of the sequences without ambiguity. This means |
| 703 | ``sets`` and other unordered sequences are not supported. |
searching dependent graphs…