fix: recursion depth

This commit is contained in:
Hazel 2024-01-15 10:50:24 +01:00
parent 60297d6faf
commit f81720f01b
4 changed files with 78 additions and 13 deletions

View File

@ -43,7 +43,8 @@ if __name__ == "__main__":
bandcamp_test = [ bandcamp_test = [
"s: #a Ghost Bath", "s: #a Ghost Bath",
"0" "0",
"d: 4"
] ]

View File

@ -1,10 +1,9 @@
from __future__ import annotations from __future__ import annotations
from collections import defaultdict from collections import defaultdict
from typing import TypeVar, Generic, Dict, Optional, Iterable, List, Iterator from typing import TypeVar, Generic, Dict, Optional, Iterable, List, Iterator, Tuple
from .parents import OuterProxy from .parents import OuterProxy
T = TypeVar('T', bound=OuterProxy) T = TypeVar('T', bound=OuterProxy)
@ -47,6 +46,9 @@ class Collection(Generic[T]):
self.extend(data) self.extend(data)
def _map_element(self, __object: T, from_map: bool = False): def _map_element(self, __object: T, from_map: bool = False):
if __object.id in self._contains_ids:
return
self._contains_ids.add(__object.id) self._contains_ids.add(__object.id)
for name, value in __object.indexing_values: for name, value in __object.indexing_values:
@ -67,6 +69,7 @@ class Collection(Generic[T]):
__object.__getattribute__(attribute).append(new_object) __object.__getattribute__(attribute).append(new_object)
def _unmap_element(self, __object: T): def _unmap_element(self, __object: T):
if __object.id in self._contains_ids:
self._contains_ids.remove(__object.id) self._contains_ids.remove(__object.id)
for name, value in __object.indexing_values: for name, value in __object.indexing_values:
@ -188,10 +191,53 @@ class Collection(Generic[T]):
self._map_element(__object, from_map=from_map) self._map_element(__object, from_map=from_map)
self._data.append(__object) self._data.append(__object)
def _find_object_in_self(self, __object: T) -> Optional[T]:
for name, value in __object.indexing_values:
if value is None:
continue
if value in self._indexed_values[name]:
return self._indexed_to_objects[value][0]
def _find_object(self, __object: T) -> Tuple[Collection[T], Optional[T]]:
other_object = self._find_object_in_self(__object)
if other_object is not None:
return self, other_object
for c in self.children:
o, other_object = c._find_object(__object)
if other_object is not None:
return o, other_object
return self, None
def append(self, __object: Optional[T], already_is_parent: bool = False, from_map: bool = False): def append(self, __object: Optional[T], already_is_parent: bool = False, from_map: bool = False):
"""
If an object, that represents the same entity exists in a relevant collection,
merge into this object. (and remap)
Else append to this collection.
:param __object:
:param already_is_parent:
:param from_map:
:return:
"""
if __object is None or __object.id in self._contains_ids: if __object is None or __object.id in self._contains_ids:
return return
append_to, existing_object = self._find_object(__object)
if existing_object is None:
# append
append_to._data.append(__object)
else:
# merge
append_to._unmap_element(existing_object)
existing_object.merge(__object)
append_to._map_element(__object, from_map=from_map)
"""
exists_in_collection = self._contained_in_sub(__object) exists_in_collection = self._contained_in_sub(__object)
if len(exists_in_collection) and self is exists_in_collection[0]: if len(exists_in_collection) and self is exists_in_collection[0]:
# assuming that the object already is contained in the correct collections # assuming that the object already is contained in the correct collections
@ -202,20 +248,20 @@ class Collection(Generic[T]):
if not len(exists_in_collection): if not len(exists_in_collection):
self._append(__object, from_map=from_map) self._append(__object, from_map=from_map)
else: else:
pass
exists_in_collection[0].merge_into_self(__object, from_map=from_map) exists_in_collection[0].merge_into_self(__object, from_map=from_map)
if not already_is_parent or not self._is_root: if not already_is_parent or not self._is_root:
for parent_collection in self._get_parents_of_multiple_contained_children(__object): for parent_collection in self._get_parents_of_multiple_contained_children(__object):
pass pass
parent_collection.append(__object, already_is_parent=True, from_map=from_map) parent_collection.append(__object, already_is_parent=True, from_map=from_map)
"""
def extend(self, __iterable: Optional[Iterable[T]]): def extend(self, __iterable: Optional[Iterable[T]], from_map: bool = False):
if __iterable is None: if __iterable is None:
return return
for __object in __iterable: for __object in __iterable:
self.append(__object) self.append(__object, from_map=from_map)
def sync_with_other_collection(self, equal_collection: Collection): def sync_with_other_collection(self, equal_collection: Collection):
""" """
@ -263,6 +309,23 @@ class Collection(Generic[T]):
for element in self._data: for element in self._data:
yield element yield element
for c in self.children:
for element in c:
yield element
def __merge__(self, __other: Collection, override: bool = False): def __merge__(self, __other: Collection, override: bool = False):
print(__other) self.extend(__other.shallow_list, from_map=True)
self.extend(__other.shallow_list)
def __getitem__(self, item: int):
if item < len(self._data):
return self._data[item]
item = item - (len(self._data) - 1)
for c in self.children:
if item < len(c):
return c[item]
item = item - (len(self._data) - 1)
raise IndexError

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import random import random
from functools import lru_cache from functools import lru_cache
from typing import Optional, Dict, Tuple, List, Type, Generic, Any, TypeVar from typing import Optional, Dict, Tuple, List, Type, Generic, Any, TypeVar, Set
from .metadata import Metadata from .metadata import Metadata
from ..utils.config import logging_settings from ..utils.config import logging_settings
@ -61,6 +61,7 @@ class OuterProxy:
""" """
_default_factories: dict = {} _default_factories: dict = {}
_outer_attribute: Set[str] = {"options", "metadata", "indexing_values"}
def __init__(self, _id: int = None, dynamic: bool = False, **kwargs): def __init__(self, _id: int = None, dynamic: bool = False, **kwargs):
_automatic_id: bool = False _automatic_id: bool = False
@ -111,8 +112,8 @@ class OuterProxy:
:return: :return:
""" """
if __name.startswith("_"): if __name.startswith("_") or __name in self._outer_attribute:
return super().__getattribute__(__name) return object.__getattribute__(self, __name)
_inner: InnerData = super().__getattribute__("_inner") _inner: InnerData = super().__getattribute__("_inner")
try: try:

View File

@ -268,7 +268,7 @@ class Album(Base):
@property @property
def option_string(self) -> str: def option_string(self) -> str:
return f"{self.__repr__()} " \ return f"{self.__repr__()} " \
f"by Artist({OPTION_STRING_DELIMITER.join([artist.name for artist in self.artist_collection])}) " \ f"by Artist({OPTION_STRING_DELIMITER.join([str(artist.name) for artist in self.artist_collection])}) " \
f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})" f"under Label({OPTION_STRING_DELIMITER.join([label.name for label in self.label_collection])})"
@property @property