pytest-dev/pytest · error · TypeError
use setattr(target, name, value) with name being a string…
Error message
use setattr(target, name, value) with name being a string or setattr(target, value) with target being a dotted import string
What it means
A TypeError raised by MonkeyPatch.setattr when the three-argument form is used (value is provided) but the `name` argument is not a string. pytest requires the attribute name to be a string when patching a concrete target object. Passing an int, None, or any non-string as the name triggers this guard.
Solutions
- Ensure the second positional argument (name) is a string naming the attribute.
- If the name is dynamic, coerce to str or validate before calling.
- Double-check argument order: (target, name, value).
Example fix
# before monkeypatch.setattr(obj, attr_name if cond else None, value) # after monkeypatch.setattr(obj, str(attr_name), value)
Defensive patterns
Strategy: type-guard
Validate before calling
def is_setattr_name(name) -> bool:
return isinstance(name, str) Type guard
def is_valid_attribute_name(name) -> bool:
return isinstance(name, str) and len(name) > 0 Prevention
- Always pass a string attribute name in the three-arg form.
- Coerce dynamic names with str() after a None-check.
- Keep argument order: (target, name, value).
When it happens
Trigger: Calling `monkeypatch.setattr(obj, 123, value)`, `monkeypatch.setattr(obj, None, value)`, or `monkeypatch.setattr(obj, ['attr'], value)`. The branch `value is not NOTSET and not isinstance(name, str)` fires.
Common situations: Passing a computed attribute name that is None; mixing positional arguments; confusing the order of (target, name, value).
Related errors
- use setattr(target, name, value) or setattr(target, value)…
- must be absolute import path string, not
- has no attribute
- object at has no attribute
- Expected id to be a string or a `pytest.HIDDEN_PARAM`…
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/f599fc6dd3fc243f.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/monkeypatch.py:234
See the section :ref:`Where to patch <python:where-to-patch>` in the :mod:`unittest.mock`
docs for a complete explanation, which is meant for :func:`unittest.mock.patch` but
applies to ``monkeypatch.setattr`` as well.
"""
__tracebackhide__ = True
import inspect
if value is NOTSET:
if not isinstance(target, str):
raise TypeError(
"use setattr(target, name, value) or "
"setattr(target, value) with target being a dotted "
"import string"
)
value = name
name, target = derive_importpath(target, raising)
else:
if not isinstance(name, str):
raise TypeError(
"use setattr(target, name, value) with name being a string or "
"setattr(target, value) with target being a dotted "
"import string"
)
oldval = getattr(target, name, NOTSET)
if raising and oldval is NOTSET:
raise AttributeError(f"{target!r} has no attribute {name!r}")
# avoid class descriptors like staticmethod/classmethod
if inspect.isclass(target):
oldval = target.__dict__.get(name, NOTSET)
setattr(target, name, value)
self._setattr.append((target, name, oldval))
def delattr(
self,
target: object | str,View on GitHub (pinned to 0d6fbdeffa)