{"id":"d32b233972498213","repo":"pytest-dev/pytest","slug":"absolute-tolerance-for-datetime-timedelta-must-be","errorCode":null,"errorMessage":"absolute tolerance for datetime/timedelta must be a timedelta, got {type(abs).__name__}","messagePattern":"absolute tolerance for datetime/timedelta must be a timedelta, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/approx.py","lineNumber":664,"sourceCode":"        if isinstance(expected, datetime) and rel is not None:\n            raise TypeError(\n                \"pytest.approx() does not support relative tolerance for \"\n                \"datetime comparisons. Use abs=timedelta(...) instead.\"\n            )\n        if nan_ok:\n            raise TypeError(\n                \"pytest.approx() does not support nan_ok for \"\n                \"datetime/timedelta comparisons.\"\n            )\n        if abs is None and rel is None:\n            raise TypeError(\n                \"pytest.approx() requires an explicit tolerance for \"\n                \"datetime/timedelta comparisons: \"\n                \"e.g. approx(expected, abs=timedelta(seconds=1)) \"\n                \"or approx(expected, rel=0.01)\"\n            )\n        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","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/approx.py#L646-L682","documentation":"ApproxTimedelta.__init__ requires the absolute tolerance for datetime/timedelta comparisons to itself be a timedelta, since the units must match the values being compared. Passing a raw number is ambiguous (seconds? microseconds?) and is rejected.","triggerScenarios":"Call pytest.approx(dt, abs=1.0) or approx(dt, abs=2) — any non-timedelta value for abs when expected is a datetime/timedelta.","commonSituations":"Migrating a numeric approx(x, abs=0.001) call to datetime without wrapping the tolerance in timedelta(...); copy-pasting tolerance kwargs.","solutions":["Wrap the tolerance in timedelta with explicit units: abs=timedelta(seconds=1).","If you have a numeric tolerance in seconds, write abs=timedelta(seconds=n).","Double-check the units (seconds vs milliseconds vs microseconds) to avoid off-by-1000 bugs."],"exampleFix":"// before\nassert got == approx(dt, abs=1.0)\n// after\nfrom datetime import timedelta\nassert got == approx(dt, abs=timedelta(seconds=1))","handlingStrategy":"type-guard","validationCode":"from datetime import timedelta\n\ndef approx_dt(value, abs_tol):\n    if not isinstance(abs_tol, timedelta):\n        raise TypeError(f'abs must be a timedelta, got {type(abs_tol).__name__}')\n    return pytest.approx(value, abs=abs_tol)","typeGuard":"from datetime import timedelta\n\ndef is_timedelta(v) -> bool:\n    return isinstance(v, timedelta)","tryCatchPattern":null,"preventionTips":["Always construct datetime tolerances via timedelta(seconds=...) so the units are explicit.","Static-type the tolerance parameter as timedelta in your helpers."],"tags":["pytest","approx","datetime","type-mismatch"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}