78 lines
2.3 KiB
Python
78 lines
2.3 KiB
Python
"""
|
|
Utility functions for reading and writing toml files.
|
|
|
|
Handles module imports for all supported versions (in a build root or on a host).
|
|
"""
|
|
import importlib
|
|
from types import ModuleType
|
|
from typing import Optional
|
|
|
|
# Different modules require different file mode (text vs binary)
|
|
_toml_modules = {
|
|
"tomllib": {"mode": "rb"}, # stdlib since 3.11 (read-only)
|
|
"tomli": {"mode": "rb"}, # EL9+
|
|
"toml": {"mode": "r", "encoding": "utf-8"}, # older unmaintained lib, needed for backwards compatibility
|
|
"pytoml": {"mode": "r", "encoding": "utf-8"}, # deprecated, needed for backwards compatibility (EL8 manifests)
|
|
}
|
|
|
|
|
|
_toml: Optional[ModuleType] = None
|
|
_rargs: dict = {}
|
|
for module, args in _toml_modules.items():
|
|
try:
|
|
_toml = importlib.import_module(module)
|
|
_rargs = args
|
|
break
|
|
except ModuleNotFoundError:
|
|
pass
|
|
else:
|
|
raise ModuleNotFoundError("No toml module found: " + ", ".join(_toml_modules))
|
|
|
|
# Different modules require different file mode (text vs binary)
|
|
_tomlw_modules = {
|
|
"tomli_w": {"mode": "wb"}, # EL9+
|
|
"toml": {"mode": "w", "encoding": "utf-8"}, # older unmaintained lib, needed for backwards compatibility
|
|
"pytoml": {"mode": "w", "encoding": "utf-8"}, # deprecated, needed for backwards compatibility (EL8 manifests)
|
|
}
|
|
|
|
|
|
_tomlw: Optional[ModuleType] = None
|
|
_wargs: dict = {}
|
|
for module, args in _tomlw_modules.items():
|
|
try:
|
|
_tomlw = importlib.import_module(module)
|
|
_wargs = args
|
|
break
|
|
except ModuleNotFoundError:
|
|
# allow importing without write support
|
|
pass
|
|
|
|
|
|
def load_from_file(path):
|
|
if _toml is None:
|
|
raise RuntimeError("no toml module available")
|
|
|
|
with open(path, **_rargs) as tomlfile: # pylint: disable=unspecified-encoding
|
|
return _toml.load(tomlfile)
|
|
|
|
|
|
def dump_to_file(data, path, header=""):
|
|
if _tomlw is None:
|
|
raise RuntimeError("no toml module available with write support")
|
|
|
|
with open(path, **_wargs) as tomlfile: # pylint: disable=unspecified-encoding
|
|
if header:
|
|
_write_comment(tomlfile, header)
|
|
|
|
_tomlw.dump(data, tomlfile)
|
|
|
|
|
|
def _write_comment(f, comment: list):
|
|
if not comment:
|
|
return
|
|
|
|
data = "\n".join(map(lambda c: f"# {c}", comment)) + "\n\n"
|
|
if "b" in f.mode:
|
|
f.write(data.encode())
|
|
else:
|
|
f.write(data)
|