{"id":"2d9147faea9bf3b3","repo":"pytest-dev/pytest","slug":"name","errorCode":null,"errorMessage":"{name}","messagePattern":"\\{name\\}","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/monkeypatch.py","lineNumber":279,"sourceCode":"\n        Raises AttributeError it the attribute does not exist, unless\n        ``raising`` is set to False.\n        \"\"\"\n        __tracebackhide__ = True\n        import inspect\n\n        if name is NOTSET:\n            if not isinstance(target, str):\n                raise TypeError(\n                    \"use delattr(target, name) or \"\n                    \"delattr(target) with target being a dotted \"\n                    \"import string\"\n                )\n            name, target = derive_importpath(target, raising)\n\n        if not hasattr(target, name):\n            if raising:\n                raise AttributeError(name)\n        else:\n            oldval = getattr(target, name, NOTSET)\n            # Avoid class descriptors like staticmethod/classmethod.\n            if inspect.isclass(target):\n                oldval = target.__dict__.get(name, NOTSET)\n            self._setattr.append((target, name, oldval))\n            delattr(target, name)\n\n    def setitem(self, dic: Mapping[K, V], name: K, value: V) -> None:\n        \"\"\"Set dictionary entry ``name`` to value.\"\"\"\n        self._setitem.append((dic, name, dic.get(name, NOTSET)))\n        # Not all Mapping types support indexing, but MutableMapping doesn't support TypedDict\n        dic[name] = value  # type: ignore[index]\n\n    def delitem(self, dic: Mapping[K, V], name: K, raising: bool = True) -> None:\n        \"\"\"Delete ``name`` from dict.\n\n        Raises ``KeyError`` if it doesn't exist, unless ``raising`` is set to","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/monkeypatch.py#L261-L297","documentation":"Raised by MonkeyPatch.delattr as an AttributeError(name) when the attribute does not exist on target and raising=True (the default). pytest surfaces the missing attribute so the teardown bookkeeping is not silently a no-op.","triggerScenarios":"monkeypatch.delattr(obj, 'missing_attr') with the default raising=True; the attribute is absent (e.g. typo, never set, or already deleted).","commonSituations":"Typos in attribute names, conditional attributes that were never set this run, attributes removed earlier in the test, or asserts on optional features.","solutions":["Pass raising=False to tolerate a missing attribute: monkeypatch.delattr(obj, 'attr', raising=False)","Guard with hasattr(obj, 'attr') before calling delattr","Correct the attribute-name typo"],"exampleFix":"// before\nmonkeypatch.delattr(obj, 'atrr')\n// after\nmonkeypatch.delattr(obj, 'attr', raising=False)","handlingStrategy":"validation","validationCode":"if hasattr(target, name):\n    monkeypatch.delattr(target, name)\nelse:\n    monkeypatch.delattr(target, name, raising=False)","typeGuard":"def attr_exists(target, name) -> bool:\n    return hasattr(target, name)","tryCatchPattern":"try:\n    monkeypatch.delattr(target, name)\nexcept AttributeError:\n    pass  # attribute absent; acceptable in this test","preventionTips":["Pass raising=False whenever the attribute is optional for the test","Use hasattr() to guard deletion of conditional attributes"],"tags":["monkeypatch","attribute","pytest","delattr"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}