code: def approx(expected, rel=None, abs=None, nan_ok=False):
      """
      Assert that two numbers (or two sets of numbers) are equal to each other
      within some tolerance.
  
      Due to the `intricacies of floating-point arithmetic`__, numbers that we
      would intuitively expect to be equal are not always so::
  
          >>> 0.1 + 0.2 == 0.3
          False
  
      __ https://docs.python.org/3/tutorial/floatingpoint.html
  
      This problem is commonly encountered when writing tests, e.g. when making
      sure that floating-point values are what you expect them to be.  One way to
      deal with this problem is to assert that two floating-point numbers are
      equal to within some appropriate tolerance::
  
          >>> abs((0.1 + 0.2) - 0.3) < 1e-6
          True
  
      However, comparisons like this are tedious to write and difficult to
      understand.  Furthermore, absolute comparisons like the one above are
      usually discouraged because there's no tolerance that works well for all
      situations.  ``1e-6`` is good for numbers around ``1``, but too small for
      very big numbers and too big for very small ones.  It's better to express
      the tolerance as a fraction of the expected value, but relative comparisons
      like that are even more difficult to write correctly and concisely.
  
      The ``approx`` class performs floating-point comparisons using a syntax
      that's as intuitive as possible::
  
          >>> from pytest import approx
          >>> 0.1 + 0.2 == approx(0.3)
          True
  
      The same syntax also works for sequences of numbers::
  
          >>> (0.1 + 0.2, 0.2 + 0.4) == approx((0.3, 0.6))
          True
  
      Dictionary *values*::
  
          >>> {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6})
          True
  
      ``numpy`` arrays::
  
          >>> import numpy as np                                                          # doctest: +SKIP
          >>> np.array([0.1, 0.2]) + np.array([0.2, 0.4]) == approx(np.array([0.3, 0.6])) # doctest: +SKIP
          True
  
      And for a ``numpy`` array against a scalar::
  
          >>> import numpy as np                                         # doctest: +SKIP
          >>> np.array([0.1, 0.2]) + np.array([0.2, 0.1]) == approx(0.3) # doctest: +SKIP
          True
  
      By default, ``approx`` considers numbers within a relative tolerance of
      ``1e-6`` (i.e. one part in a million) of its expected value to be equal.
      This treatment would lead to surprising results if the expected value was
      ``0.0``, because nothing but ``0.0`` itself is relatively close to ``0.0``.
      To handle this case less surprisingly, ``approx`` also considers numbers
      within an absolute tolerance of ``1e-12`` of its expected value to be
      equal.  Infinity and NaN are special cases.  Infinity is only considered
      equal to itself, regardless of the relative tolerance.  NaN is not
      considered equal to anything by default, but you can make it be equal to
      itself by setting the ``nan_ok`` argument to True.  (This is meant to
      facilitate comparing arrays that use NaN to mean "no data".)
  
      Both the relative and absolute tolerances can be changed by passing
      arguments to the ``approx`` constructor::
  
          >>> 1.0001 == approx(1)
          False
          >>> 1.0001 == approx(1, rel=1e-3)
          True
          >>> 1.0001 == approx(1, abs=1e-3)
          True
  
      If you specify ``abs`` but not ``rel``, the comparison will not consider
      the relative tolerance at all.  In other words, two numbers that are within
      the default relative tolerance of ``1e-6`` will still be considered unequal
      if they exceed the specified absolute tolerance.  If you specify both
      ``abs`` and ``rel``, the numbers will be considered equal if either
      tolerance is met::
  
          >>> 1 + 1e-8 == approx(1)
          True
          >>> 1 + 1e-8 == approx(1, abs=1e-12)
          False
          >>> 1 + 1e-8 == approx(1, rel=1e-6, abs=1e-12)
          True
  
      If you're thinking about using ``approx``, then you might want to know how
      it compares to other good ways of comparing floating-point numbers.  All of
      these algorithms are based on relative and absolute tolerances and should
      agree for the most part, but they do have meaningful differences:
  
      - ``math.isclose(a, b, rel_tol=1e-9, abs_tol=0.0)``:  True if the relative
        tolerance is met w.r.t. either ``a`` or ``b`` or if the absolute
        tolerance is met.  Because the relative tolerance is calculated w.r.t.
        both ``a`` and ``b``, this test is symmetric (i.e.  neither ``a`` nor
        ``b`` is a "reference value").  You have to specify an absolute tolerance
        if you want to compare to ``0.0`` because there is no tolerance by
        default.  Only available in python>=3.5.  `More information...`__
  
        __ https://docs.python.org/3/library/math.html#math.isclose
  
      - ``numpy.isclose(a, b, rtol=1e-5, atol=1e-8)``: True if the difference
        between ``a`` and ``b`` is less that the sum of the relative tolerance
        w.r.t. ``b`` and the absolute tolerance.  Because the relative tolerance
        is only calculated w.r.t. ``b``, this test is asymmetric and you can
        think of ``b`` as the reference value.  Support for comparing sequences
        is provided by ``numpy.allclose``.  `More information...`__
  
        __ http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.isclose.html
  
      - ``unittest.TestCase.assertAlmostEqual(a, b)``: True if ``a`` and ``b``
        are within an absolute tolerance of ``1e-7``.  No relative tolerance is
        considered and the absolute tolerance cannot be changed, so this function
        is not appropriate for very large or very small numbers.  Also, it's only
        available in subclasses of ``unittest.TestCase`` and it's ugly because it
        doesn't follow PEP8.  `More information...`__
  
        __ https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertAlmostEqual
  
      - ``a == pytest.approx(b, rel=1e-6, abs=1e-12)``: True if the relative
        tolerance is met w.r.t. ``b`` or if the absolute tolerance is met.
        Because the relative tolerance is only calculated w.r.t. ``b``, this test
        is asymmetric and you can think of ``b`` as the reference value.  In the
        special case that you explicitly specify an absolute tolerance but not a
        relative tolerance, only the absolute tolerance is considered.
  
      .. warning::
  
         .. versionchanged:: 3.2
  
         In order to avoid inconsistent behavior, ``TypeError`` is
         raised for ``>``, ``>=``, ``<`` and ``<=`` comparisons.
         The example below illustrates the problem::
  
             assert approx(0.1) > 0.1 + 1e-10  # calls approx(0.1).__gt__(0.1 + 1e-10)
             assert 0.1 + 1e-10 > approx(0.1)  # calls approx(0.1).__lt__(0.1 + 1e-10)
  
         In the second example one expects ``approx(0.1).__le__(0.1 + 1e-10)``
         to be called. But instead, ``approx(0.1).__lt__(0.1 + 1e-10)`` is used to
         comparison. This is because the call hierarchy of rich comparisons
         follows a fixed behavior. `More information...`__
  
         __ https://docs.python.org/3/reference/datamodel.html#object.__ge__
      """
  
      # 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).
      #
      # The primary responsibility of these classes is to implement ``__eq__()``
      # and ``__repr__()``.  The former is used to actually check if some
      # "actual" value is equivalent to the given expected value within the
      # allowed tolerance.  The latter is used to show the user the expected
      # value and tolerance, in the case that a test failed.
      #
      # The actual logic for making approximate comparisons can be found in
      # ApproxScalar, which is used to compare individual numbers.  All of the
      # other Approx classes eventually delegate to this class.  The ApproxBase
      # class provides some convenient methods and overloads, but isn't really
      # essential.
  
      __tracebackhide__ = True
  
      if isinstance(expected, Decimal):
          cls = ApproxDecimal
      elif isinstance(expected, Number):
          cls = ApproxScalar
      elif isinstance(expected, Mapping):
          cls = ApproxMapping
      elif _is_numpy_array(expected):
          cls = ApproxNumpy
      elif (
          isinstance(expected, Iterable)
          and isinstance(expected, Sized)
          and not isinstance(expected, STRING_TYPES)
      ):
          cls = ApproxSequencelike
      else:
          raise _non_numeric_type_error(expected, at=None)
  
      return cls(expected, rel, abs, nan_ok)
  
imports: from __future__ import absolute_import
  import math
  import pprint
  import sys
  import warnings
  from decimal import Decimal
  from numbers import Number
  from more_itertools.more import always_iterable
  from six.moves import filterfalse
  from six.moves import zip
  import _pytest._code
  from _pytest import deprecated
  from _pytest.compat import isclass
  from _pytest.compat import Iterable
  from _pytest.compat import Mapping
  from _pytest.compat import Sized
  from _pytest.compat import STRING_TYPES
  from _pytest.outcomes import fail
label_desc: Use image node_id 4 for calling a global function with example usage: approx(expected, rel, abs, nan_ok) and returns: cls