Skip to content

Instantly share code, notes, and snippets.

@kkirsche
Last active September 14, 2022 19:28
Show Gist options
  • Save kkirsche/444c38fa855ff8ec75649196a604f2ac to your computer and use it in GitHub Desktop.
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
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