|
@@ -1,3 +1,4 @@
|
|
|
|
+import datetime # pylint: disable=unused-import; doctest
|
|
import pathlib
|
|
import pathlib
|
|
import typing
|
|
import typing
|
|
|
|
|
|
@@ -6,7 +7,7 @@ import yaml
|
|
from yamily import Person
|
|
from yamily import Person
|
|
|
|
|
|
|
|
|
|
-class _YamlLoader(yaml.SafeLoader):
|
|
|
|
|
|
+class _Loader(yaml.SafeLoader):
|
|
|
|
|
|
# pylint: disable=too-many-ancestors
|
|
# pylint: disable=too-many-ancestors
|
|
|
|
|
|
@@ -15,9 +16,7 @@ class _YamlLoader(yaml.SafeLoader):
|
|
self.add_constructor("!person", self._construct_person)
|
|
self.add_constructor("!person", self._construct_person)
|
|
|
|
|
|
@staticmethod
|
|
@staticmethod
|
|
- def _construct_person(
|
|
|
|
- loader: "_YamlLoader", node: yaml.nodes.MappingNode
|
|
|
|
- ) -> Person:
|
|
|
|
|
|
+ def _construct_person(loader: "_Loader", node: yaml.nodes.MappingNode) -> Person:
|
|
(person_attrs,) = loader.construct_yaml_map(node)
|
|
(person_attrs,) = loader.construct_yaml_map(node)
|
|
person = Person(person_attrs["identifier"])
|
|
person = Person(person_attrs["identifier"])
|
|
if "name" in person_attrs:
|
|
if "name" in person_attrs:
|
|
@@ -31,6 +30,52 @@ class _YamlLoader(yaml.SafeLoader):
|
|
return person
|
|
return person
|
|
|
|
|
|
|
|
|
|
|
|
+class Dumper(yaml.SafeDumper):
|
|
|
|
+
|
|
|
|
+ """
|
|
|
|
+ >>> p = Person('alice')
|
|
|
|
+ >>> p.name = 'Alice'
|
|
|
|
+ >>> p.birth_date = datetime.date(1976, 2, 1)
|
|
|
|
+ >>> print(yaml.dump(p, Dumper=Dumper))
|
|
|
|
+ !person
|
|
|
|
+ birth_date: 1976-02-01
|
|
|
|
+ identifier: alice
|
|
|
|
+ name: Alice
|
|
|
|
+ <BLANKLINE>
|
|
|
|
+
|
|
|
|
+ >>> p = Person('bob')
|
|
|
|
+ >>> p.mother = Person('bob-mum')
|
|
|
|
+ >>> p.father = Person('bob-father')
|
|
|
|
+ >>> print(yaml.dump(p, Dumper=Dumper))
|
|
|
|
+ !person
|
|
|
|
+ father: !person
|
|
|
|
+ identifier: bob-father
|
|
|
|
+ identifier: bob
|
|
|
|
+ mother: !person
|
|
|
|
+ identifier: bob-mum
|
|
|
|
+ <BLANKLINE>
|
|
|
|
+ """
|
|
|
|
+
|
|
|
|
+ # pylint: disable=too-many-ancestors
|
|
|
|
+
|
|
|
|
+ def __init__(self, stream, **kwargs):
|
|
|
|
+ super().__init__(stream, **kwargs)
|
|
|
|
+ self.add_representer(Person, self._represent_person)
|
|
|
|
+
|
|
|
|
+ @staticmethod
|
|
|
|
+ def _represent_person(dumper: "_Dumper", person: Person) -> yaml.nodes.MappingNode:
|
|
|
|
+ person_attrs = {"identifier": person.identifier}
|
|
|
|
+ if person.name is not None:
|
|
|
|
+ person_attrs["name"] = person.name
|
|
|
|
+ if person.birth_date is not None:
|
|
|
|
+ person_attrs["birth_date"] = person.birth_date
|
|
|
|
+ if person.mother is not None:
|
|
|
|
+ person_attrs["mother"] = person.mother
|
|
|
|
+ if person.father is not None:
|
|
|
|
+ person_attrs["father"] = person.father
|
|
|
|
+ return dumper.represent_mapping("!person", person_attrs)
|
|
|
|
+
|
|
|
|
+
|
|
def read(yaml_path: typing.Union[str, pathlib.Path]) -> Person:
|
|
def read(yaml_path: typing.Union[str, pathlib.Path]) -> Person:
|
|
"""
|
|
"""
|
|
>>> read('persons/erika-mustermann.yml')
|
|
>>> read('persons/erika-mustermann.yml')
|
|
@@ -46,4 +91,4 @@ def read(yaml_path: typing.Union[str, pathlib.Path]) -> Person:
|
|
if isinstance(yaml_path, str):
|
|
if isinstance(yaml_path, str):
|
|
return read(pathlib.Path(yaml_path))
|
|
return read(pathlib.Path(yaml_path))
|
|
with yaml_path.open("r") as yaml_file:
|
|
with yaml_path.open("r") as yaml_file:
|
|
- return yaml.load(yaml_file, Loader=_YamlLoader)
|
|
|
|
|
|
+ return yaml.load(yaml_file, Loader=_Loader)
|