pytest-dev/pytest · error · AttributeError
{target!r} has no attribute {name!r}
Error message
{target!r} has no attribute {name!r} What it means
In `monkeypatch.setattr`, after resolving target+name, pytest checks the existing attribute. With `raising=True` (the default), if the attribute is not present on the target it raises `AttributeError: <target> has no attribute <name>`. This is the guard against patching non-existent attributes, which usually signals a typo or wrong patch location.
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 98b357f69e)
Solutions
- Patch the name where it is looked up (e.g. `mypkg.mod.os` if `myobj` does `import os` there).
- Set `raising=False` if you intentionally create a new attribute.
- Verify with `hasattr(target, name)` before patching to get a clearer assertion.
Example fix
# before monkeypatch.setattr(mymod, 'requests.get', fake) # nested path not an attribute # after import mymod.requests as r monkeypatch.setattr(r, 'get', fake)
Defensive patterns
Strategy: validation
Validate before calling
def safe_to_patch(target, name) -> bool:
return hasattr(target, name) Try / catch
try:
monkeypatch.setattr(target, name, fake)
except AttributeError:
# patch the using module instead, or pass raising=False to create
monkeypatch.setattr(target, name, fake, raising=False) Prevention
- Patch the name where it is looked up, not where it is defined.
- Use `hasattr` checks or `raising=False` for genuinely new attributes.
- Confirm the attribute exists after the runtime setup that defines it.
When it happens
Trigger: `monkeypatch.setattr(myobj, 'nonexistent', fake)` with default `raising=True`; patching an attribute introduced only after some runtime setup that hasn't happened.
Common situations: Patching the wrong module (the classic 'where to patch' problem — patching the using module vs the defining module); typos; version skew where the attribute was removed.
Related errors
- {type(obj).__name__!r} object at {ann} has no attribute {nam
- import error in {used}: {ex}
- use setattr(target, name, value) or setattr(target, value) w
- use setattr(target, name, value) with name being a string or
- Marker name must NOT start with underscore
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/c8995c0e710b8e71.json.
Report an issue: GitHub.