Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Code contributions:
- Muspi Merol (CNSeniorious000)
- YISH (mokeyish)
- Bit0r
- Jesper Schlegel (jesperschlegel)


Suggestions and bug reporting:
Expand Down
14 changes: 9 additions & 5 deletions box/box.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ def _parse_box_dots(bx, item, setting=False):
if char == "[":
return item[:idx], item[idx:]
elif char == ".":
if item[:idx] in bx:
return item[:idx], item[idx + 1 :]
return item[:idx], item[idx + 1 :]
if setting and "." in item:
return item.split(".", 1)
raise BoxError("Could not split box dots properly")
Expand Down Expand Up @@ -657,9 +656,14 @@ def __setitem__(self, key, value):
if hasattr(self[first_item], "__setitem__"):
return self[first_item].__setitem__(children, value)
elif self._box_config["default_box"]:
super().__setitem__(
first_item, self._box_config["box_class"](**self.__box_config(extra_namespace=first_item))
)
if children[0] == "[":
super().__setitem__(
first_item, box.BoxList(**self.__box_config(extra_namespace=first_item))
)
else:
super().__setitem__(
first_item, self._box_config["box_class"](**self.__box_config(extra_namespace=first_item))
)
return self[first_item].__setitem__(children, value)
else:
raise BoxKeyError(f"'{self.__class__}' object has no attribute {first_item}")
Expand Down
10 changes: 9 additions & 1 deletion box/box_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,17 @@ def __setitem__(self, key, value):
if self.box_options.get("box_dots") and isinstance(key, str) and key.startswith("["):
list_pos = _list_pos_re.search(key)
pos = int(list_pos.groups()[0])
if pos >= len(self) and self.box_options.get("default_box"):
self.extend([None] * (pos - len(self) + 1))
if len(list_pos.group()) == len(key):
return super().__setitem__(pos, value)
return super().__getitem__(pos).__setitem__(key[len(list_pos.group()) :].lstrip("."), value)
children = key[len(list_pos.group()):].lstrip(".")
if self.box_options.get("default_box"):
if children[0] == "[":
super().__setitem__(pos, box.BoxList(**self.box_options))
else:
super().__setitem__(pos, self.box_options.get("box_class")(**self.box_options))
return super().__getitem__(pos).__setitem__(children, value)
super().__setitem__(key, value)

def _is_intact_type(self, obj):
Expand Down
19 changes: 19 additions & 0 deletions test/test_box_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,25 @@ def test_box_list_dots(self):
for key in keys:
db[key]

def test_box_list_default_dots(self):
box_1 = Box(default_box=True, box_dots=True)
box_1["a[0]"] = 42
assert box_1.a[0] == 42

box_1["b[0].c[0].d"] = 42
assert box_1.b[0].c[0].d == 42

box_1["c[0][0][0]"] = 42
assert box_1.c[0][0][0] == 42

box_2 = Box(default_box=True, box_dots=True)
box_2["a[4]"] = 42
assert box_2.a.to_list() == [None, None, None, None, 42]

box_3 = Box(default_box=True, box_dots=True)
box_3["a.b[0]"] = 42
assert box_3.a.b[0] == 42

def test_box_config_propagate(self):
structure = Box(a=[Box(default_box=False)], default_box=True, box_inherent_settings=True)
assert structure._box_config["default_box"] is True
Expand Down
Loading