Skip to content

Commit

Permalink
[Fix] Encode nested Dotty object into standard dict (#66)
Browse files Browse the repository at this point in the history
* Add no_list flag and remove deprecations

* Fix docs

* Add possibility to json dump nested Dotty

* Add to_json()

* Simplify to_dict

* Remove newline at the end

* Remove unit tests for to_json, because it's unreal to test string from dict
  • Loading branch information
Dysproz committed Jul 7, 2020
1 parent 3a5a691 commit b23b8a4
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
30 changes: 29 additions & 1 deletion dotty_dict/dotty_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from collections import Mapping

from functools import lru_cache
import json

__author__ = 'Paweł Zadrożny'
__copyright__ = 'Copyright (c) 2017, Paweł Zadrożny'
Expand Down Expand Up @@ -309,7 +310,17 @@ def to_dict(self):
:return dict: Wrapped dictionary
"""
return self._data
return json.loads(self.to_json())

def to_json(self):
"""Return wrapped dictionary as json string.
This method does not copy wrapped dictionary.
:return str: Wrapped dictionary as json string
"""
return json.dumps(self._data, cls=DottyEncoder)


def _split(self, key):
"""Split dot notated chain of keys.
Expand All @@ -333,3 +344,20 @@ def _split(self, key):
keys[i] = k.replace(*stamp_esc).replace(*stamp_skp)

return keys


class DottyEncoder(json.JSONEncoder):
"""Helper class for encoding of nested Dotty dicts into standard dict
"""
def default(self, obj):
"""Return dict data of Dotty when possible or encode with standard format
:param object: Input object
:return: Serializable data
"""
if hasattr(obj, '_data'):
return obj._data
else:
return json.JSONEncoder.default(self, obj)

13 changes: 13 additions & 0 deletions tests/test_dotty_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ def test_to_dict(self):
self.assertIsInstance(dot.to_dict(), dict)
self.assertEqual(sorted(dot.to_dict().items()), sorted(plain_dict.items()))

def test_nested_dotty_object_to_dict(self):
expected_dict = {'hello': {'world': 1}, 'nested': {'dotty': {'wazaa': 3}}}
top_dot = dotty({'hello': {'world': 1}})
nested_dot = dotty({'wazaa': 3})
top_dot['nested.dotty'] = nested_dot
self.assertDictEqual(top_dot.to_dict(), expected_dict)

def test_nested_dotty_in_list_to_dict(self):
expected_dict = {'testlist': [{'dot1': 1}, {'dot2': 2}]}
dot_list = [dotty({'dot1': 1}), dotty({'dot2': 2})]
top_dot = dotty({'testlist': dot_list})
self.assertDictEqual(top_dot.to_dict(), expected_dict)


class TestDictSpecificMethods(unittest.TestCase):
def setUp(self):
Expand Down

0 comments on commit b23b8a4

Please sign in to comment.