Skip to content

Commit

Permalink
improvements to Config
Browse files Browse the repository at this point in the history
  • Loading branch information
edublancas committed Apr 18, 2022
1 parent 1f8e374 commit 0fe72db
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
19 changes: 16 additions & 3 deletions src/ploomber/config.py
@@ -1,3 +1,4 @@
import warnings
import abc
from collections.abc import Mapping

Expand All @@ -6,6 +7,8 @@

class Config(abc.ABC):
def __init__(self):
self._init_values()

# resolve home directory
path = self.path()

Expand All @@ -19,13 +22,13 @@ def __init__(self):
try:
content = yaml.safe_load(text)
loaded = True
except Exception:
# NOTE: show warning?
except Exception as e:
warnings.warn(str(e))
loaded = False
content = self._get_data()

if loaded and not isinstance(content, Mapping):
# NOTE: show warning?
warnings.warn('YAMl not a mapping')
content = self._get_data()

self._set_data(content)
Expand All @@ -42,6 +45,16 @@ def _set_data(self, data):
if key in data:
setattr(self, key, data[key])

def _init_values(self):
for key in self.__annotations__:
name = f'{key}_default'
if hasattr(self, name):
value = getattr(self, name)()
# call __setattr__ on the superclass so we skip the part
# where we overwrite the YAML file, here we only want to
# set the default values
super().__setattr__(key, value)

def _write(self):
path = self.path()
data = self._get_data()
Expand Down
31 changes: 31 additions & 0 deletions tests/test_config.py
Expand Up @@ -14,6 +14,17 @@ def path(self):
return Path('myconfig.yaml')


class AnotherConfig(Config):
uuid: str
another: str = 'default'

def path(self):
return Path('another.yaml')

def uuid_default(self):
return 'some-value'


def test_stores_defaults(tmp_directory):
MyConfig()

Expand Down Expand Up @@ -78,3 +89,23 @@ def test_uses_defaults_if_corrupted(tmp_directory, content):
assert cfg.number == 42
assert cfg.string == 'value'
assert content == {'number': 42, 'string': 'value'}


def test_config_with_factory(tmp_directory):
cfg = AnotherConfig()

assert cfg.uuid == 'some-value'
assert cfg.another == 'default'


def test_factory_keeps_existing_values(tmp_directory):
path = Path('another.yaml')
values = {'uuid': 'my-uuid', 'another': 'some-value'}
path.write_text(yaml.dump(values))

cfg = AnotherConfig()
content = yaml.safe_load(Path('another.yaml').read_text())

assert cfg.uuid == 'my-uuid'
assert cfg.another == 'some-value'
assert content == values

0 comments on commit 0fe72db

Please sign in to comment.