{"record":{"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/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/approx.py#L646-L682","documentation":"Raised by ApproxTimedelta.__init__ when abs is provided but is not a timedelta instance. datetime/timedelta comparisons require the absolute tolerance to be a timedelta so that arithmetic stays dimensionally consistent. Passing a number (int/float) or string is rejected with TypeError showing the actual type received.","triggerScenarios":"approx(expected_timedelta, abs=0.5); approx(dt, abs=1); approx(td, abs='1s').","commonSituations":"Reusing scalar approx() muscle memory (where abs is a float) for time values; mixing tolerance units across assertion types.","solutions":["Wrap the tolerance in timedelta: abs=timedelta(seconds=0.5).","Use rel with a float if you want a proportional tolerance (timedelta only).","Double-check the expected type is datetime/timedelta before using abs=timedelta(...)."],"exampleFix":"// before\napprox(timedelta(seconds=10), abs=0.5)\n// after\napprox(timedelta(seconds=10), abs=timedelta(milliseconds=500))","handlingStrategy":"type-guard","validationCode":"from datetime import timedelta\ndef approx_td(expected, *, abs=None, **kw):\n    if abs is not None and not isinstance(abs, timedelta):\n        raise TypeError('abs must be timedelta for time values')\n    return approx(expected, abs=abs, **kw)","typeGuard":"from datetime import timedelta\ndef is_timedelta_or_none(v) -> bool:\n    return v is None or isinstance(v, timedelta)","tryCatchPattern":null,"preventionTips":["Remember abs=timedelta(...) for datetime/timedelta.","Use rel=float only for timedelta proportional tolerance."],"tags":["approx","timedelta","datetime","type-mismatch"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}