@@ -39,17 +39,20 @@ def __init__(self,
39
39
self .attr_name = attr_name
40
40
41
41
def __set__ (self , instance , value ):
42
- if instance :
42
+ if instance and not self . _is_map_attribute_class_object ( instance ) :
43
43
attr_name = instance ._dynamo_to_python_attrs .get (self .attr_name , self .attr_name )
44
44
instance .attribute_values [attr_name ] = value
45
45
46
46
def __get__ (self , instance , owner ):
47
- if instance :
47
+ if instance and not self . _is_map_attribute_class_object ( instance ) :
48
48
attr_name = instance ._dynamo_to_python_attrs .get (self .attr_name , self .attr_name )
49
49
return instance .attribute_values .get (attr_name , None )
50
50
else :
51
51
return self
52
52
53
+ def _is_map_attribute_class_object (self , instance ):
54
+ return isinstance (instance , MapAttribute ) and getattr (instance , '_class_object' , False )
55
+
53
56
def serialize (self , value ):
54
57
"""
55
58
This method should return a dynamodb compatible value
@@ -120,8 +123,18 @@ def _initialize_attributes(cls):
120
123
if item_cls is None :
121
124
continue
122
125
123
- if issubclass (item_cls , ( Attribute , ) ):
126
+ if issubclass (item_cls , Attribute ):
124
127
instance = getattr (cls , item_name )
128
+ if isinstance (instance , MapAttribute ):
129
+ # Attributes are data descriptors that bind their value to the containing object.
130
+ # When subclassing MapAttribute and using them as AttributeContainers on a Model,
131
+ # their internal attributes are bound to the instance in the Model class.
132
+ # The `_class_object` attribute is used to indicate that the MapAttribute instance
133
+ # belongs to a class object and not a class instance, overriding the binding.
134
+ # Without this, Model.MapAttribute().attribute would the value and not the object;
135
+ # whereas Model.attribute always returns the object.
136
+ instance ._class_object = True
137
+
125
138
cls ._attributes [item_name ] = instance
126
139
if instance .attr_name is not None :
127
140
cls ._dynamo_to_python_attrs [instance .attr_name ] = item_name
0 commit comments