docstrings, simplify dict validator
This commit is contained in:
parent
3eca67101b
commit
16cba13570
2 changed files with 80 additions and 25 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Type
|
from typing import Type
|
||||||
from typing import TypeVar
|
from typing import TypeVar
|
||||||
|
|
@ -7,18 +8,20 @@ from ytdl_subscribe.validators.exceptions import ValidationException
|
||||||
|
|
||||||
|
|
||||||
class Validator:
|
class Validator:
|
||||||
|
"""
|
||||||
|
Abstract class used to validate any kind of field. Will ensure the value is the specified type.
|
||||||
|
"""
|
||||||
|
|
||||||
# The python type that value should be
|
# The python type that value should be
|
||||||
expected_value_type: Type = object
|
expected_value_type: Type = object
|
||||||
|
|
||||||
# When raising an error, call the type this value instead of its python name
|
# When raising an error, call the type this value instead of its python name
|
||||||
expected_value_type_name: Optional[str] = None
|
expected_value_type_name: Optional[str] = None
|
||||||
|
|
||||||
def __validate_value(self):
|
def __init__(self, name: str, value: Any):
|
||||||
"""
|
self.name = name
|
||||||
Returns
|
self._value = value
|
||||||
-------
|
|
||||||
Validation exception to raise when the value's type is not the expected type
|
|
||||||
"""
|
|
||||||
if not isinstance(self._value, self.expected_value_type):
|
if not isinstance(self._value, self.expected_value_type):
|
||||||
expected_value_type_name = self.expected_value_type_name or str(
|
expected_value_type_name = self.expected_value_type_name or str(
|
||||||
self.expected_value_type
|
self.expected_value_type
|
||||||
|
|
@ -27,36 +30,63 @@ class Validator:
|
||||||
error_message=f"should be of type {expected_value_type_name}."
|
error_message=f"should be of type {expected_value_type_name}."
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, name: str, value: Any):
|
|
||||||
self.name = name
|
|
||||||
self._value = value
|
|
||||||
|
|
||||||
self.__validate_value()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self) -> object:
|
def value(self) -> object:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Value of the validator
|
||||||
|
"""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
def _validation_exception(self, error_message: str):
|
def _validation_exception(self, error_message: str) -> ValidationException:
|
||||||
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
error_message
|
||||||
|
Error message to include in the ValidationException
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Validation exception with a consistent prefix.
|
||||||
|
"""
|
||||||
prefix = f"Validation error in {self.name}: "
|
prefix = f"Validation error in {self.name}: "
|
||||||
return ValidationException(f"{prefix}{error_message}")
|
return ValidationException(f"{prefix}{error_message}")
|
||||||
|
|
||||||
|
|
||||||
class BoolValidator(Validator):
|
class BoolValidator(Validator):
|
||||||
|
"""
|
||||||
|
Validates boolean fields.
|
||||||
|
"""
|
||||||
|
|
||||||
expected_value_type: Type = bool
|
expected_value_type: Type = bool
|
||||||
expected_value_type_name = "boolean"
|
expected_value_type_name = "boolean"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self) -> bool:
|
def value(self) -> bool:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Boolean value
|
||||||
|
"""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
|
|
||||||
class StringValidator(Validator):
|
class StringValidator(Validator):
|
||||||
|
"""
|
||||||
|
Validates string fields.
|
||||||
|
"""
|
||||||
|
|
||||||
expected_value_type: Type = str
|
expected_value_type: Type = str
|
||||||
expected_value_type_name = "string"
|
expected_value_type_name = "string"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self) -> str:
|
def value(self) -> str:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
String value
|
||||||
|
"""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -64,24 +94,49 @@ T = TypeVar("T", bound=Validator)
|
||||||
|
|
||||||
|
|
||||||
class DictValidator(Validator):
|
class DictValidator(Validator):
|
||||||
|
"""
|
||||||
|
Validates dictionary-based fields. Errors to them as 'object's since this could be validating a yaml.
|
||||||
|
"""
|
||||||
|
|
||||||
expected_value_type = dict
|
expected_value_type = dict
|
||||||
expected_value_type_name = "object" # for non-python users
|
expected_value_type_name = "object"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dict(self) -> dict:
|
def dict(self) -> dict:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Dictionary value
|
||||||
|
"""
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def keys(self):
|
def keys(self) -> List[str]:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Sorted list of dictionary keys
|
||||||
|
"""
|
||||||
return sorted(list(self.dict.keys()))
|
return sorted(list(self.dict.keys()))
|
||||||
|
|
||||||
def get(self, key: str, default: Optional[Any] = None) -> Any:
|
|
||||||
return self.dict.get(key, default)
|
|
||||||
|
|
||||||
def validate_key(
|
def validate_key(
|
||||||
self, key: str, validator: Type[T], default: Optional[Any] = None
|
self, key: str, validator: Type[T], default: Optional[Any] = None
|
||||||
) -> T:
|
) -> T:
|
||||||
value = self.get(key=key, default=default)
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
key
|
||||||
|
Name of they key in the dict to validate
|
||||||
|
validator
|
||||||
|
The validator to use for the key's value
|
||||||
|
default
|
||||||
|
If the key's value is None, use this as the default
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
An instance of the specified validator
|
||||||
|
"""
|
||||||
|
value = self.dict.get(key, default)
|
||||||
if value is None:
|
if value is None:
|
||||||
raise self._validation_exception(
|
raise self._validation_exception(
|
||||||
f"{key} is missing when it should be present."
|
f"{key} is missing when it should be present."
|
||||||
|
|
@ -89,5 +144,5 @@ class DictValidator(Validator):
|
||||||
|
|
||||||
return validator(
|
return validator(
|
||||||
name=f"{self.name}.{key}",
|
name=f"{self.name}.{key}",
|
||||||
value=self.get(key=key, default=default),
|
value=value,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -67,11 +67,11 @@ class SubscriptionValidator(StrictDictValidator):
|
||||||
|
|
||||||
return subscription_class(
|
return subscription_class(
|
||||||
name=self.name,
|
name=self.name,
|
||||||
options=self.preset.get(self.preset.subscription_source_name),
|
options=self.preset.dict.get(self.preset.subscription_source_name),
|
||||||
ytdl_opts=self.preset.get("ytdl_options"),
|
ytdl_opts=self.preset.dict.get("ytdl_options"),
|
||||||
post_process=self.preset.get("post_process"),
|
post_process=self.preset.dict.get("post_process"),
|
||||||
overrides=self.preset.get("overrides"),
|
overrides=self.preset.dict.get("overrides"),
|
||||||
output_path=self.preset.get("output_path"),
|
output_path=self.preset.dict.get("output_path"),
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue