aosabook/500lines · error · AttributeError
fieldname
Error message
fieldname
What it means
Raised by Base.read_attr in the 04-maps objmodel. Lookup order is identical to the 03-customizable variant (instance storage -> class MRO -> __getattr__), but instance storage is backed by a Map/shape mechanism rather than a plain dict. Reaching this raise means the field is absent from the instance's indexed storage, the class MRO, and no __getattr__ resolved it.
Source
Thrown at objmodel/code/04-maps/objmodel.py:24
def __init__(self, cls, fields):
""" Every object has a class. """
self.cls = cls
self._fields = fields
def read_attr(self, fieldname):
""" read field 'fieldname' out of the object """
result = self._read_dict(fieldname)
if result is not MISSING:
return result
result = self.cls._read_from_class(fieldname)
if _is_bindable(result):
return _make_boundmethod(result, self)
if result is not MISSING:
return result
meth = self.cls._read_from_class("__getattr__")
if meth is not MISSING:
return meth(self, fieldname)
raise AttributeError(fieldname)
def write_attr(self, fieldname, value):
""" write field 'fieldname' into the object """
meth = self.cls._read_from_class("__setattr__")
return meth(self, fieldname, value)
def isinstance(self, cls):
""" return True if the object is an instance of class cls """
return self.cls.issubclass(cls)
def callmethod(self, methname, *args):
""" call method 'methname' with arguments 'args' on object """
meth = self.read_attr(methname)
return meth(*args)
def _read_dict(self, fieldname):
""" read an field 'fieldname' out of the object's dict """
return self._fields.get(fieldname, MISSING)View on GitHub (pinned to fba689d101)
Solutions
- Store the field through write_attr so it is registered in the instance's Map storage.
- Add the attribute to the Class fields so it resolves via _read_from_class.
- Provide a __getattr__ on the class to handle unknown names gracefully.
Example fix
// before
obj.read_attr('height') # AttributeError: height
// after
obj.write_attr('height', 180)
obj.read_attr('height') Defensive patterns
Strategy: validation
Validate before calling
MISSING = object()
def safe_read(obj, fieldname, default=None):
if obj._read_dict(fieldname) is not MISSING:
return obj._read_dict(fieldname)
cls_val = obj.cls._read_from_class(fieldname)
if cls_val is not MISSING:
return cls_val
return default Type guard
def has_field_or_getattr(obj, name):
MISSING = object()
return (obj._read_dict(name) is not MISSING
or obj.cls._read_from_class(name) is not MISSING
or obj.cls._read_from_class('__getattr__') is not MISSING) Try / catch
try:
val = obj.read_attr(fieldname)
except AttributeError:
val = <default> Prevention
- Use write_attr so the field is registered in the instance Map storage.
- Provide __getattr__ on the class for graceful fallback.
- Check storage and class MRO before read_attr.
When it happens
Trigger: Reading a field that was never stored on the instance and is not present in the class MRO, while the class defines no usable __getattr__. Because storage is map-indexed, the field must have been added through the Map's add_attribute path to be readable.
Common situations: Writing a field via a different storage path than the Map expects; referencing attributes before they are allocated in the instance's Map; typos; missing __getattr__ coverage.
Related errors
- fieldname
- fieldname
- name '%s' is not defined
- local variable '%s' referenced before assignment
- global name '%s' is not defined
AI-assisted analysis of aosabook/500lines@fba689d101 (2026-08-13).
Data as JSON: /api/errors/e6b8ab2e1ff9657f.
Report an issue: GitHub.