diff --git a/music_kraken/__init__.py b/music_kraken/__init__.py index 0f906f6..f67bf3b 100644 --- a/music_kraken/__init__.py +++ b/music_kraken/__init__.py @@ -46,7 +46,7 @@ init_logging() from . import cli if DEBUG: - sys.setrecursionlimit(5000) + sys.setrecursionlimit(300) if main_settings['modify_gc']: diff --git a/music_kraken/objects/collection.py b/music_kraken/objects/collection.py index d351774..e4905dc 100644 --- a/music_kraken/objects/collection.py +++ b/music_kraken/objects/collection.py @@ -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): diff --git a/music_kraken/objects/parents.py b/music_kraken/objects/parents.py index 4a8d064..feebe3d 100644 --- a/music_kraken/objects/parents.py +++ b/music_kraken/objects/parents.py @@ -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: diff --git a/music_kraken/utils/shared.py b/music_kraken/utils/shared.py index 6676393..8861fce 100644 --- a/music_kraken/utils/shared.py +++ b/music_kraken/utils/shared.py @@ -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