Source code for pyjob.config

import logging
import os
import sys
from collections import UserDict
from functools import wraps

import yaml
from pyjob.exception import DictLockedError

logger = logging.getLogger(__name__)


[docs]class ImmutableDictMixin(object): _locked = False
[docs] def lock(self): self._locked = True
[docs] def unlock(self): self._locked = False
[docs] @staticmethod def assert_lock(fn): @wraps(fn) def wrapper(self, *args, **kwargs): if self._locked: raise DictLockedError("Dictionary locked, cannot override value") return fn(self, *args, **kwargs) return wrapper
[docs]class PyJobConfig(UserDict, ImmutableDictMixin): _directory = os.path.expanduser("~/.pyjob") if not os.path.isdir(_directory): try: os.makedirs(_directory) except OSError as e: if e.errno == errno.EEXIST and os.path.isdir(_directory): pass else: raise RuntimeError("Cannot create configuration directory") file = os.path.join(_directory, "pyjob.yml") if not os.path.isfile(file): open(file, "w").close() @ImmutableDictMixin.assert_lock def __setitem__(self, key, value): super().__setitem__(key, value)
[docs] @ImmutableDictMixin.assert_lock def setdefault(self, key, value=None): super().setdefault(key, value=value) self.write()
[docs] @ImmutableDictMixin.assert_lock def update(self, *args, **kwargs): super().update(*args, **kwargs)
[docs] def write(self): data = yaml.dump(dict(self), default_flow_style=False) with open(self.file, "w") as f: f.write(data)
[docs] @staticmethod def read_yaml(yamlf): """Read a YAML file Parameters ---------- yamlf : str The path to a PyJob YAML config file Returns ------- :obj:`~pyjob.config.PyJobConfig` A :obj:`~pyjob.config.PyJobConfig` instance Raises ------ :exc:`FileNotFoundError` Cannot find YAML file """ if not os.path.isfile(yamlf): raise FileNotFoundError("Cannot find YAML file") with open(yamlf, "r") as f: data = yaml.safe_load(f) data = data or {} config = PyJobConfig(**data) config.dir = os.path.dirname(yamlf) config.file = yamlf return config
[docs] @classmethod def from_default(cls): """Construct the configuration from the default file Returns ------- :obj:`~pyjob.config.PyJobConfig` A :obj:`~pyjob.config.PyJobConfig` instance """ return PyJobConfig.read_yaml(cls.file)