{"id":"f599fc6dd3fc243f","repo":"pytest-dev/pytest","slug":"use-setattr-target-name-value-with-name-being-a","errorCode":null,"errorMessage":"use setattr(target, name, value) with name being a string or setattr(target, value) with target being a dotted import string","messagePattern":"use setattr\\(target, name, value\\) with name being a string or setattr\\(target, value\\) with target being a dotted import string","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/monkeypatch.py","lineNumber":234,"sourceCode":"        See the section :ref:`Where to patch <python:where-to-patch>` in the :mod:`unittest.mock`\n        docs for a complete explanation, which is meant for :func:`unittest.mock.patch` but\n        applies to ``monkeypatch.setattr`` as well.\n        \"\"\"\n        __tracebackhide__ = True\n        import inspect\n\n        if value is NOTSET:\n            if not isinstance(target, str):\n                raise TypeError(\n                    \"use setattr(target, name, value) or \"\n                    \"setattr(target, value) with target being a dotted \"\n                    \"import string\"\n                )\n            value = name\n            name, target = derive_importpath(target, raising)\n        else:\n            if not isinstance(name, str):\n                raise TypeError(\n                    \"use setattr(target, name, value) with name being a string or \"\n                    \"setattr(target, value) with target being a dotted \"\n                    \"import string\"\n                )\n\n        oldval = getattr(target, name, NOTSET)\n        if raising and oldval is NOTSET:\n            raise AttributeError(f\"{target!r} has no attribute {name!r}\")\n\n        # avoid class descriptors like staticmethod/classmethod\n        if inspect.isclass(target):\n            oldval = target.__dict__.get(name, NOTSET)\n        setattr(target, name, value)\n        self._setattr.append((target, name, oldval))\n\n    def delattr(\n        self,\n        target: object | str,","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/monkeypatch.py#L216-L252","documentation":"When the three-argument form of `monkeypatch.setattr` is used (`value` is provided), `name` must be a `str`. If it is not (e.g. an int, the value itself, or NOTSET misuse), TypeError is raised pointing to the correct call signatures.","triggerScenarios":"`monkeypatch.setattr(os, 123, fake)`, or accidentally swapping `name` and `value` like `setattr(os, fake, 'getcwd')`.","commonSituations":"Swapping the second and third argument; passing a non-string attribute name from dynamic code.","solutions":["Ensure the second positional arg is the string attribute name and the third is the value.","When the name is dynamic, coerce it with `str(name)` before calling."],"exampleFix":"# before\nmonkeypatch.setattr(os, fake, 'getcwd')\n# after\nmonkeypatch.setattr(os, 'getcwd', fake)","handlingStrategy":"type-guard","validationCode":"def valid_setattr_name(name) -> bool:\n    return isinstance(name, str)","typeGuard":"def is_setattr_name(name: object) -> bool:\n    return isinstance(name, str)","tryCatchPattern":null,"preventionTips":["Keep argument order: `(target, name, value)`.","Coerce dynamic names with `str()`."],"tags":["pytest","monkeypatch","type-error","setattr","api-usage"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}