{"record":{"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/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/monkeypatch.py#L261-L297","documentation":"Raised by MonkeyPatch.delattr when raising=True (the default) and the target does not have the named attribute. This surfaces at line 279 after the hasattr check fails, so the deletion is aborted and the original AttributeError(name) propagates. The error mirrors Python's native delattr behavior but is gated by the raising flag, letting callers opt out for optional attributes.","triggerScenarios":"monkeypatch.delattr(target, 'nonexistent') with raising left at True; deleting an attribute that was never defined or already removed; typos in attribute names; deleting attributes conditionally mocked away.","commonSituations":"Test setup assumes a module exposes an attribute that the installed version does not; another fixture already deleted/restored the attribute; refactoring production code renamed or removed the attribute but tests still reference the old name.","solutions":["Verify the attribute exists at test time: hasattr(target, name) before calling delattr, or fix the attribute name.","Pass raising=False if the attribute is optional: monkeypatch.delattr(target, name, raising=False).","Align the test with the current API surface of the target module."],"exampleFix":"// before\nmonkeypatch.delattr(settings, 'DEBUG_FLAG')\n// after\nmonkeypatch.delattr(settings, 'DEBUG_FLAG', raising=False)","handlingStrategy":"validation","validationCode":"if raising and not hasattr(target, name):\n    # attribute absent; decide whether to skip deletion\n    monkeypatch.delattr(target, name, raising=False)","typeGuard":"def _attr_safe(target, name) -> bool:\n    return hasattr(target, name)","tryCatchPattern":"try:\n    monkeypatch.delattr(target, name)\nexcept AttributeError:\n    # attribute was absent; acceptable in this test\n    pass","preventionTips":["Use raising=False for attributes that may be absent.","Check hasattr before deleting when the API surface is uncertain."],"tags":["pytest","monkeypatch","attributeerror","api-misuse"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}