From 408b9362eb6d1aa51f2e644142294da522657c44 Mon Sep 17 00:00:00 2001 From: Vadim Fedorov Date: Fri, 28 Mar 2025 11:56:43 +0100 Subject: [PATCH 1/3] Make CallbackData prefix optional and dafault to class name --- aiogram/filters/callback_data.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/aiogram/filters/callback_data.py b/aiogram/filters/callback_data.py index e504d50b..3cd1c369 100644 --- a/aiogram/filters/callback_data.py +++ b/aiogram/filters/callback_data.py @@ -47,24 +47,26 @@ class CallbackData(BaseModel): This class should be used as super-class of user-defined callbacks. - The class-keyword :code:`prefix` is required to define prefix - and also the argument :code:`sep` can be passed to define separator (default is :code:`:`). + An optional class-keyword :code:`prefix` can be passed to define prefix. + If no prefix is provided, the class name will be used as the prefix. + + An optional argument :code:`sep` can be passed to define the separator + (default is :code:`:`). """ if TYPE_CHECKING: __separator__: ClassVar[str] """Data separator (default is :code:`:`)""" __prefix__: ClassVar[str] - """Callback prefix""" + """Callback prefix (default is class name)""" def __init_subclass__(cls, **kwargs: Any) -> None: - if "prefix" not in kwargs: - raise ValueError( - f"prefix required, usage example: " - f"`class {cls.__name__}(CallbackData, prefix='my_callback'): ...`" - ) + # If no prefix is provided explicitly, default to the class name + prefix = kwargs.pop("prefix", None) + if prefix is None: + prefix = cls.__name__ cls.__separator__ = kwargs.pop("sep", ":") - cls.__prefix__ = kwargs.pop("prefix") + cls.__prefix__ = prefix if cls.__separator__ in cls.__prefix__: raise ValueError( f"Separator symbol {cls.__separator__!r} can not be used " From 4f95c68ef540ff32a30f11b57b6d4f0d06409029 Mon Sep 17 00:00:00 2001 From: Vadim Fedorov Date: Fri, 28 Mar 2025 12:03:30 +0100 Subject: [PATCH 2/3] Update tests --- tests/test_filters/test_callback_data.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/test_filters/test_callback_data.py b/tests/test_filters/test_callback_data.py index 1bc50cae..e0e9b1f3 100644 --- a/tests/test_filters/test_callback_data.py +++ b/tests/test_filters/test_callback_data.py @@ -28,13 +28,18 @@ class MyCallback(CallbackData, prefix="test"): class TestCallbackData: - def test_init_subclass_prefix_required(self): - assert MyCallback.__prefix__ == "test" + def test_init_subclass_prefix_optional(self): + # Case 1: Explicitly provided prefix + class ExplicitCallbackData(CallbackData, prefix="explicit"): + pass - with pytest.raises(ValueError, match="prefix required.+"): + assert ExplicitCallbackData.__prefix__ == "explicit" - class MyInvalidCallback(CallbackData): - pass + # Case 2: No prefix provided; should default to class name + class DefaultCallbackData(CallbackData): + pass + + assert DefaultCallbackData.__prefix__ == "DefaultCallbackData" def test_init_subclass_sep_validation(self): assert MyCallback.__separator__ == ":" From 599f00d7285556eb2706f99cfc86acd560480f4e Mon Sep 17 00:00:00 2001 From: Vadim Fedorov Date: Sat, 5 Apr 2025 23:00:06 +0200 Subject: [PATCH 3/3] Add changelog --- CHANGES/1668.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGES/1668.feature.rst diff --git a/CHANGES/1668.feature.rst b/CHANGES/1668.feature.rst new file mode 100644 index 00000000..629cfd36 --- /dev/null +++ b/CHANGES/1668.feature.rst @@ -0,0 +1 @@ +Feature: Make CallbackData prefix optional and default to class name