aiogram/aiogram/types/base.py
Alex Root Junior 04bd0c9e7c
Fixed error overlapping when validation error is caused by remove_unset root validator in base types and methods. (#1290)
* Ensure base type validation can handle non-dictionary values

The update introduces a condition to verify whether the values being validated are a dictionary before attempting to handle UNSET_TYPE in the aiogram base type. This adjustment helps to prevent potential errors or incorrect validation when non-dictionary values are faced.

* Added a test case for non-dictionary input in remove_unset method

* Added changelog

* Fixed tests
2023-08-29 02:01:54 +03:00

47 lines
1.6 KiB
Python

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.
"""
if not isinstance(values, dict):
return values
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)