Source code for picometer.settings

from collections import UserDict
from dataclasses import asdict, dataclass, fields, Field
from importlib import resources
import logging
from typing import Union

import yaml


logger = logging.getLogger(__name__)


[docs] class SettingsError(KeyError): """Custom `KeyError` raised when there are issues with `DefaultSettings`"""
[docs] @dataclass class DefaultSettings: """Store default values of all settings. Use `AnyValue` if no default.""" auto_write_unit_cell: bool = True clear_selection_after_use: bool = True displacement_get_cartesian_eigenvalues: bool = False complete_uiso_from_umatrix: bool = False complete_umatrix_from_uiso: bool = False
[docs] @classmethod def get_field(cls, key: str) -> Field: if fields_ := [f for f in fields(cls) if f.name == key]: # noqa return fields_[0] raise SettingsError(f'Unknown setting name {key!r}')
[docs] class Settings(UserDict): """Automatically set self from `DefaultSettings` on init, handle settings"""
[docs] @classmethod def from_yaml(cls, path=None) -> 'Settings': settings_stream = open(path, 'r') if path \ else resources.open_text('picometer', 'settings.yaml') with settings_stream: return cls(yaml.safe_load(settings_stream)['settings'])
def __init__(self, data: dict = None) -> None: super().__init__(asdict(DefaultSettings())) # noqa if data: self.update(data) logger.debug(f'Initialized {self}')
[docs] def __setitem__(self, key, value, /) -> None: field = DefaultSettings.get_field(key) super().__setitem__(key, value := field.type(value)) logger.debug(f'Changed setting {key} to {value}')
[docs] def __delitem__(self, key, /) -> None: field = DefaultSettings.get_field(key) super().__setitem__(key, default := field.default) logger.debug(f'Reset setting {key} to {default}')
[docs] def update(self, other: Union[dict, UserDict] = None, /, **kwargs) -> None: other = {**other, **kwargs} if other else kwargs for key, value in other.items(): self[key] = value