From: Aleš Mrázek Date: Mon, 16 Feb 2026 18:34:42 +0000 (+0100) Subject: python: modeling: added base class for custom types (BaseCustomType) X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f5f5c73bd44ca88ac5410f45b32b2c65fc2b2880;p=thirdparty%2Fknot-resolver.git python: modeling: added base class for custom types (BaseCustomType) --- diff --git a/python/knot_resolver/utils/modeling/types/base_custom_type.py b/python/knot_resolver/utils/modeling/types/base_custom_type.py new file mode 100644 index 000000000..d2fb6baf9 --- /dev/null +++ b/python/knot_resolver/utils/modeling/types/base_custom_type.py @@ -0,0 +1,96 @@ +from __future__ import annotations + +from abc import ABC, abstractmethod +from pathlib import Path +from typing import Any, TypeVar + +from knot_resolver.utils.modeling.context import Context, Strictness + +T = TypeVar("T") + +NoneType = type(None) + + +class BaseCustomType(ABC): + """ + Base class for custom types that just wraps the value. + + This class provides the basis for other custom types. + """ + + _is_valid: bool = False + + def __init__(self, value: Any, tree_path: str = "/", base_path: Path = Path()) -> None: + self._value = value + self._tree_path = tree_path + self._base_path = base_path + + def __repr__(self) -> str: + return f'{type(self).__name__}("{self._value!r}")' + + def __eq__(self, obj: object) -> bool: + if not isinstance(obj, type(self)): + return NotImplemented + return self._value == obj._value + + def __hash__(self) -> int: + return hash(self._value) + + def __str__(self) -> str: + return str(self._value) + + def __int__(self) -> int: + msg = f"int() not supported for {type(self).__name__}" + raise TypeError(msg) + + def __float__(self) -> float: + msg = f"float() not supported for {type(self).__name__}" + raise TypeError(msg) + + @abstractmethod + def _validate(self, context: Context) -> None: + """ + Validate data value wrapped by the custom type. + + All validation should be done here. + This method is automatically called during validation. + Subclasses must implement this method. + """ + + def validate(self, context: Context | None = None) -> None: + """ + Validate data value wrapped by the custom type. + + Args: + context (Context | None): + Optional, validation context for the validation operations, e.g. validation strictness + or username and groupname to check permissions on paths. + If set to None, Context() with defaults is used. + + Raises: + DataTypeError: When input data type validation fails. + DataValueError: When input data value validation fails. + DataValidationError: When some other input data validation fails. + + At least BASIC validation strictness is required + for the data value to be considered valid. + If validation is successful, no error is raised. + """ + + if context is None: + # use default context + context = Context() + + self._validate(context) + if context.strictness > Strictness.PERMISSIVE: + self._is_valid = True + + @classmethod + @abstractmethod + def json_schema(cls) -> dict[Any, Any]: + """ + Get JSON schema of the custom type. + + Returns: + JSON schema of the custom type in dictionary. + """