Source code for app.portfolio.models.portfolio.portfolio_impl

# SPDX-License-Identifier: GPLv3-or-later
# Copyright © 2025 pygaindalf Rui Pinheiro

from abc import ABCMeta
from collections.abc import Iterator
from collections.abc import Set as AbstractSet
from typing import TYPE_CHECKING, override

from ....util.helpers.empty_class import empty_class
from ...collections.ordered_view import OrderedViewSet
from ...util.uid import Uid
from ..entity import Entity, EntityImpl
from ..instrument import Instrument, InstrumentRecord
from ..ledger import Ledger, LedgerRecord
from .portfolio_schema import PortfolioSchema


[docs] class PortfolioImpl[ T_Ledger_Set: OrderedViewSet[Ledger], ]( EntityImpl, PortfolioSchema[T_Ledger_Set] if TYPE_CHECKING else empty_class(), AbstractSet[Ledger], metaclass=ABCMeta, ): # MARK: Ledgers def __getitem__(self, index: int | Uid | InstrumentRecord | Instrument) -> Ledger: ledger = None if isinstance(index, int): return self.ledgers[index] if isinstance(index, Uid): entity = Entity.by_uid(index) if isinstance(entity, Ledger): if entity not in self.ledgers: msg = f"Ledger with UID {index} not found in portfolio" raise KeyError(msg) return entity elif not isinstance(entity, Instrument): msg = f"Instrument with UID {index} not found in portfolio" raise KeyError(msg) index = entity if isinstance(index, (Instrument, InstrumentRecord)): instrument = Instrument.narrow_to_uid(index) if (ledger := Ledger.by_instrument(instrument)) is None: msg = f"Ledger for index '{index}' not found" raise KeyError(msg) return ledger msg = f"Index must be an int, Uid or InstrumentRecord, got {type(index).__name__}" raise KeyError(msg) # MARK: Set ABC @override def __contains__(self, value: object) -> bool: if not isinstance(value, (Ledger, LedgerRecord, Uid)): return False return Ledger.narrow_to_instance(value) in self.ledgers @override def __iter__(self) -> Iterator[Ledger]: # pyright: ignore[reportIncompatibleMethodOverride] since we are overriding the pydantic BaseModel iterator on purpose return iter(self.ledgers) @override def __len__(self) -> int: return len(self.ledgers) @override def __repr__(self) -> str: return super().__repr__().replace(">", f", ledgers={self.ledgers!r}>")