pytest-dev/pytest · error · AttributeError
has no attribute
Error message
{target!r} has no attribute {name!r} What it means
An AttributeError raised by MonkeyPatch.setattr when raising=True (the default) and the target does not already have the named attribute. pytest refuses to create brand-new attributes by default to catch typos and patches against the wrong object; oldval is NOTSET when getattr returns the sentinel. The message shows the target repr and the attribute name.
Solutions
- Verify the attribute exists on the exact object you are patching (use hasattr).
- Pass `raising=False` if you intentionally want to create a new attribute.
- Correct the dotted path to point at the object that actually owns the attribute (beware re-exports).
Example fix
# before monkeypatch.setattr(obj, 'attr_name', value) # AttributeError: <Obj> has no attribute 'attr_name' # after monkeypatch.setattr(obj, 'real_attr', value) # or, to create a new attribute: monkeypatch.setattr(obj, 'attr_name', value, raising=False)
Defensive patterns
Strategy: validation
Validate before calling
def can_patch(obj, name) -> bool:
return hasattr(obj, name) Try / catch
try:
monkeypatch.setattr(obj, 'attr', value)
except AttributeError:
monkeypatch.setattr(obj, 'attr', value, raising=False) Prevention
- Use hasattr to confirm the attribute before patching.
- Pass raising=False only when intentionally creating a new attribute.
- Patch the object that truly owns the attribute.
When it happens
Trigger: Calling `monkeypatch.setattr(obj, 'nonexistent', value)` with the default raising=True on an object that lacks the attribute; or `monkeypatch.setattr('mymod.X.typo', value)` where the attribute name is misspelled.
Common situations: Typos in the attribute name, patching the wrong class/module (e.g. a copy vs the original), version skew where the attribute was removed, or genuinely intending to add a new attribute without opting in.
Related errors
- object at has no attribute
- use setattr(target, name, value) or setattr(target, value)…
- use setattr(target, name, value) with name being a string…
- import error in
- Marker name must NOT start with underscore
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/c8995c0e710b8e71.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/monkeypatch.py:242
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,
name: str | NotSetType = NOTSET,
raising: bool = True,
) -> None:
"""Delete attribute ``name`` from ``target``.
If no ``name`` is specified and ``target`` is a string
it will be interpreted as a dotted import path with the
last part being the attribute name.View on GitHub (pinned to 0d6fbdeffa)