diff --git a/README.md b/README.md index 0f3a4647..7a9e7fd8 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ python-benedict is a dict subclass with **keylist/keypath/keyattr** support, **I - [Usage](#usage) - [Basics](#basics) - [Keyattr](#keyattr) `my_dict.x.y.z` - - [Keylist](#keylist) `my_dict["x", "y", "z"]` + - [Keylist](#keylist) `my_dict[["x", "y", "z"]]` - [Keypath](#keypath) `my_dict["x.y.z"]` - [Custom keypath separator](#custom-keypath-separator) - [Change keypath separator](#change-keypath-separator) @@ -136,16 +136,16 @@ Wherever a **key** is used, it is possible to use also a **list (or a tuple) of d = benedict() # set values by keys list -d["profile", "firstname"] = "Fabio" -d["profile", "lastname"] = "Caccamo" +d[["profile", "firstname"]] = "Fabio" +d[["profile", "lastname"]] = "Caccamo" print(d) # -> { "profile":{ "firstname":"Fabio", "lastname":"Caccamo" } } print(d["profile"]) # -> { "firstname":"Fabio", "lastname":"Caccamo" } # check if keypath exists in dict -print(["profile", "lastname"] in d) # -> True +print([["profile", "lastname"]] in d) # -> True # delete value by keys list -del d["profile", "lastname"] +del d[["profile", "lastname"]] print(d["profile"]) # -> { "firstname":"Fabio" } ``` diff --git a/benedict/dicts/keylist/keylist_dict.py b/benedict/dicts/keylist/keylist_dict.py index 0f0bc23a..a337a017 100644 --- a/benedict/dicts/keylist/keylist_dict.py +++ b/benedict/dicts/keylist/keylist_dict.py @@ -8,7 +8,7 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def __contains__(self, key): - if type_util.is_list_or_tuple(key): + if type_util.is_list(key): return self._contains_by_keys(key) return super().__contains__(key) @@ -19,7 +19,7 @@ def _contains_by_keys(self, keys): return False def __delitem__(self, key): - if type_util.is_list_or_tuple(key): + if type_util.is_list(key): self._delitem_by_keys(key) return super().__delitem__(key) @@ -35,7 +35,7 @@ def _delitem_by_keys(self, keys): raise KeyError(f"Invalid keys: {keys!r}") def __getitem__(self, key): - if type_util.is_list_or_tuple(key): + if type_util.is_list(key): return self._getitem_by_keys(key) return super().__getitem__(key) @@ -46,7 +46,7 @@ def _getitem_by_keys(self, keys): raise KeyError(f"Invalid keys: {keys!r}") def __setitem__(self, key, value): - if type_util.is_list_or_tuple(key): + if type_util.is_list(key): self._setitem_by_keys(key, value) return super().__setitem__(key, value) @@ -55,7 +55,7 @@ def _setitem_by_keys(self, keys, value): keylist_util.set_item(self, keys, value) def get(self, key, default=None): - if type_util.is_list_or_tuple(key): + if type_util.is_list(key): return self._get_by_keys(key, default) return super().get(key, default) @@ -68,7 +68,7 @@ def _get_by_keys(self, keys, default=None): return default def pop(self, key, *args): - if type_util.is_list_or_tuple(key): + if type_util.is_list(key): return self._pop_by_keys(key, *args) return super().pop(key, *args) diff --git a/benedict/dicts/keypath/keypath_util.py b/benedict/dicts/keypath/keypath_util.py index 2a864e65..fcff75fd 100644 --- a/benedict/dicts/keypath/keypath_util.py +++ b/benedict/dicts/keypath/keypath_util.py @@ -26,7 +26,7 @@ def parse_keys(keypath, separator): """ Parse keys from keylist or keypath using the given separator. """ - if type_util.is_list_or_tuple(keypath): + if type_util.is_list(keypath): keys = [] for key in keypath: keys += parse_keys(key, separator) diff --git a/tests/dicts/keylist/test_keylist_dict.py b/tests/dicts/keylist/test_keylist_dict.py index 6db5e740..e708b1fc 100644 --- a/tests/dicts/keylist/test_keylist_dict.py +++ b/tests/dicts/keylist/test_keylist_dict.py @@ -14,9 +14,6 @@ def test_contains(self): d["a"]["b"] = True self.assertTrue(["a", "b"] in d) self.assertFalse(["a", "b", "c"] in d) - # with keys as tuple - self.assertTrue(("a", "b") in d) - self.assertFalse(("a", "b", "c") in d) def test_delitem(self): d = KeylistDict() @@ -27,10 +24,6 @@ def test_delitem(self): del d[["a", "b", "c"]] self.assertFalse(["a", "b", "c"] in d) self.assertTrue(["a", "b"] in d) - # with keys as tuple - del d[("a", "b")] - self.assertFalse(["a", "b"] in d) - self.assertTrue(["a"] in d) def test_get(self): d = KeylistDict() @@ -38,9 +31,6 @@ def test_get(self): d["a"]["b"] = True self.assertEqual(d.get(["a", "b"]), True) self.assertEqual(d.get(["a", "b"]), True) - # with keys as tuple - self.assertEqual(d.get(("a", "b")), True) - self.assertEqual(d.get(("a", "b")), True) def test_getitem(self): d = KeylistDict() @@ -48,9 +38,6 @@ def test_getitem(self): d["a"]["b"] = True self.assertEqual(d[["a", "b"]], True) self.assertEqual(d[["a", "b"]], True) - # with keys as tuple - self.assertEqual(d[("a", "b")], True) - self.assertEqual(d[("a", "b")], True) def test_pop(self): d = KeylistDict() @@ -61,10 +48,6 @@ def test_pop(self): d.pop(["a", "b", "c"]) self.assertFalse(["a", "b", "c"] in d) self.assertTrue(["a", "b"] in d) - # with keys as tuple - d.pop(("a", "b")) - self.assertFalse(["a", "b"] in d) - self.assertTrue(["a"] in d) def test_set(self): # TODO diff --git a/tests/dicts/keypath/test_keypath_dict.py b/tests/dicts/keypath/test_keypath_dict.py index c5f4b88b..9f314fd8 100644 --- a/tests/dicts/keypath/test_keypath_dict.py +++ b/tests/dicts/keypath/test_keypath_dict.py @@ -334,17 +334,11 @@ def test_get_item_with_keys_list(self): }, } b = KeypathDict(d) - self.assertEqual(b["a", "b.c"], 1) self.assertEqual(b[["a", "b.c"]], 1) - self.assertEqual(b[("a", "b.c")], 1) - self.assertEqual(b["a", "b", "c"], 1) self.assertEqual(b[["a", "b", "c"]], 1) - self.assertEqual(b[("a", "b", "c")], 1) - self.assertEqual(b["a", "b", "d"], 2) self.assertEqual(b[["a", "b", "d"]], 2) - self.assertEqual(b[("a", "b", "d")], 2) with self.assertRaises(KeyError): - _ = b["a", "b", "e"] + _ = b[["a", "b", "e"]] def test_get_item_with_keys_list_and_no_keypath_separator(self): d = { @@ -357,16 +351,12 @@ def test_get_item_with_keys_list_and_no_keypath_separator(self): } b = KeypathDict(d, keypath_separator=None) with self.assertRaises(KeyError): - _ = b["a", "b.c"] + _ = b[["a", "b.c"]] - self.assertEqual(b["a", "b", "c"], 1) self.assertEqual(b[["a", "b", "c"]], 1) - self.assertEqual(b[("a", "b", "c")], 1) - self.assertEqual(b["a", "b", "d"], 2) self.assertEqual(b[["a", "b", "d"]], 2) - self.assertEqual(b[("a", "b", "d")], 2) with self.assertRaises(KeyError): - _ = b["a", "b", "e"] + _ = b[["a", "b", "e"]] def test_has_with_1_key(self): d = { @@ -516,13 +506,13 @@ def test_setitem_with_keys_list(self): }, } b = KeypathDict(d) - b["a", "b.c"] = 2 + b[["a", "b.c"]] = 2 self.assertEqual(b["a.b.c"], 2) - b["a", "b", "c"] = 3 + b[["a", "b", "c"]] = 3 self.assertEqual(b["a.b.c"], 3) - b["a", "b", "d"] = 4 + b[["a", "b", "d"]] = 4 self.assertEqual(b["a.b.d"], 4) - b["a", "b", "e"] = 5 + b[["a", "b", "e"]] = 5 self.assertEqual(b["a.b.e"], 5) def test_setitem_with_keys_list_and_no_keypath_separator(self): @@ -535,20 +525,20 @@ def test_setitem_with_keys_list_and_no_keypath_separator(self): }, } b = KeypathDict(d, keypath_separator=None) - b["a", "b", "c"] = 3 + b[["a", "b", "c"]] = 3 with self.assertRaises(KeyError): _ = b["a.b.c"] - self.assertEqual(b["a", "b", "c"], 3) + self.assertEqual(b[["a", "b", "c"]], 3) - b["a", "b", "d"] = 4 + b[["a", "b", "d"]] = 4 with self.assertRaises(KeyError): _ = b["a.b.d"] - self.assertEqual(b["a", "b", "d"], 4) + self.assertEqual(b[["a", "b", "d"]], 4) - b["a", "b", "e"] = 5 + b[["a", "b", "e"]] = 5 with self.assertRaises(KeyError): _ = b["a.b.e"] - self.assertEqual(b["a", "b", "e"], 5) + self.assertEqual(b[["a", "b", "e"]], 5) def test_setitem_with_dict_value_with_separator_in_keys(self): d = { @@ -668,8 +658,8 @@ def test_delitem_with_keys_list(self): } b = KeypathDict(d) with self.assertRaises(KeyError): - del b["a", "b", "c", "d"] - del b["a", "b", "c"] + del b[["a", "b", "c", "d"]] + del b[["a", "b", "c"]] self.assertEqual(b.get("a.b.c", 3), 3) def test_delitem_with_keys_list_and_no_keypath_separator(self): @@ -683,8 +673,8 @@ def test_delitem_with_keys_list_and_no_keypath_separator(self): } b = KeypathDict(d, keypath_separator=None) with self.assertRaises(KeyError): - del b["a", "b", "c", "d"] - del b["a", "b", "c"] + del b[["a", "b", "c", "d"]] + del b[["a", "b", "c"]] self.assertEqual(b.get("a.b.c", 3), 3) def test_pop_default(self): diff --git a/tests/github/test_issue_0432.py b/tests/github/test_issue_0432.py new file mode 100644 index 00000000..d076d114 --- /dev/null +++ b/tests/github/test_issue_0432.py @@ -0,0 +1,31 @@ +import unittest +from benedict import benedict + + +class github_issue_0432_test_case(unittest.TestCase): + """ + This class describes a github issue 0432 test case. + https://github.com/fabiocaccamo/python-benedict/issues/432 + + To run this specific test: + - Run python -m unittest tests.github.test_issue_0432 + """ + + def test_tuple_as_key_like_dict_432(self): + d1 = {} + d2 = benedict() + d1[(0, 0, 1)] = "a" + d2[(0, 0, 1)] = "a" + self.assertEqual(d1, d2) + + def test_tuple_as_key_like_dict_412(self): + d = {} + d[("a", True)] = "test" + + b1 = benedict() + b1[("a", True)] = "test" + self.assertEqual(d, b1) + + b2 = benedict() + b2.update({("a", True): "test"}) + self.assertEqual(d, b2)