{"record":{"id":"b604869ab8ba0cca","repo":"aosabook/500lines","slug":"fieldname","errorCode":null,"errorMessage":"fieldname","messagePattern":"fieldname","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"objmodel/code/02-attr-based/objmodel.py","lineNumber":21,"sourceCode":"class Base(object):\n    \"\"\" The base class that all of the object model classes inherit from. \"\"\"\n\n    def __init__(self, cls, fields):\n        \"\"\" Every object has a class. \"\"\"\n        self.cls = cls\n        self._fields = fields\n\n    def read_attr(self, fieldname):\n        \"\"\" read field 'fieldname' out of the object \"\"\"\n        result = self._read_dict(fieldname)\n        if result is not MISSING:\n            return result\n        result = self.cls._read_from_class(fieldname)\n        if _is_bindable(result):\n            return _make_boundmethod(result, self)\n        if result is not MISSING:\n            return result\n        raise AttributeError(fieldname)\n\n    def write_attr(self, fieldname, value):\n        \"\"\" write field 'fieldname' into the object \"\"\"\n        self._write_dict(fieldname, value)\n\n    def isinstance(self, cls):\n        \"\"\" return True if the object is an instance of class cls \"\"\"\n        return self.cls.issubclass(cls)\n\n    def callmethod(self, methname, *args):\n        \"\"\" call method 'methname' with arguments 'args' on object \"\"\"\n        meth = self.read_attr(methname)\n        return meth(*args)\n\n    def _read_dict(self, fieldname):\n        \"\"\" read an field 'fieldname' out of the object's dict \"\"\"\n        return self._fields.get(fieldname, MISSING)\n","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/aosabook/500lines/blob/fba689d101eb5600f5c8f4d7fd79912498e950e2/objmodel/code/02-attr-based/objmodel.py#L3-L39","documentation":"Raised by Base.read_attr in the 02-attr-based objmodel when a field is not in the instance's own dict (self._fields) and not found walking the class MRO via cls._read_from_class, and the class result is not a bindable callable. The message is the bare fieldname. This variant has no __getattr__ fallback, so any truly absent attribute lands here.","triggerScenarios":"Calling obj.read_attr('foo') (directly, or indirectly via attribute access / callmethod) where 'foo' was never written with write_attr and is not a field/method on the instance's class or any base class. E.g. reading an attribute from a freshly created Instance whose Class has no such field.","commonSituations":"Forgetting to write_attr before read_attr; referencing a method name never added to the Class fields; a typo in the fieldname; expecting inherited attributes when the base_class chain does not contain them.","solutions":["Store the field first via write_attr, or pass it in the Class fields dict at construction.","Confirm the fieldname spelling matches between write and read.","Add the field/method to the Class (or a base class in the MRO) so _read_from_class resolves it.","Move to the 03-customizable or 04-maps variant, which support a __getattr__ fallback before raising."],"exampleFix":"// before\nobj = Instance(MyClass)\nobj.read_attr('color')   # AttributeError: color\n// after\nobj = Instance(MyClass)\nobj.write_attr('color', 'red')\nobj.read_attr('color')","handlingStrategy":"validation","validationCode":"MISSING = object()\n\ndef has_attr(obj, fieldname):\n    if obj._read_dict(fieldname) is not MISSING:\n        return True\n    return obj.cls._read_from_class(fieldname) is not MISSING\n\n# before reading\nif has_attr(obj, 'color'):\n    obj.read_attr('color')","typeGuard":"def field_exists(obj, name):\n    MISSING = object()  # same sentinel as objmodel\n    return (obj._fields.get(name, MISSING) is not MISSING\n            or obj.cls._read_from_class(name) is not MISSING)","tryCatchPattern":"try:\n    val = obj.read_attr(fieldname)\nexcept AttributeError:\n    val = <default>","preventionTips":["Always write_attr before read_attr on a new field.","Centralize field access behind a helper that supplies a default.","Add fields to the Class fields dict so instances inherit them."],"tags":["attribute-access","object-model","python"],"backgroundTag":null,"analyzedSha":"fba689d101eb5600f5c8f4d7fd79912498e950e2","analyzedAt":"2026-08-13T06:26:32.792Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}