yaml.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import pathlib
  2. import typing
  3. import yaml
  4. from yamily import Person
  5. class _YamlLoader(yaml.SafeLoader):
  6. # pylint: disable=too-many-ancestors
  7. def __init__(self, stream):
  8. super().__init__(stream)
  9. self.add_constructor("!person", self._construct_person)
  10. @staticmethod
  11. def _construct_person(
  12. loader: "_YamlLoader", node: yaml.nodes.MappingNode
  13. ) -> Person:
  14. (person_attrs,) = loader.construct_yaml_map(node)
  15. person = Person(person_attrs["identifier"])
  16. if "name" in person_attrs:
  17. person.name = person_attrs["name"]
  18. if "birth_date" in person_attrs:
  19. person.birth_date = person_attrs["birth_date"]
  20. if "mother" in person_attrs:
  21. person.mother = Person(person_attrs["mother"])
  22. if "father" in person_attrs:
  23. person.father = Person(person_attrs["father"])
  24. return person
  25. def read(yaml_path: typing.Union[str, pathlib.Path]) -> Person:
  26. """
  27. >>> read('persons/erika-mustermann.yml')
  28. Person(erika-mustermann, Erika Mustermann, *1957-08-12)
  29. >>> maxl = read('persons/max-mustermann.yml')
  30. >>> maxl
  31. Person(max-mustermann, Max Mustermann, *1976-02-01)
  32. >>> maxl.mother
  33. Person(erika-mustermann)
  34. >>> maxl.father
  35. Person(thomas-mustermann)
  36. """
  37. if isinstance(yaml_path, str):
  38. return read(pathlib.Path(yaml_path))
  39. with yaml_path.open("r") as yaml_file:
  40. return yaml.load(yaml_file, Loader=_YamlLoader)