Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_raw_map_attribute_with_initialized_instance_init(self):
attribute = {
'foo': 123,
'bar': 'baz'
}
initialized_instance = MapAttribute(**attribute)
actual = ExplicitRawMapModel(map_id=3, map_attr=initialized_instance)
self.assertEqual(actual.map_attr['foo'], initialized_instance['foo'])
self.assertEqual(actual.map_attr['foo'], attribute['foo'])
def test_raw_map_json_serialize(self):
raw = {
"foo": "bar",
"num": 3,
"nested": {
"nestedfoo": "nestedbar"
}
}
serialized_raw = json.dumps(raw, sort_keys=True)
serialized_attr_from_raw = json.dumps(
AttributeTestModel(map_attr=raw).map_attr.as_dict(),
sort_keys=True)
serialized_attr_from_map = json.dumps(
AttributeTestModel(map_attr=MapAttribute(**raw)).map_attr.as_dict(),
sort_keys=True)
assert serialized_attr_from_raw == serialized_raw
assert serialized_attr_from_map == serialized_raw
'workman': [
{
'name': 'Mandy',
'age': 29,
'height': 157.48,
'female': True
},
{
'name': 'Rodney',
'age': 31,
'height': 175.26,
'hasChild': False
}
]
}
serialized = MapAttribute().serialize(family_attributes)
assert MapAttribute().deserialize(serialized) == family_attributes
def test_complex_map_accessors(self):
class NestedThing(MapAttribute):
double_nested = MapAttribute()
double_nested_renamed = MapAttribute(attr_name='something_else')
class ThingModel(Model):
nested = NestedThing()
t = ThingModel(nested=NestedThing(
double_nested={'hello': 'world'},
double_nested_renamed={'foo': 'bar'})
)
assert t.nested.double_nested.as_dict() == {'hello': 'world'}
assert t.nested.double_nested_renamed.as_dict() == {'foo': 'bar'}
assert t.nested.double_nested.hello == 'world'
assert t.nested.double_nested_renamed.foo == 'bar'
assert t.nested['double_nested'].as_dict() == {'hello': 'world'}
def test_attribute_paths_wrapping(self):
class InnerMapAttribute(MapAttribute):
map_attr = MapAttribute(attr_name='dyn_map_attr')
class MiddleMapAttributeA(MapAttribute):
inner_map = InnerMapAttribute(attr_name='dyn_in_map_a')
class MiddleMapAttributeB(MapAttribute):
inner_map = InnerMapAttribute(attr_name='dyn_in_map_b')
class OuterMapAttribute(MapAttribute):
mid_map_a = MiddleMapAttributeA()
mid_map_b = MiddleMapAttributeB()
class MyModel(Model):
outer_map = OuterMapAttribute(attr_name='dyn_out_map')
mid_map_a_map_attr = MyModel.outer_map.mid_map_a.inner_map.map_attr
mid_map_b_map_attr = MyModel.outer_map.mid_map_b.inner_map.map_attr
assert mid_map_a_map_attr.attr_name == 'dyn_map_attr'
assert mid_map_a_map_attr.attr_path == ['dyn_out_map', 'mid_map_a', 'dyn_in_map_a', 'dyn_map_attr']
assert mid_map_b_map_attr.attr_name == 'dyn_map_attr'
assert mid_map_b_map_attr.attr_path == ['dyn_out_map', 'mid_map_b', 'dyn_in_map_b', 'dyn_map_attr']
def test_typed_and_raw_map_json_serialize(self):
class TypedMap(MapAttribute):
map_attr = MapAttribute()
class SomeModel(Model):
typed_map = TypedMap()
item = SomeModel(
typed_map=TypedMap(map_attr={'foo': 'bar'})
)
assert json.dumps({'map_attr': {'foo': 'bar'}}) == json.dumps(item.typed_map.as_dict())
class TreeModel(Model):
class Meta:
table_name = 'TreeModelTable'
tree_key = UnicodeAttribute(hash_key=True)
left = TreeLeaf()
right = TreeLeaf()
class ExplicitRawMapModel(Model):
class Meta:
table_name = 'ExplicitRawMapModel'
map_id = NumberAttribute(hash_key=True, default=123)
map_attr = MapAttribute()
class MapAttrSubClassWithRawMapAttr(MapAttribute):
num_field = NumberAttribute()
str_field = UnicodeAttribute()
map_field = MapAttribute()
class ExplicitRawMapAsMemberOfSubClass(Model):
class Meta:
table_name = 'ExplicitRawMapAsMemberOfSubClass'
map_id = NumberAttribute(hash_key=True)
sub_attr = MapAttrSubClassWithRawMapAttr()
class Animal(Model):
for name, attr in self._get_attributes().items():
if isinstance(attr, ListAttribute):
if attr is None or getattr(self, name) is None:
yield name, None
else:
values = attr.serialize(getattr(self, name))
if len(values) < 1:
yield name, []
else:
key = list(values[0].keys())[0]
yield name, [value[key] for value in values]
else:
yield name, attr.serialize(getattr(self, name))
class DocumentTabModel(MapAttribute):
"""
Represents a document tab in the document model.
"""
document_tab_type = UnicodeAttribute(default='text')
document_tab_id = UnicodeAttribute()
document_tab_name = UnicodeAttribute()
document_tab_page = NumberAttribute(default=1)
document_tab_position_x = NumberAttribute()
document_tab_position_y = NumberAttribute()
document_tab_width = NumberAttribute(default=200)
document_tab_height = NumberAttribute(default=20)
document_tab_is_locked = BooleanAttribute(default=False)
document_tab_is_required = BooleanAttribute(default=True)
class DocumentTab(model_interfaces.DocumentTab):
"""
self.uuid_version = uuid_version
super(UUIDAttribute, self).__init__(hash_key=hash_key, range_key=range_key,
null=null, default=default, attr_name=attr_name)
def serialize(self, value):
if isinstance(value, uuid.UUID):
value_str = str(value)
uuid.UUID(value_str, version=self.uuid_version)
return super(UUIDAttribute, self).serialize(value_str)
else:
return super(UUIDAttribute, self).serialize(value)
class MapAttribute(PynamoDBMapAttribute):
"""
A Map Attribute
The MapAttribute class can be used to store a JSON document as "raw" name-value pairs, or
it can be subclassed and the document fields represented as class attributes using Attribute instances.
To support the ability to subclass MapAttribute and use it as an AttributeContainer, instances of
MapAttribute behave differently based both on where they are instantiated and on their type.
Because of this complicated behavior, a bit of an introduction is warranted.
Models that contain a MapAttribute define its properties using a class attribute on the model.
For example, below we define "MyModel" which contains a MapAttribute "my_map":
class MyModel(Model):
my_map = MapAttribute(attr_name="dynamo_name", default={})
def set_document_tab_position_x(self, tab_position_x):
self.model.document_tab_position_x = tab_position_x
def set_document_tab_position_y(self, tab_position_y):
self.model.document_tab_position_y = tab_position_y
def set_document_tab_width(self, tab_width):
self.model.document_tab_width = tab_width
def set_document_tab_height(self, tab_height):
self.model.document_tab_height = tab_height
def set_document_tab_is_locked(self, is_locked):
self.model.document_tab_is_locked = is_locked
class DocumentModel(MapAttribute):
"""
Represents a document in the project model.
"""
document_name = UnicodeAttribute()
document_file_id = UnicodeAttribute(null=True)
document_content_type = UnicodeAttribute() # pdf, url+pdf, storage+pdf, etc
document_content = UnicodeAttribute(null=True) # None if using storage service.
document_major_version = NumberAttribute(default=1)
document_minor_version = NumberAttribute(default=0)
document_author_name = UnicodeAttribute()
# Not using UTCDateTimeAttribute due to https://github.com/pynamodb/PynamoDB/issues/162
document_creation_date = UnicodeAttribute()
document_preamble = UnicodeAttribute(null=True)
document_legal_entity_name = UnicodeAttribute(null=True)
document_tabs = ListAttribute(of=DocumentTabModel, default=[])