Skip to content

Commit

Permalink
Merge pull request #2 from farmersez/to-dict
Browse files Browse the repository at this point in the history
#1: Added to_dict
  • Loading branch information
Nurdok committed Oct 4, 2015
2 parents 0708eed + 3ffb1ed commit e816d26
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,6 @@ docs/_build/

# PyBuilder
target/

# PyCharm files
.idea
23 changes: 23 additions & 0 deletions src/basicstruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""This is a placeholder."""

import six
from copy import deepcopy
from six.moves import zip
from itertools import chain

Expand All @@ -24,6 +25,20 @@ def __init__(self, *args, **kwargs):
if not hasattr(self, key):
setattr(self, key, None)

def to_dict(self, copy=False):
"""Convert the struct to a dictionary.
If `copy == True`, returns a deep copy of the values.
"""
new_dict = {}
for attr, value in self:
if copy:
value = deepcopy(value)
new_dict[attr] = value

return new_dict

def __repr__(self):
attrs_str = ', '.join('{0}={1!r}'.format(key, getattr(self, key))
for key in self.__slots__)
Expand Down Expand Up @@ -62,6 +77,14 @@ def __ne__(self, other):
def __hash__(self):
return hash(self._to_tuple())

def __iter__(self):
"""Yield pairs of (attrubute_name, value).
This allows using `dict(my_struct)`.
"""
return zip(self.__slots__, self._to_tuple())

def _to_tuple(self):
return tuple(getattr(self, key) for key in self.__slots__)

Expand Down
19 changes: 19 additions & 0 deletions src/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,25 @@ def test_hash(self):
self.assertNotEqual(hash(medium), hash(large))
self.assertEqual(hash(medium), hash(another_medium))

def test_to_dict(self):
f = Foo(1, 2)
d1 = f.to_dict()
d2 = dict(f)
expected = {'x': 1, 'y': 2}

self.assertEqual(d1, expected)
self.assertEqual(d2, expected)

def test_to_dict_copy(self):
l = []
f = Foo(1, l)
d1 = f.to_dict()
d2 = f.to_dict(copy=True)
l.append(1)

self.assertEqual(d1, {'x': 1, 'y': [1]})
self.assertEqual(d2, {'x': 1, 'y': []})


if __name__ == '__main__':
unittest.main()

0 comments on commit e816d26

Please sign in to comment.