53 lines
1.8 KiB
Python
53 lines
1.8 KiB
Python
|
# Copyright (c) 2016-2022 Adam Karpierz
|
||
|
# Licensed under the zlib/libpng License
|
||
|
# https://opensource.org/licenses/Zlib
|
||
|
|
||
|
__all__ = ('make_config',)
|
||
|
|
||
|
|
||
|
def make_config(cfg_fname, cfg_section=None):
|
||
|
import sys
|
||
|
from pathlib import Path
|
||
|
from functools import partial
|
||
|
fglobals = sys._getframe(1).f_globals
|
||
|
fglobals.pop("__builtins__", None)
|
||
|
fglobals.pop("__cached__", None)
|
||
|
if cfg_section is None: cfg_section = fglobals["__package__"]
|
||
|
cfg_path = Path(fglobals["__file__"]).parent/cfg_fname
|
||
|
fglobals["__all__"] = ("config", "set_config")
|
||
|
fglobals["config"] = get_config(cfg_path, cfg_section)
|
||
|
fglobals["set_config"] = partial(set_config, fglobals)
|
||
|
|
||
|
|
||
|
def get_config(cfg_path, cfg_section):
|
||
|
from pathlib import Path
|
||
|
from configparser import ConfigParser, ExtendedInterpolation
|
||
|
cfg_path = Path(cfg_path)
|
||
|
if not cfg_path.is_file():
|
||
|
return {}
|
||
|
cfg = ConfigParser(interpolation=ExtendedInterpolation(),
|
||
|
inline_comment_prefixes=('#', ';'),
|
||
|
default_section=cfg_section)
|
||
|
cfg.read(str(cfg_path), "utf-8")
|
||
|
return cfg[cfg_section]
|
||
|
|
||
|
|
||
|
def set_config(fglobals, **cfg_dict):
|
||
|
import sys
|
||
|
import importlib
|
||
|
# Update config
|
||
|
to_update = {key: str(val) for key, val in cfg_dict.items()
|
||
|
if val is not None}
|
||
|
to_remove = {key for key, val in cfg_dict.items() if val is None}
|
||
|
package_name = fglobals["__package__"]
|
||
|
config_name = package_name + ".__config__"
|
||
|
config = sys.modules[config_name].config
|
||
|
config.update(to_update)
|
||
|
for key in to_remove: config.pop(key, None)
|
||
|
# Reload
|
||
|
for mod_name in tuple(sys.modules):
|
||
|
if (mod_name.startswith(package_name + ".")
|
||
|
and mod_name != config_name): # noqa: E129
|
||
|
del sys.modules[mod_name]
|
||
|
importlib.reload(sys.modules[package_name])
|