{"id":"7daa572e18071a41","repo":"pytest-dev/pytest","slug":"relative-tolerance-for-a-scalar-value-must-be-an-i","errorCode":null,"errorMessage":"relative tolerance for a scalar value must be an int, float or Decimal, got {type(rel).__name__}","messagePattern":"relative tolerance for a scalar value must be an int, float or Decimal, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/approx.py","lineNumber":450,"sourceCode":"\n    # Using Real should be better than this Union, but not possible yet:\n    # https://github.com/python/typeshed/pull/3108\n    DEFAULT_ABSOLUTE_TOLERANCE: float | Decimal = 1e-12\n    DEFAULT_RELATIVE_TOLERANCE: float | Decimal = 1e-6\n    rel: float | Decimal | None\n    abs: float | Decimal | None\n\n    def __init__(\n        self,\n        expected: ExpectedT,\n        rel: float | Decimal | timedelta | None,\n        abs: float | Decimal | timedelta | None,\n        nan_ok: bool,\n    ) -> None:\n        __tracebackhide__ = True\n        if rel is not None:\n            if not isinstance(rel, (int, float, Decimal)):\n                raise TypeError(\n                    f\"relative tolerance for a scalar value must be an int, float or Decimal, \"\n                    f\"got {type(rel).__name__}\"\n                )\n            if not isinstance(expected, SupportsAbs):\n                raise TypeError(\n                    f\"expected value must support abs(...) when relative tolerance is used, \"\n                    f\"got {type(expected).__name__}\"\n                )\n        if abs is not None and not isinstance(abs, (int, float, Decimal)):\n            raise TypeError(\n                f\"absolute tolerance for a scalar value must be an int, float or Decimal, \"\n                f\"got {type(abs).__name__}\"\n            )\n        super().__init__(expected, rel=rel, abs=abs, nan_ok=nan_ok)\n\n    def __repr__(self) -> str:\n        \"\"\"Return a string communicating both the expected value and the\n        tolerance for the comparison being made.","sourceCodeStart":432,"sourceCodeEnd":468,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/approx.py#L432-L468","documentation":"When constructing an ApproxScalar, the rel (relative tolerance) parameter must be None or an int, float, or Decimal. If rel is any other type (string, complex, numpy type, None mishandled), pytest raises TypeError in __init__. This validates the tolerance type before any comparison occurs.","triggerScenarios":"Calling approx(1.0, rel='0.01') or approx(1.0, rel=np.float64(0.01)) with a non-standard numeric type. The isinstance(rel, (int, float, Decimal)) check fails.","commonSituations":"Passing a tolerance parsed from a config string without converting to float, or passing a numpy scalar type that isn't a Python float subclass.","solutions":["Convert rel to a Python float: approx(1.0, rel=float(value)).","Pass rel as a plain numeric literal: approx(1.0, rel=0.01).","Use Decimal explicitly if needed: approx(Decimal('1.0'), rel=Decimal('0.01'))."],"exampleFix":"# before\napprox(1.0, rel='0.01')  # string\n\n# after\napprox(1.0, rel=0.01)  # float","handlingStrategy":"type-guard","validationCode":"from decimal import Decimal\n\ndef validate_rel_tolerance(rel):\n    if rel is not None and not isinstance(rel, (int, float, Decimal)):\n        raise TypeError(f'rel must be int, float, or Decimal, got {type(rel).__name__}')\n    return rel","typeGuard":"from decimal import Decimal\n\ndef is_valid_rel_tolerance(value) -> bool:\n    return value is None or isinstance(value, (int, float, Decimal))","tryCatchPattern":null,"preventionTips":["Always pass rel as a plain float literal or variable.","Convert config/string-sourced tolerance values with float() before passing to approx().","Use Decimal type consistently if working with Decimal expected values."],"tags":["approx","type-error","tolerance","validation"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}