python/cpython · error · TypeError
{obj!r} does not have annotations
Error message
{obj!r} does not have annotations What it means
After trying __annotations__ and __annotate__, get_annotations() raises TypeError if no annotations were found AND the object is neither a class nor callable. Classes and callables get an empty dict as a courtesy; everything else (instances, modules without annotations, plain objects) is considered not annotatable, hence the TypeError.
Source
Thrown at Lib/annotationlib.py:1003
ann = _get_dunder_annotations(obj)
case Format.STRING:
# For STRING, we try to call __annotate__
ann = _get_and_call_annotate(obj, format)
if ann is not None:
return dict(ann)
# But if we didn't get it, we use __annotations__ instead.
ann = _get_dunder_annotations(obj)
if ann is not None:
return annotations_to_string(ann)
case Format.VALUE_WITH_FAKE_GLOBALS:
raise ValueError("The VALUE_WITH_FAKE_GLOBALS format is for internal use only")
case _:
raise ValueError(f"Unsupported format {format!r}")
if ann is None:
if isinstance(obj, type) or callable(obj):
return {}
raise TypeError(f"{obj!r} does not have annotations")
if not ann:
return {}
if not eval_str:
return dict(ann)
if globals is None or locals is None:
if isinstance(obj, type):
# class
obj_globals = None
module_name = getattr(obj, "__module__", None)
if module_name:
module = sys.modules.get(module_name, None)
if module:
obj_globals = getattr(module, "__dict__", None)
obj_locals = dict(vars(obj))
unwrap = objView on GitHub (pinned to bc6749cc3b)
Solutions
- Pass the class or function itself, not an instance: get_annotations(type(obj)).
- Check `callable(obj) or isinstance(obj, type)` before calling, or use getattr checks.
- Catch TypeError and treat it as 'no annotations'.
Example fix
# before
ann = get_annotations(instance) # TypeError: 42 does not have annotations
# after
ann = get_annotations(type(instance)) or {} Defensive patterns
Strategy: type-guard
Validate before calling
def has_annotations_source(obj) -> bool:
return (isinstance(obj, type) or callable(obj)
or getattr(obj, '__annotations__', None) is not None
or getattr(obj, '__annotate__', None) is not None) Type guard
def annotatable(obj) -> bool:
return isinstance(obj, type) or callable(obj) Try / catch
try:
ann = get_annotations(obj)
except TypeError as e:
if 'does not have annotations' in str(e):
ann = {}
else:
raise Prevention
- Pass classes/functions, not instances
- Use type(obj) when handed an instance
- Treat 'no annotations' as an empty dict in callers
When it happens
Trigger: get_annotations(42); get_annotations(some_instance); get_annotations(<module without __annotations__>); passing an instance instead of its class.
Common situations: Introspection tools walking arbitrary objects; passing an instance where the class was intended; objects whose __annotations__ was deleted or set to None.
Related errors
- {obj!r}.__annotations__ is neither a dict nor None
- integer argument expected, got float
- invalid mode: %s
- expected integer from opener
- an integer is required
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/0611b1223f0d75fb.
Report an issue: GitHub.