Skip to content
This repository has been archived by the owner on Oct 3, 2019. It is now read-only.

Commit

Permalink
Implement rudimentary fix for references attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
jacebrowning committed Apr 28, 2015
1 parent b771be3 commit 17b5266
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 5 deletions.
72 changes: 70 additions & 2 deletions yorm/converters/containers.py
Expand Up @@ -75,7 +75,52 @@ def to_data(cls, value):
return data

def apply(self, data):
value = self.to_value(data)
# TODO: replace to_value and to_data
cls = self.__class__

# TODO: is `default` still needed?
value = cls.default()

# Convert object attributes to a dictionary
attrs = common.ATTRS[cls].copy()
if isinstance(data, cls):
dictionary = {}
for k, v in data.items():
if k in attrs:
dictionary[k] = v
for k, v in data.__dict__.items():
if k in attrs:
dictionary[k] = v
else:
dictionary = to_dict(data)

# Map object attributes to converters
for name, data in dictionary.items():
try:
converter = attrs.pop(name)
except KeyError:
converter = standard.match(name, data, nested=True)
common.ATTRS[cls][name] = converter

# Convert the loaded data
if issubclass(converter, Container):
container = getattr(self, name, None)
if not isinstance(container, converter):
container = converter()
setattr(self, name, container)
container.apply(data)
value[name] = container
else:
value[name] = converter.to_value(data)

# Create default values for unmapped converters
for name, converter in attrs.items():
if issubclass(converter, Container):
value[name] = converter()
else:
value[name] = converter.to_value(None)
log.warn("added missing nested key '%s'...", name)

self.clear()
self.update(value)

Expand Down Expand Up @@ -128,7 +173,30 @@ def to_data(cls, value):
return data

def apply(self, data):
value = self.to_value(data)
# TODO: replace to_value and to_data
cls = self.__class__

# TODO: is `default` still needed?
value = cls.default()

converter = cls.item_type

for item in to_list(data):
if issubclass(converter, Container):

try:
container = self[len(value)]
except IndexError:
container = converter() # pylint: disable=E1120
else:
if not isinstance(container, converter):
container = converter() # pylint: disable=E1120

container.apply(item)
value.append(container)
else:
value.append(converter.to_value(item))

self[:] = value[:]


Expand Down
6 changes: 3 additions & 3 deletions yorm/test/test_all_nesting.py
Expand Up @@ -340,10 +340,10 @@ def test_alias_list_in_dict(self):
top = Top()
top.nested_dict.number = 1
ref1 = top.nested_dict
ref2 = top.nested_dict.nested_list2
ref2 = top.nested_dict.nested_list_2
yorm.update(top)
assert id(ref1) == top.nested_dict
assert id(ref2) == top.nested_dict.nested_list2
assert id(ref1) == id(top.nested_dict)
assert id(ref2) == id(top.nested_dict.nested_list_2)


if __name__ == '__main__':
Expand Down

0 comments on commit 17b5266

Please sign in to comment.