Source code for spines.parameters.store

# -*- coding: utf-8 -*-
"""
Parameter storage module.
"""
from collections.abc import MutableMapping
from typing import Dict
from typing import Iterator
from typing import Type

from .base import Parameter
from .base import MissingParameterException
from .decorators import state_changed


[docs]class ParameterStore(MutableMapping): """ Helper class for managing collections of Parameters. """ def __init__(self): self._params = dict() self._values = dict() self._finalized = True return def __repr__(self): ret = "<%s final=%s> {\n" % (self.__class__.__name__, self._finalized) for k, v in self._params.items(): ret += " %s: %s,\n" % (repr(v), self._values.get(k)) ret += "}" return ret def __str__(self): ret = "{\n" for k, v in self._params.items(): ret += " %s: %s\n" % (v, self._values.get(k)) ret += "}" return ret @state_changed def __setitem__(self, k: str, v) -> None: self._values[k] = self._params[k](v) return @state_changed def __delitem__(self, v: str) -> None: del self._values[v] def __getitem__(self, k: str): return self._values[k] def __len__(self) -> int: return len(self._values) def __iter__(self) -> Iterator[str]: return iter(self._values) @property def parameters(self) -> Dict[str, Parameter]: """dict: Copy of the current set of parameters.""" return self._params.copy() @property def values(self) -> Dict[str, object]: """dict: Copy of the current set of parameter values.""" return self._values.copy() @property def valid(self) -> bool: """bool: Whether or not this is a fully valid set of parameters.""" return self._validate_helper(raise_exceptions=False) @property def final(self) -> bool: """bool: Whethor or not this set of parameters is finalized.""" return self._finalized
[docs] def copy(self, deep: bool = False) -> Type['ParameterStore']: """Returns a copy of this parameter store object. Parameters ---------- deep : bool, optional Whether or not to do deep-copying of this stores contents. Returns ------- ParameterStore Copied parameter store object. """ new_obj = self.__class__() for k, v in self._params: new_obj.add(v) for k, v in self._values: new_obj[k] = v if self._finalized: new_obj.finalize() return new_obj
[docs] @state_changed def reset(self) -> None: """Clears all of the parameters and options stored.""" self._values.clear() self._params.clear()
[docs] @state_changed def add(self, parameter: Type[Parameter]) -> None: """Add a :class:`Parameter` specification to this store Parameters ---------- parameter : Parameter :class:`Parameter` specification to add to this parameter store. Raises ------ ParameterExistsError If a parameter option with the same name already exists. """ self._params[parameter.name] = parameter return
[docs] @state_changed def remove(self, name: str) -> Parameter: """Removes a :class:`Parameter` specification Parameters ---------- name : str Name of the :class:`Parameter` to remove. Returns ------- Parameter The removed :class:`Parameter` specified. Raises ------ KeyError If the given `name` does not exist. """ if name in self._values.keys(): del self._values[name] return self._params.pop(name)
[docs] def finalize(self) -> None: """Finalizes the parameters stored Raises ------ MissingParameterException If a required parameter is not set. """ if self._validate_helper(raise_exceptions=True): for k, v in self._params.items(): if k not in self._values.keys(): self._values[k] = v.default self._finalized = True return
def _validate_helper(self, raise_exceptions: bool = False) -> bool: """Helper to check if this set of parameters is valid""" for k, v in self._params.items(): if v.required and k not in self._values.keys(): if raise_exceptions: raise MissingParameterException(k) return False return True