Documented skeleton.py

pull/15/head
Jef Roosens 2021-04-25 18:10:37 +02:00
parent 6f8cb2e6f9
commit 3277af2ac5
Signed by: Jef Roosens
GPG Key ID: B580B976584B5F30
2 changed files with 51 additions and 8 deletions

View File

@ -1,21 +1,55 @@
"""Handles merging with the skeleton config."""
from typing import Dict
class InvalidKeyError(Exception):
def __init__(self, key):
"""Thrown when a config file contains an invalid key."""
def __init__(self, key: str):
"""
Create a new InvalidKeyError object with the given key.
Args:
key: the invalid key
"""
self.message = "Invalid key: {}".format(key)
super().__init__(key)
class MissingKeyError(Exception):
def __init__(self, key):
"""Thrown when a required key is missing from a config."""
def __init__(self, key: str):
"""
Create a new MissingKeyError object with the given key.
Args:
key: the invalid key
"""
self.message = "Missing key: {}".format(key)
super().__init__(key)
def merge(*dicts: [Dict]) -> Dict:
"""
Merge multiple dicts into one.
It reads the dicts from left to right, always preferring the "right"
dictionary's values. Therefore, the dictionaries should be sorted from
least important to most important (e.g. a default values skeleton should be
to the left of a dict of selected values).
Args:
dicts: the dictionaries to merge
Returns:
a new dictionary representing the merged dictionaries
Todo:
* Make sure an infinite loop is not possible
"""
# Base cases
if len(dicts) == 0:
return {}
@ -45,10 +79,20 @@ def merge(*dicts: [Dict]) -> Dict:
def merge_with_skeleton(data: Dict, skel: Dict) -> Dict:
"""
Compare a dict with a given skeleton dict, and fill in default values where
needed.
"""
Merge a dictionary with a skeleton containing default values.
The skeleton not only defines what the default values are, but also
enforces a certain shape. This allows us to define a config file using a
dictionary and parse it.
Args:
data: dictionary containing the selected config values
skel: dictionary containing the skeleton (aka the def)
Todo:
* Check if an infinite loop is possible
* Split info less complex functions
"""
# First, check for illegal keys
for key in data:
if key not in skel:
@ -66,6 +110,7 @@ def merge_with_skeleton(data: Dict, skel: Dict) -> Dict:
# Error if value is not same type as default value
elif type(data[key]) != type(value) and value is not None:
# TODO make this error message more verbose
raise TypeError("Invalid value type")
# Recurse into dicts

View File

@ -6,9 +6,7 @@ from datetime import datetime
class DirectorySpec(Spec):
"""
A spec for backing up a local directory.
"""
"""A spec for backing up a local directory."""
_SKEL = {
"source": None,