Source code for finstmt.config_manage.statement

from dataclasses import dataclass
from typing import Dict, List

import pandas as pd
from sympy import IndexedBase

from finstmt.config_manage.base import ConfigManagerBase
from finstmt.config_manage.data import DataConfigManager
from finstmt.exc import NoSuchItemException
from finstmt.items.config import ItemConfig
from finstmt.logger import logger


[docs]@dataclass class StatementConfigManager(ConfigManagerBase): """ Used for entire single financial statement, e.g. income statement or balance sheet, with multiple dates in the statement. """ config_managers: Dict[pd.Timestamp, DataConfigManager]
[docs] def get(self, item_key: str) -> ItemConfig: """ For internal use, get the config as well as the key of the financial statement type it belongs to """ for date, manager in self.config_managers.items(): try: conf = manager.get(item_key) logger.debug(f"Got config for {item_key} from {date}") return conf except KeyError: continue raise NoSuchItemException(item_key)
def __getattr__(self, item_key: str) -> ItemConfig: """ Get the config for a given key """ # When copying the object, config_managers can be undefined and so would cause a # recursive loop without this check if item_key == "config_managers": # Trigger the default Python behavior return object.__getattribute__(self, item_key) try: return self.get(item_key) except NoSuchItemException: raise AttributeError(item_key) def __dir__(self) -> List[str]: return self.keys
[docs] def set(self, item_key: str, config: ItemConfig) -> None: """ Set entire configuration for item by key. Needs to handle setting the value in each individual data config manager """ for date, manager in self.config_managers.items(): manager.set(item_key, config) logger.debug(f"Set config for {item_key} for {date}")
@property def sympy_namespace(self) -> Dict[str, IndexedBase]: for manager in self.config_managers.values(): # All should be identical, so first is enough return manager.sympy_namespace raise ValueError("no managers, could not get sympy_namespace") @property def keys(self) -> List[str]: all_keys = set() for manager in self.config_managers.values(): all_keys.update(manager.keys) return list(all_keys) @property def items(self) -> List[ItemConfig]: for manager in self.config_managers.values(): return manager.configs return []
# TODO [#39]: rethink low-level config structure # # We have a config for each item for each date and this method just gets the ones for the first date