diff --git a/CHANGES/1493.bugfix.rst b/CHANGES/1493.bugfix.rst new file mode 100644 index 00000000..386cdb71 --- /dev/null +++ b/CHANGES/1493.bugfix.rst @@ -0,0 +1 @@ +Fix handling of default empty string ("") in CallbackData filter diff --git a/aiogram/filters/callback_data.py b/aiogram/filters/callback_data.py index c60cd818..e504d50b 100644 --- a/aiogram/filters/callback_data.py +++ b/aiogram/filters/callback_data.py @@ -22,6 +22,7 @@ from uuid import UUID from magic_filter import MagicFilter from pydantic import BaseModel from pydantic.fields import FieldInfo +from pydantic_core import PydanticUndefined from aiogram.filters.base import Filter from aiogram.types import CallbackQuery @@ -130,8 +131,8 @@ class CallbackData(BaseModel): payload = {} for k, v in zip(names, parts): # type: str, Optional[str] if field := cls.model_fields.get(k): - if v == "" and _check_field_is_nullable(field): - v = None + if v == "" and _check_field_is_nullable(field) and field.default != "": + v = field.default if field.default is not PydanticUndefined else None payload[k] = v return cls(**payload) diff --git a/tests/test_filters/test_callback_data.py b/tests/test_filters/test_callback_data.py index 8cc2f51f..1bc50cae 100644 --- a/tests/test_filters/test_callback_data.py +++ b/tests/test_filters/test_callback_data.py @@ -160,6 +160,13 @@ class TestCallbackData: assert MyCallback3.unpack("test3:experiment:42") == MyCallback3(bar=42) assert MyCallback3.unpack("test3:spam:42") == MyCallback3(foo="spam", bar=42) + class MyCallback4(CallbackData, prefix="test4"): + foo: Optional[str] = "" + bar: Optional[str] = None + + assert MyCallback4.unpack("test4::") == MyCallback4(foo="", bar=None) + assert MyCallback4.unpack("test4::") == MyCallback4() + @pytest.mark.parametrize( "hint", [