mirror of
https://github.com/ChristianLight/tutor.git
synced 2024-06-14 11:32:20 +00:00
336cb79fa8
I stumbled upon a bug that should have been detected by the type checking. Turns out, considering that config is of type Dict[str, Any] means that we can use just any method on all config values -- which is terrible. I discovered this after I set `config["PLUGINS"] = None`: this triggered a crash when I enabled a plugin. We resolve this by making the Config type more explicit. We also take the opportunity to remove a few cast statements.
40 lines
1.1 KiB
Python
40 lines
1.1 KiB
Python
from typing import Any, Dict, List, Optional, Type, TypeVar, Union
|
|
|
|
from . import exceptions
|
|
|
|
ConfigValue = Union[
|
|
str, float, None, bool, List[str], List[Any], Dict[str, Any], Dict[Any, Any]
|
|
]
|
|
Config = Dict[str, ConfigValue]
|
|
|
|
|
|
def cast_config(config: Any) -> Config:
|
|
if not isinstance(config, dict):
|
|
raise exceptions.TutorError(
|
|
"Invalid configuration: expected dict, got {}".format(config.__class__)
|
|
)
|
|
for key in config.keys():
|
|
if not isinstance(key, str):
|
|
raise exceptions.TutorError(
|
|
"Invalid configuration: expected str, got {} for key '{}'".format(
|
|
key.__class__, key
|
|
)
|
|
)
|
|
return config
|
|
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
def get_typed(
|
|
config: Config, key: str, expected_type: Type[T], default: Optional[T] = None
|
|
) -> T:
|
|
value = config.get(key, default)
|
|
if not isinstance(value, expected_type):
|
|
raise exceptions.TutorError(
|
|
"Invalid config entry: expected {}, got {} for key '{}'".format(
|
|
expected_type.__name__, value.__class__, key
|
|
)
|
|
)
|
|
return value
|