Last active
September 14, 2022 19:28
-
-
Save kkirsche/444c38fa855ff8ec75649196a604f2ac to your computer and use it in GitHub Desktop.
TOML Path — A simple utility class to retrieve a specific key path in a TOML file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from os import PathLike | |
from functools import reduce | |
from operator import getitem | |
try: | |
# Python 3.11+ | |
from tomllib import load, loads | |
except ImportError: | |
from tomli import load, loads | |
from typing import Any, BinaryIO, Iterable, Mapping, TypeAlias, TypeGuard, Union | |
StrOrBytesPath: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes] | |
_Path: TypeAlias = str | |
_PathParts: TypeAlias = Iterable[_Path] | |
_PathOrParts: TypeAlias = _Path | _PathParts | |
def _path_guard(__o: object) -> TypeGuard[_Path]: | |
return isinstance(__o, str) | |
def _path_parts_guard(__o: object) -> TypeGuard[_PathParts]: | |
if not isinstance(__o, Iterable): | |
return False | |
return all(_path_guard(member) for member in __o) | |
class TOMLPath: | |
parts: tuple[str, ...] | |
def __init__(self, path_or_parts: _PathOrParts, separator: str = ".") -> None: | |
if _path_guard(path_or_parts): | |
self.parts = tuple(path_or_parts.split(separator)) | |
return | |
if _path_parts_guard(path_or_parts): | |
self.parts = tuple(path_or_parts) | |
return | |
raise ValueError( | |
"TOMLPath requires a path string or an iterable returning the path keys" | |
) | |
def get_from_file(self, path: StrOrBytesPath | int) -> Any: | |
with open(path, "rb") as fp: | |
return self.get(parsed=load(fp)) | |
def get_from_fp(self, file_pointer: BinaryIO) -> Any: | |
return self.get(parsed=load(file_pointer)) | |
def get_from_str(self, content: str) -> Any: | |
return self.get(parsed=loads(content)) | |
def get(self, parsed: Mapping[str, Any]) -> Any: | |
return reduce(getitem, self.parts, parsed) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment