diff --git a/music_kraken/objects/collection.py b/music_kraken/objects/collection.py index 2adb792..1e3ee89 100644 --- a/music_kraken/objects/collection.py +++ b/music_kraken/objects/collection.py @@ -1,7 +1,7 @@ from __future__ import annotations from collections import defaultdict -from typing import TypeVar, Generic, Dict, Optional, Iterable, List, Iterator, Tuple, Generator +from typing import TypeVar, Generic, Dict, Optional, Iterable, List, Iterator, Tuple, Generator, Union from .parents import OuterProxy T = TypeVar('T', bound=OuterProxy) @@ -55,17 +55,19 @@ class Collection(Generic[T]): self._id_to_index_values[__object.id].add((name, value)) - def _unmap_element(self, __object: T): - if __object.id in self._contains_ids: - self._contains_ids.remove(__object.id) + def _unmap_element(self, __object: Union[T, int]): + obj_id = __object.id if isinstance(__object, OuterProxy) else __object - for name, value in self._id_to_index_values[__object.id]: + if obj_id in self._contains_ids: + self._contains_ids.remove(obj_id) + + for name, value in self._id_to_index_values[obj_id]: if name in self._indexed_values: del self._indexed_values[name] if value in self._indexed_to_objects: del self._indexed_to_objects[value] - del self._id_to_index_values[__object.id] + del self._id_to_index_values[obj_id] def _contained_in_self(self, __object: T) -> bool: if __object.id in self._contains_ids: @@ -232,12 +234,14 @@ class Collection(Generic[T]): if existing_object.id == __object.id: return - append_to._unmap_element(existing_object) - append_to._unmap_element(__object) + old_id = existing_object.id existing_object.merge(__object) - append_to._map_element(existing_object) + if existing_object.id != old_id: + append_to._unmap_element(old_id) + + append_to._map_element(existing_object) def extend(self, __iterable: Optional[Generator[T, None, None]]): if __iterable is None: diff --git a/music_kraken/objects/parents.py b/music_kraken/objects/parents.py index 0ab6165..a90576b 100644 --- a/music_kraken/objects/parents.py +++ b/music_kraken/objects/parents.py @@ -3,9 +3,11 @@ from __future__ import annotations import random from collections import defaultdict from functools import lru_cache - from typing import Optional, Dict, Tuple, List, Type, Generic, Any, TypeVar, Set +from pathlib import Path +import inspect + from .metadata import Metadata from ..utils import get_unix_time, object_trace from ..utils.config import logging_settings, main_settings @@ -187,12 +189,12 @@ class OuterProxy: if __other is None: return - object_trace(f"merging {type(self).__name__} [{self.title_string} | {self.id}] with {type(__other).__name__} [{__other.title_string} | {__other.id}]") + object_trace(f"merging {type(self).__name__} [{self.title_string} | {self.id}] with {type(__other).__name__} [{__other.title_string} | {__other.id}] called by [{' | '.join(f'{s.function} {Path(s.filename).name}:{str(s.lineno)}' for s in inspect.stack()[1:4])}]") a = self b = __other - if a._inner is b._inner: + if a.id == b.id: return # switch instances if more efficient @@ -211,12 +213,15 @@ class OuterProxy: collection.parents.remove(parent_collection) except ValueError: pass - + + old_inner = b._inner a._inner._refers_to_instances.update(b._inner._refers_to_instances) for instance in b._inner._refers_to_instances: instance._inner = a._inner + del old_inner + def __merge__(self, __other: Optional[OuterProxy], override: bool = False): self.merge(__other, override)