From 1e268857546c4b5602aae53e7856aa9e873b6af8 Mon Sep 17 00:00:00 2001 From: Muspi Merol Date: Mon, 18 Sep 2023 06:52:37 +0000 Subject: [PATCH 1/2] Fixing #251 support for circular references in lists --- box/box_list.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/box/box_list.py b/box/box_list.py index 048b014..12548a1 100644 --- a/box/box_list.py +++ b/box/box_list.py @@ -40,16 +40,16 @@ def __new__(cls, *args, **kwargs): # This is required for pickling to work correctly obj.box_options = {"box_class": box.Box} obj.box_options.update(kwargs) - obj.box_org_ref = 0 return obj def __init__(self, iterable: Optional[Iterable] = None, box_class: Type[box.Box] = box.Box, **box_options): self.box_options = box_options self.box_options["box_class"] = box_class - self.box_org_ref = id(iterable) if iterable else 0 + self.box_org_ref = iterable if iterable: for x in iterable: self.append(x) + self.box_org_ref = None if box_options.get("frozen_box"): def frozen(*args, **kwargs): @@ -101,7 +101,7 @@ def _convert(self, p_object): elif isinstance(p_object, box.Box): p_object._box_config.update(self.box_options) if isinstance(p_object, list) and not self._is_intact_type(p_object): - p_object = self.__class__(p_object, **self.box_options) + p_object = self if p_object is self or p_object is self.box_org_ref else self.__class__(p_object, **self.box_options) elif isinstance(p_object, BoxList): p_object.box_options.update(self.box_options) return p_object From 92df3737cfcaa098b385dcb7d1c3ff73b13bd105 Mon Sep 17 00:00:00 2001 From: Muspi Merol Date: Mon, 18 Sep 2023 15:20:00 +0800 Subject: [PATCH 2/2] Fixing pickling and change circular_references test --- box/box_list.py | 1 + test/test_box_list.py | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/box/box_list.py b/box/box_list.py index 12548a1..00ca185 100644 --- a/box/box_list.py +++ b/box/box_list.py @@ -40,6 +40,7 @@ def __new__(cls, *args, **kwargs): # This is required for pickling to work correctly obj.box_options = {"box_class": box.Box} obj.box_options.update(kwargs) + obj.box_org_ref = None return obj def __init__(self, iterable: Optional[Iterable] = None, box_class: Type[box.Box] = box.Box, **box_options): diff --git a/test/test_box_list.py b/test/test_box_list.py index 536520f..c59245e 100644 --- a/test/test_box_list.py +++ b/test/test_box_list.py @@ -228,10 +228,8 @@ def test_no_recursion_errors(self): a.list_of_dicts.append([{"example2": 2}]) assert a["list_of_dicts"][1] == [{"example2": 2}] - def test_no_circular_references(self): - if sys.version_info >= (3, 12) and sys.platform == "win32": - pytest.skip("Windows fatal exception: stack overflow on github actions") + def test_circular_references(self): circular_list = [] circular_list.append(circular_list) - with pytest.raises(RecursionError): - BoxList(circular_list) + circular_box = BoxList(circular_list) + assert circular_box[0] == circular_box