from typing import Any, Dict from unittest.mock import sentinel from pydantic import BaseModel, ConfigDict, model_validator from aiogram.client.context_controller import BotContextController class TelegramObject(BotContextController, BaseModel): model_config = ConfigDict( use_enum_values=True, extra="allow", validate_assignment=True, frozen=True, populate_by_name=True, arbitrary_types_allowed=True, defer_build=True, ) @model_validator(mode="before") @classmethod def remove_unset(cls, values: Dict[str, Any]) -> Dict[str, Any]: """ Remove UNSET before fields validation. We use UNSET as a sentinel value for `parse_mode` and replace it to real value later. It isn't a problem when it's just default value for a model field, but UNSET might be passed to a model initialization from `Bot.method_name`, so we must take care of it and remove it before fields validation. """ return {k: v for k, v in values.items() if not isinstance(v, UNSET_TYPE)} class MutableTelegramObject(TelegramObject): model_config = ConfigDict( frozen=False, ) # special sentinel object which used in a situation when None might be a useful value UNSET: Any = sentinel.UNSET UNSET_PARSE_MODE: Any = sentinel.UNSET_PARSE_MODE UNSET_DISABLE_WEB_PAGE_PREVIEW: Any = sentinel.UNSET_DISABLE_WEB_PAGE_PREVIEW UNSET_PROTECT_CONTENT: Any = sentinel.UNSET_PROTECT_CONTENT UNSET_TYPE: Any = type(UNSET)