feat: removed children from collections after merging

This commit is contained in:
Hazel 2024-04-17 17:24:51 +02:00
parent cc5ee88389
commit b15d0839ef
4 changed files with 28 additions and 39 deletions

View File

@ -46,7 +46,7 @@ init_logging()
from . import cli
if DEBUG:
sys.setrecursionlimit(5000)
sys.setrecursionlimit(300)
if main_settings['modify_gc']:

View File

@ -43,13 +43,11 @@ class Collection(Generic[T]):
self.extend(data)
def _map_element(self, __object: T, from_map: bool = False):
if __object.id in self._contains_ids:
return
__object._inner._mapped_in_collection.add(self)
self._contains_ids.add(__object.id)
for name, value in __object.indexing_values:
if value is None:
if value is None or value == __object._inner._default_values.get(name):
continue
self._indexed_values[name].add(value)
@ -175,8 +173,6 @@ class Collection(Generic[T]):
def _find_object_in_self(self, __object: T) -> Optional[T]:
for name, value in __object.indexing_values:
if value is None or value == __object._default_factories.get(name, lambda: None)():
continue
if value in self._indexed_values[name]:
return self._indexed_to_objects[value][0]
@ -219,7 +215,7 @@ class Collection(Generic[T]):
:return:
"""
if __object is None or __object.id in self._contains_ids:
if __object is None:
return
append_to, existing_object = self._find_object(__object)
@ -230,8 +226,8 @@ class Collection(Generic[T]):
append_to._map_element(__object)
# only modify collections if the object actually has been appended
for collection_attribute, new_object in self.contain_given_in_attribute.items():
__object.__getattribute__(collection_attribute).contain_collection_inside(new_object)
for collection_attribute, child_collection in self.contain_given_in_attribute.items():
__object.__getattribute__(collection_attribute).contain_collection_inside(child_collection, __object)
for attribute, new_object in self.append_object_to_attribute.items():
__object.__getattribute__(attribute).append(new_object)
@ -252,39 +248,22 @@ class Collection(Generic[T]):
for __object in __iterable:
self.append(__object)
def sync_with_other_collection(self, equal_collection: Collection):
"""
If two collections always need to have the same values, this can be used.
Internally:
1. import the data from other to self
- _data
- contained_collections
2. replace all refs from the other object, with refs from this object
"""
if equal_collection is self:
return
# don't add the elements from the subelements from the other collection.
# this will be done in the next step.
self.extend(equal_collection._data)
# add all submodules
for equal_sub_collection in equal_collection.children:
self.contain_collection_inside(equal_sub_collection)
def contain_collection_inside(self, sub_collection: Collection):
def contain_collection_inside(self, sub_collection: Collection, _object: T):
"""
This collection will ALWAYS contain everything from the passed in collection
"""
if self is sub_collection or sub_collection in self.children:
return
_object._inner._is_collection_child[self] = sub_collection
_object._inner._is_collection_parent[sub_collection] = self
self.children.append(sub_collection)
sub_collection.parents.append(self)
@property
def data(self) -> List[T]:
return list(i for i in self.__iter__())
return list(self.__iter__())
def __len__(self) -> int:
return len(self._data) + sum(len(collection) for collection in self.children)
@ -306,7 +285,7 @@ class Collection(Generic[T]):
yield from c.__iter__(finished_ids=finished_ids)
def __merge__(self, __other: Collection, override: bool = False):
self.extend(__other)
self.extend(__other.__iter__())
def __getitem__(self, item: int):
if item < len(self._data):

View File

@ -29,12 +29,16 @@ class InnerData:
_refers_to_instances: set = None
def __init__(self, object_type, **kwargs):
self._refers_to_instances =set()
self._refers_to_instances = set()
# collection : collection that is a collection of self
self._is_collection_child: Dict[Collection, Collection] = {}
self._is_collection_parent: Dict[Collection, Collection] = {}
# initialize the default values
self.__default_values = {}
self._default_values = {}
for name, factory in object_type._default_factories.items():
self.__default_values[name] = factory()
self._default_values[name] = factory()
for key, value in kwargs.items():
self.__setattr__(key, value)
@ -48,7 +52,7 @@ class InnerData:
for key, value in __other.__dict__.copy().items():
# just set the other value if self doesn't already have it
if key not in self.__dict__ or (key in self.__dict__ and self.__dict__[key] == self.__default_values.get(key)):
if key not in self.__dict__ or (key in self.__dict__ and self.__dict__[key] == self._default_values.get(key)):
self.__setattr__(key, value)
continue
@ -183,7 +187,7 @@ class OuterProxy:
if __other is None:
return
object_trace(f"merging {type(self).__name__} [{self.title_string}] with {type(__other).__name__} [{__other.title_string}]")
object_trace(f"merging {type(self).__name__} [{self.title_string} | {self.id}] with {type(__other).__name__} [{__other.title_string} | {__other.id}]")
a = self
b = __other
@ -196,6 +200,12 @@ class OuterProxy:
a, b = b, a
a._inner.__merge__(b._inner, override=override)
for collection, child_collection in b._inner._is_collection_child.items():
collection.children.remove(child_collection)
for collection, parent_collection in b._inner._is_collection_parent.items():
collection.parents.remove(parent_collection)
a._inner._refers_to_instances.update(b._inner._refers_to_instances)
for instance in b._inner._refers_to_instances:

View File

@ -15,7 +15,7 @@ __stage__ = os.getenv("STAGE", "prod")
DEBUG = (__stage__ == "dev") and True
DEBUG_LOGGING = DEBUG and True
DEBUG_TRACE = DEBUG and True
DEBUG_OBJECT_TRACE = DEBUG and False
DEBUG_OBJECT_TRACE = DEBUG and True
DEBUG_YOUTUBE_INITIALIZING = DEBUG and False
DEBUG_PAGES = DEBUG and False
DEBUG_DUMP = DEBUG and True