{"id":"40e1a7ee4082622f","repo":"pytest-dev/pytest","slug":"relative-tolerance-can-t-be-infinite","errorCode":null,"errorMessage":"relative tolerance can't be infinite.","messagePattern":"relative tolerance can't be infinite\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/approx.py","lineNumber":681,"sourceCode":"        if abs is not None and not isinstance(abs, timedelta):\n            raise TypeError(\n                f\"absolute tolerance for datetime/timedelta must be a \"\n                f\"timedelta, got {type(abs).__name__}\"\n            )\n        if abs is not None and abs < timedelta(0):\n            raise ValueError(f\"absolute tolerance can't be negative: {abs}\")\n        if rel is not None:\n            if not isinstance(rel, (int, float)):\n                raise TypeError(\n                    f\"relative tolerance for timedelta must be a \"\n                    f\"number, got {type(rel).__name__}\"\n                )\n            if rel < 0:\n                raise ValueError(f\"relative tolerance can't be negative: {rel}\")\n            if math.isnan(rel):\n                raise ValueError(\"relative tolerance can't be NaN.\")\n            if math.isinf(rel):\n                raise ValueError(\"relative tolerance can't be infinite.\")\n        # Compute the effective tolerance. abs_tolerance is a timedelta, rel * expected\n        # gives a timedelta (timedelta * float works in Python).\n        abs_tolerance = abs\n        if rel is None:\n            rel_tolerance = None\n        else:\n            # Checked above.\n            assert not isinstance(expected, datetime)\n            rel_tolerance = rel * builtins.abs(expected)\n        if abs_tolerance is not None and rel_tolerance is not None:\n            tolerance: timedelta | None = max(abs_tolerance, rel_tolerance)\n        else:\n            tolerance = abs_tolerance if abs_tolerance is not None else rel_tolerance\n        super().__init__(expected, rel=rel, abs=tolerance, nan_ok=False)\n\n    def __repr__(self) -> str:\n        return f\"{self.expected} ± {self.abs}\"\n","sourceCodeStart":663,"sourceCodeEnd":699,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/approx.py#L663-L699","documentation":"ApproxTimedelta.__init__ rejects an infinite relative tolerance for timedelta comparisons. An infinite tolerance would make every value match, defeating the purpose of the assertion.","triggerScenarios":"Call pytest.approx(some_timedelta, rel=float('inf')) or rel=math.inf.","commonSituations":"rel computed from a division by zero; tolerance loaded from a config that allows inf; copy-paste error.","solutions":["Pass a finite rel: approx(td, rel=0.01).","Guard the producing computation against division by zero.","Validate the config value at load time."],"exampleFix":"// before\nassert got == approx(td, rel=float('inf'))\n// after\nassert got == approx(td, rel=0.01)","handlingStrategy":"validation","validationCode":"import math\n\ndef approx_td_rel(value, rel):\n    if isinstance(rel, float) and math.isinf(rel):\n        raise ValueError('rel is infinite')\n    return pytest.approx(value, rel=rel)","typeGuard":"import math\n\ndef is_finite_number(v) -> bool:\n    return isinstance(v, (int, float)) and not math.isnan(v) and not math.isinf(v)","tryCatchPattern":null,"preventionTips":["Guard against division-by-zero when computing tolerances.","Validate config-provided tolerances at load time."],"tags":["pytest","approx","timedelta","validation"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}