diff --git a/README.md b/README.md index 3167765..c14b4c6 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,16 @@ print('profile.lastname' in d) # -> True d.deepcopy() ``` +```python +# Return a readable representation of any dict/list. +s = benedict.dump(d.keypaths()) +print(s) + +# Return a readable representation of the dict for the given key (optional). +s = d.dump_items(key=None) +print(s) +``` + ```python # Return a list of all keypaths in the dict. d.keypaths() @@ -61,12 +71,6 @@ d.keypaths() d.get_bool(key, default=False) ``` -```python -# Get value by key or keypath trying to return it as bool. -# Values like `1`, `true`, `yes`, `on`, `ok` will be returned as `True`. -d.get_bool(key, default=False) -``` - ```python # Get value by key or keypath trying to return it as list of bool values. # If separator is specified and value is a string it will be splitted. diff --git a/README.rst b/README.rst index 50b4574..dab2d4e 100644 --- a/README.rst +++ b/README.rst @@ -58,6 +58,16 @@ Extra methods # Return a deepcopy of the dict. d.deepcopy() +.. code:: python + # Return a readable representation of any dict/list. + s = benedict.dump(d.keypaths()) + print(s) + +.. code:: python + # Return a readable representation of the dict for the given key (optional). + s = d.dump_items(key=None) + print(s) + .. code:: python # Return a list of all keypaths in the dict. diff --git a/benedict/dicts/__init__.py b/benedict/dicts/__init__.py index 31b9b63..697672c 100644 --- a/benedict/dicts/__init__.py +++ b/benedict/dicts/__init__.py @@ -5,6 +5,7 @@ from benedict.dicts.keypath import KeypathDict from benedict.dicts.parse import ParseDict import copy +import json class benedict(KeypathDict, ParseDict): @@ -39,6 +40,17 @@ class benedict(KeypathDict, ParseDict): def deepcopy(self): return copy.deepcopy(self) + @staticmethod + def dump(data): + def encoder(obj): + if not isinstance(obj, (bool, dict, float, int, list, tuple, str, )): + return str(obj) + return json.dumps(data, indent=4, sort_keys=True, default=encoder) + + def dump_items(self, key=None): + return benedict.dump( + self.get(key) if key else self) + @classmethod def fromkeys(cls, sequence, value=None): return benedict._cast( diff --git a/tests/test_dicts_benedict.py b/tests/test_dicts_benedict.py index e3c931a..057ce41 100644 --- a/tests/test_dicts_benedict.py +++ b/tests/test_dicts_benedict.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- from benedict import benedict +from datetime import datetime +from decimal import Decimal import unittest @@ -41,6 +43,82 @@ class BenedictTestCase(unittest.TestCase): self.assertEqual(b.get('a.b.c'), 1) self.assertEqual(c.get('a.b.c'), 2) + def test_dump(self): + d = { + 'a': { + 'b': { + 'c': 1 + } + } + } + b = benedict(d) + expected_output = """{ + "a": { + "b": { + "c": 1 + } + } +}""" + output = benedict.dump(b) + self.assertEqual(output, expected_output) + + def test_dump_items(self): + d = { + 'a': { + 'b': { + 'c': 1 + } + } + } + b = benedict(d) + print(b.dump_items()) + expected_output = """{ + "a": { + "b": { + "c": 1 + } + } +}""" + output = b.dump_items() + self.assertEqual(output, expected_output) + + def test_dump_items_with_key(self): + d = { + 'a': { + 'b': { + 'c': 1 + } + } + } + b = benedict(d) + expected_output = """{ + "c": 1 +}""" + output = b.dump_items('a.b') + self.assertEqual(output, expected_output) + + def test_dump_items_with_datetime(self): + d = { + 'datetime': datetime(2019, 6, 11), + } + b = benedict(d) + expected_output = """{ + "datetime": "2019-06-11 00:00:00" +}""" + output = b.dump_items() + self.assertEqual(output, expected_output) + + def test_dump_items_with_decimal(self): + d = { + 'decimal': Decimal('1.75'), + } + b = benedict(d) + expected_output = """{ + "decimal": "1.75" +}""" + output = b.dump_items() + self.assertEqual(output, expected_output) + def test_fromkeys(self): k = [ 'a', @@ -117,7 +195,7 @@ class BenedictTestCase(unittest.TestCase): def test_get_dict(self): d = { - 'a': { 'x':1, 'y':2 }, + 'a': {'x': 1, 'y': 2}, 'b': {}, } b = benedict(d) @@ -183,4 +261,3 @@ class BenedictTestCase(unittest.TestCase): b = benedict(d) self.assertTrue(isinstance(b.setdefault('b', 1), benedict)) self.assertTrue(isinstance(b.setdefault('b.d', 1), benedict)) -