pytex/PyTeX/format/config.py

108 lines
3.3 KiB
Python
Raw Normal View History

2022-02-08 19:01:18 +01:00
from __future__ import annotations
2022-02-07 17:32:46 +01:00
import json
from pathlib import Path
from typing import Dict, Optional, Union
import yaml
def clean_dict(dictionary: Dict) -> Optional[Dict]:
aux = {
k: clean_dict(v) for k, v in dictionary.items() if type(v) == dict
} | {
k: v for k, v in dictionary.items() if type(v) != dict
}
aux2 = {
k: v for k, v in aux.items() if v is not None
}
return aux2 if aux2 != {} else None
class Config:
2022-02-08 19:01:18 +01:00
def merge_with(self, other: Config, strict: bool = False):
2022-02-07 17:32:46 +01:00
"""
Merges the other config into this one
:param other:
:param strict: whether conflicting options are allowed or not
:return: self
"""
for var in vars(self):
if not getattr(self, var):
setattr(self, var, getattr(other, var))
else:
if strict and getattr(other, var) is not None and getattr(self, var) != getattr(other, var):
raise NotImplementedError
return self
@classmethod
def from_json(cls, content: Union[Path, Dict]):
if isinstance(content, Path):
2022-02-08 16:09:56 +01:00
with open(content, 'r') as file:
json_content: Dict = json.load(file)
else:
json_content = content
2022-02-07 17:32:46 +01:00
config = cls()
2022-02-08 16:09:56 +01:00
config.set_from_json(json_content)
2022-02-07 17:32:46 +01:00
return config
2022-02-08 16:34:59 +01:00
2022-02-07 17:32:46 +01:00
@classmethod
2022-02-08 16:34:59 +01:00
def from_yaml(cls, content: Union[Path, str]):
if isinstance(content, Path):
with open(content, 'r') as file:
json_content: Dict = yaml.safe_load(file)
else:
json_content = yaml.safe_load(content)
2022-02-08 16:09:56 +01:00
return cls.from_json(json_content)
2022-02-07 17:32:46 +01:00
def set_from_json(self, content: Optional[Dict]):
2022-02-07 17:32:46 +01:00
raise NotImplementedError
def to_json(self) -> Dict:
raise NotImplementedError
def dump_as_yaml(self, filename: Path, clean_none_entries: bool = True):
with filename.open('w') as file:
if clean_none_entries:
simple_dict = clean_dict(self.to_json())
else:
simple_dict = self.to_json()
if simple_dict is not None:
yaml.dump(simple_dict, file)
else:
pass # TODO
def dump_as_json(self, filename: Path, clean_none_entries: bool = True):
with open(filename, 'w') as config:
if clean_none_entries:
simple_dict = clean_dict(self.to_json())
else:
simple_dict = self.to_json()
if simple_dict is not None:
json.dump(simple_dict, config)
else:
pass # TODO
@classmethod
def _fill_keys(cls, dictionary: Optional[Dict]):
if dictionary is None:
return cls().to_json()
else:
return recursive_merge_dictionaries(
cls().to_json(),
dictionary
)
2022-02-07 17:32:46 +01:00
def recursive_merge_dictionaries(dict1: Dict, dict2: Dict) -> Dict:
aux1 = {
k: v for k, v in dict1.items() if type(v) == dict
}
aux2 = {
k: v for k, v in dict2.items() if type(v) == dict
}
merged = {
k: recursive_merge_dictionaries(v, aux2[k]) for k, v in aux1.items() if k in aux2.keys()
}
2022-02-07 18:36:30 +01:00
return dict1 | dict2 | merged