From 7f5fef185348d93640303565da778efc43b176c4 Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Sat, 29 Jul 2023 23:58:13 +0300 Subject: [PATCH] Add model validation to remove UNSET before field validation Updated aiogram/types/base.py to include a model validator which removes any 'UNSET' before field validation. This change was necessary to correctly handle `parse_mode` where 'UNSET' is used as a sentinel value. Without the removal of 'UNSET', it would create issues when passed to model initialization from `Bot.method_name`. 'UNSET' was also added to typing. Tiny documentation fix was made. --- aiogram/types/base.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/aiogram/types/base.py b/aiogram/types/base.py index 641b16df..9c24c703 100644 --- a/aiogram/types/base.py +++ b/aiogram/types/base.py @@ -1,7 +1,7 @@ -from typing import Any +from typing import Any, Dict from unittest.mock import sentinel -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, model_validator from aiogram.client.context_controller import BotContextController @@ -17,6 +17,19 @@ class TelegramObject(BotContextController, BaseModel): 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( @@ -24,7 +37,7 @@ class MutableTelegramObject(TelegramObject): ) -# special sentinel object which used in situation when None might be a useful value +# 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