confighelper: add support for conditionals
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
d51d65ef30
commit
5b4de64709
|
@ -15,6 +15,7 @@ from typing import (
|
||||||
Any,
|
Any,
|
||||||
Callable,
|
Callable,
|
||||||
IO,
|
IO,
|
||||||
|
Optional,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
Union,
|
Union,
|
||||||
Dict,
|
Dict,
|
||||||
|
@ -77,49 +78,92 @@ class ConfigHelper:
|
||||||
def _get_option(self,
|
def _get_option(self,
|
||||||
func: Callable[..., Any],
|
func: Callable[..., Any],
|
||||||
option: str,
|
option: str,
|
||||||
default: Union[SentinelClass, _T]
|
default: Union[SentinelClass, _T],
|
||||||
|
above: Optional[Union[int, float]] = None,
|
||||||
|
below: Optional[Union[int, float]] = None,
|
||||||
|
minval: Optional[Union[int, float]] = None,
|
||||||
|
maxval: Optional[Union[int, float]] = None
|
||||||
) -> _T:
|
) -> _T:
|
||||||
try:
|
try:
|
||||||
val = func(option, default)
|
val = func(self.section, option)
|
||||||
|
except configparser.NoOptionError:
|
||||||
|
if isinstance(default, SentinelClass):
|
||||||
|
raise ConfigError(
|
||||||
|
f"No option found ({option}) in section [{self.section}]"
|
||||||
|
) from None
|
||||||
|
return default
|
||||||
except Exception:
|
except Exception:
|
||||||
raise ConfigError(
|
raise ConfigError(
|
||||||
f"Error parsing option ({option}) from "
|
f"Error parsing option ({option}) from "
|
||||||
f"section [{self.section}]")
|
f"section [{self.section}]")
|
||||||
if isinstance(val, SentinelClass):
|
self._check_option(option, val, above, below, minval, maxval)
|
||||||
raise ConfigError(
|
|
||||||
f"No option found ({option}) in section [{self.section}]")
|
|
||||||
if self.section in self.orig_sections:
|
if self.section in self.orig_sections:
|
||||||
# Only track sections included in the original config
|
# Only track sections included in the original config
|
||||||
self.parsed[self.section][option] = val
|
self.parsed[self.section][option] = val
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
def _check_option(self,
|
||||||
|
option: str,
|
||||||
|
value: Union[int, float],
|
||||||
|
above: Optional[Union[int, float]],
|
||||||
|
below: Optional[Union[int, float]],
|
||||||
|
minval: Optional[Union[int, float]],
|
||||||
|
maxval: Optional[Union[int, float]]
|
||||||
|
) -> None:
|
||||||
|
if above is not None and value <= above:
|
||||||
|
raise self.error(
|
||||||
|
f"Config Error: Section [{self.section}], Option "
|
||||||
|
f"'{option}: {value}': value is not above {above}")
|
||||||
|
if below is not None and value >= below:
|
||||||
|
raise self.error(
|
||||||
|
f"Config Error: Section [{self.section}], Option "
|
||||||
|
f"'{option}: {value}': value is not below {below}")
|
||||||
|
if minval is not None and value < minval:
|
||||||
|
raise self.error(
|
||||||
|
f"Config Error: Section [{self.section}], Option "
|
||||||
|
f"'{option}: {value}': value is below minimum value {minval}")
|
||||||
|
if maxval is not None and value > maxval:
|
||||||
|
raise self.error(
|
||||||
|
f"Config Error: Section [{self.section}], Option "
|
||||||
|
f"'{option}: {value}': value is above maximum value {minval}")
|
||||||
|
|
||||||
def get(self,
|
def get(self,
|
||||||
option: str,
|
option: str,
|
||||||
default: Union[SentinelClass, _T] = SENTINEL
|
default: Union[SentinelClass, _T] = SENTINEL
|
||||||
) -> Union[str, _T]:
|
) -> Union[str, _T]:
|
||||||
return self._get_option(
|
return self._get_option(
|
||||||
self.config[self.section].get, option, default)
|
self.config.get, option, default)
|
||||||
|
|
||||||
def getint(self,
|
def getint(self,
|
||||||
option: str,
|
option: str,
|
||||||
default: Union[SentinelClass, _T] = SENTINEL
|
default: Union[SentinelClass, _T] = SENTINEL,
|
||||||
|
above: Optional[int] = None,
|
||||||
|
below: Optional[int] = None,
|
||||||
|
minval: Optional[int] = None,
|
||||||
|
maxval: Optional[int] = None
|
||||||
) -> Union[int, _T]:
|
) -> Union[int, _T]:
|
||||||
return self._get_option(
|
return self._get_option(
|
||||||
self.config[self.section].getint, option, default)
|
self.config.getint, option, default,
|
||||||
|
above, below, minval, maxval)
|
||||||
|
|
||||||
def getboolean(self,
|
def getboolean(self,
|
||||||
option: str,
|
option: str,
|
||||||
default: Union[SentinelClass, _T] = SENTINEL
|
default: Union[SentinelClass, _T] = SENTINEL
|
||||||
) -> Union[bool, _T]:
|
) -> Union[bool, _T]:
|
||||||
return self._get_option(
|
return self._get_option(
|
||||||
self.config[self.section].getboolean, option, default)
|
self.config.getboolean, option, default)
|
||||||
|
|
||||||
def getfloat(self,
|
def getfloat(self,
|
||||||
option: str,
|
option: str,
|
||||||
default: Union[SentinelClass, _T] = SENTINEL
|
default: Union[SentinelClass, _T] = SENTINEL,
|
||||||
|
above: Optional[float] = None,
|
||||||
|
below: Optional[float] = None,
|
||||||
|
minval: Optional[float] = None,
|
||||||
|
maxval: Optional[float] = None
|
||||||
) -> Union[float, _T]:
|
) -> Union[float, _T]:
|
||||||
return self._get_option(
|
return self._get_option(
|
||||||
self.config[self.section].getfloat, option, default)
|
self.config.getfloat, option, default,
|
||||||
|
above, below, minval, maxval)
|
||||||
|
|
||||||
def read_supplemental_config(self, file_name: str) -> ConfigHelper:
|
def read_supplemental_config(self, file_name: str) -> ConfigHelper:
|
||||||
cfg_file_path = os.path.normpath(os.path.expanduser(file_name))
|
cfg_file_path = os.path.normpath(os.path.expanduser(file_name))
|
||||||
|
|
Loading…
Reference in New Issue