pytest-dev/pytest · error · AttributeError
{type(obj).__name__!r} object at {ann} has no attribute {nam
Error message
{type(obj).__name__!r} object at {ann} has no attribute {name!r} What it means
`annotated_getattr` is used while resolving a dotted import path: after importing the parent module, each remaining segment is fetched via `getattr`. If the attribute is missing, AttributeError is re-raised with a message naming the object type, the import path being resolved (`ann`), and the missing attribute name.
Source
Thrown at src/_pytest/monkeypatch.py:97
# We use explicit un-nesting of the handling block in order
# to avoid nested exceptions.
try:
importlib.import_module(used)
except ImportError as ex:
expected = str(ex).split()[-1]
if expected == used:
raise
else:
raise ImportError(f"import error in {used}: {ex}") from ex
found = annotated_getattr(found, part, used)
return found
def annotated_getattr(obj: object, name: str, ann: str) -> object:
try:
obj = getattr(obj, name)
except AttributeError as e:
raise AttributeError(
f"{type(obj).__name__!r} object at {ann} has no attribute {name!r}"
) from e
return obj
def derive_importpath(import_path: str, raising: bool) -> tuple[str, object]:
if not isinstance(import_path, str) or "." not in import_path:
raise TypeError(f"must be absolute import path string, not {import_path!r}")
module, attr = import_path.rsplit(".", 1)
target = resolve(module)
if raising:
annotated_getattr(target, attr, ann=module)
return attr, target
@final
class MonkeyPatch:
"""Helper to conveniently monkeypatch attributes/items/environmentView on GitHub (pinned to 98b357f69e)
Solutions
- Check the spelling of every segment against the actual module with `hasattr(module, 'attr')`.
- Pin or upgrade the target library to a version that has the attribute, or update the path to the new name.
- Pass `raising=False` to `setattr` if you intend to create a brand-new attribute.
Example fix
# before
monkeypatch.setattr('os.getcw', fake)
# after
monkeypatch.setattr('os.getcwd', fake) Defensive patterns
Strategy: validation
Validate before calling
def attr_exists(dotted: str) -> bool:
module, attr = dotted.rsplit('.', 1)
import importlib
try:
return hasattr(importlib.import_module(module), attr)
except ImportError:
return False Prevention
- Verify the attribute exists at import time before patching.
- Patch where the name is looked up, not where it is defined.
When it happens
Trigger: `monkeypatch.setattr('os.getcwd', ...)` where the last segment does not exist on the resolved module; typos like `os.getcwd` -> `os.getcw`; patching a private name that was renamed.
Common situations: Typos in the dotted path; library version changed/renamed/removed the attribute; patching a function injected lazily at runtime that doesn't exist at import time.
Related errors
- {target!r} has no attribute {name!r}
- 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/f58a4dd2d1ed3ba4.json.
Report an issue: GitHub.