{"record":{"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/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/approx.py#L663-L699","documentation":"Raised by ApproxTimedelta.__init__ when rel is numeric, non-negative, not NaN, but infinite (math.isinf). An infinite relative tolerance would make approx trivially accept everything, defeating the assertion's purpose. pytest treats this as a user error.","triggerScenarios":"approx(td, rel=float('inf')); rel computed as x/0.0 producing inf.","commonSituations":"Division-by-zero yielding inf instead of raising; config-driven tolerances parsed from malformed input.","solutions":["Use a finite rel value: rel=0.01.","Guard computations with math.isinf before passing.","Clamp computed tolerances to a reasonable maximum."],"exampleFix":"// before\napprox(td, rel=x / 0.0)  # inf\n// after\napprox(td, rel=0.01)","handlingStrategy":"validation","validationCode":"import math\ndef reject_inf_rel(rel):\n    if rel is not None and math.isinf(rel):\n        raise ValueError('rel must be finite')\n    return rel","typeGuard":"import math\ndef is_finite_rel(v) -> bool:\n    return v is None or (isinstance(v, (int, float)) and math.isfinite(v))","tryCatchPattern":null,"preventionTips":["Guard against division by zero when computing rel.","Clamp computed tolerances to a finite maximum."],"tags":["approx","timedelta","validation","infinity"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}