from functools import cache from pathlib import Path from typing import Any, Iterator from yaml import Loader, load class Content: def __init__(self, path: Path) -> None: self.__path = path @property def path(self) -> Path: return self.__path class ContentDirectory(Content): def load(self, subpath: Path) -> Content: current: Content = self for part in subpath.parts: if not isinstance(current, ContentDirectory): raise NotADirectoryError(self.path) current = current.__load_children(part) return current @cache # noqa: B019 def __load_children(self, name: str) -> Content: child_path = self.path / name if not child_path.exists(): raise FileNotFoundError(child_path) if child_path.is_dir(): return ContentDirectory(child_path) if child_path.is_file() and child_path.suffix in [".yml", ".yaml", ".json"]: return DataFile(child_path) raise NotImplementedError() class DataFile(Content): def __init__(self, path: Path) -> None: super().__init__(path) with path.open("r", encoding="utf-8") as data_file: self.__data = load(data_file, Loader) def __getitem__(self, key: Any) -> Any: return self.__data.get(key) def __iter__(self) -> Iterator[Any]: yield from self.__data