From 0c7b6b7adb7c5a9f86a8097e42f1215869e331fd Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Sat, 22 Apr 2023 19:55:27 +0300 Subject: [PATCH] Removed Text filter --- aiogram/filters/__init__.py | 2 - aiogram/filters/text.py | 136 ----------------- tests/test_filters/test_logic.py | 10 +- tests/test_filters/test_text.py | 245 ------------------------------- 4 files changed, 5 insertions(+), 388 deletions(-) delete mode 100644 aiogram/filters/text.py delete mode 100644 tests/test_filters/test_text.py diff --git a/aiogram/filters/__init__.py b/aiogram/filters/__init__.py index b3bee0d8..bcadc178 100644 --- a/aiogram/filters/__init__.py +++ b/aiogram/filters/__init__.py @@ -19,14 +19,12 @@ from .exception import ExceptionMessageFilter, ExceptionTypeFilter from .logic import and_f, invert_f, or_f from .magic_data import MagicData from .state import StateFilter -from .text import Text BaseFilter = Filter __all__ = ( "Filter", "BaseFilter", - "Text", "Command", "CommandObject", "CommandStart", diff --git a/aiogram/filters/text.py b/aiogram/filters/text.py deleted file mode 100644 index bdef26f0..00000000 --- a/aiogram/filters/text.py +++ /dev/null @@ -1,136 +0,0 @@ -from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Union - -from aiogram.filters.base import Filter -from aiogram.types import CallbackQuery, InlineQuery, Message, Poll - -if TYPE_CHECKING: - from aiogram.utils.i18n.lazy_proxy import LazyProxy # NOQA - -TextType = Union[str, "LazyProxy"] - - -class Text(Filter): - """ - Is useful for filtering text :class:`aiogram.types.message.Message`, - any :class:`aiogram.types.callback_query.CallbackQuery` with `data`, - :class:`aiogram.types.inline_query.InlineQuery` or :class:`aiogram.types.poll.Poll` question. - - .. warning:: - - Only one of `text`, `contains`, `startswith` or `endswith` argument can be used at once. - Any of that arguments can be string, list, set or tuple of strings. - - .. deprecated:: 3.0 - - use :ref:`magic-filter `. For example do :pycode:`F.text == "text"` instead - """ - - __slots__ = ( - "text", - "contains", - "startswith", - "endswith", - "ignore_case", - ) - - def __init__( - self, - text: Optional[Union[Sequence[TextType], TextType]] = None, - *, - contains: Optional[Union[Sequence[TextType], TextType]] = None, - startswith: Optional[Union[Sequence[TextType], TextType]] = None, - endswith: Optional[Union[Sequence[TextType], TextType]] = None, - ignore_case: bool = False, - ): - """ - - :param text: Text equals value or one of values - :param contains: Text contains value or one of values - :param startswith: Text starts with value or one of values - :param endswith: Text ends with value or one of values - :param ignore_case: Ignore case when checks - """ - self._validate_constraints( - text=text, - contains=contains, - startswith=startswith, - endswith=endswith, - ) - self.text = self._prepare_argument(text) - self.contains = self._prepare_argument(contains) - self.startswith = self._prepare_argument(startswith) - self.endswith = self._prepare_argument(endswith) - self.ignore_case = ignore_case - - def __str__(self) -> str: - return self._signature_to_string( - text=self.text, - contains=self.contains, - startswith=self.startswith, - endswith=self.endswith, - ignore_case=self.ignore_case, - ) - - @classmethod - def _prepare_argument( - cls, value: Optional[Union[Sequence[TextType], TextType]] - ) -> Optional[Sequence[TextType]]: - from aiogram.utils.i18n.lazy_proxy import LazyProxy - - if isinstance(value, (str, LazyProxy)): - return [value] - return value - - @classmethod - def _validate_constraints(cls, **values: Any) -> None: - # Validate that only one text filter type is presented - used_args = {key for key, value in values.items() if value is not None} - if len(used_args) < 1: - raise ValueError(f"Filter should contain one of arguments: {set(values.keys())}") - if len(used_args) > 1: - raise ValueError(f"Arguments {used_args} cannot be used together") - - async def __call__( - self, obj: Union[Message, CallbackQuery, InlineQuery, Poll] - ) -> Union[bool, Dict[str, Any]]: - if isinstance(obj, Message): - text = obj.text or obj.caption or "" - if not text and obj.poll: - text = obj.poll.question - elif isinstance(obj, CallbackQuery) and obj.data: - text = obj.data - elif isinstance(obj, InlineQuery): - text = obj.query - elif isinstance(obj, Poll): - text = obj.question - else: - return False - - if not text: - return False - if self.ignore_case: - text = text.lower() - - if self.text is not None: - equals = map(self.prepare_text, self.text) - return text in equals - - if self.contains is not None: - contains = map(self.prepare_text, self.contains) - return all(map(text.__contains__, contains)) - - if self.startswith is not None: - startswith = map(self.prepare_text, self.startswith) - return any(map(text.startswith, startswith)) - - if self.endswith is not None: - endswith = map(self.prepare_text, self.endswith) - return any(map(text.endswith, endswith)) - - # Impossible because the validator prevents this situation - return False # pragma: no cover - - def prepare_text(self, text: str) -> str: - if self.ignore_case: - return str(text).lower() - return str(text) diff --git a/tests/test_filters/test_logic.py b/tests/test_filters/test_logic.py index 9c4d4f48..b1382766 100644 --- a/tests/test_filters/test_logic.py +++ b/tests/test_filters/test_logic.py @@ -1,6 +1,6 @@ import pytest -from aiogram.filters import Text, and_f, invert_f, or_f +from aiogram.filters import Command, and_f, invert_f, or_f from aiogram.filters.logic import _AndFilter, _InvertFilter, _OrFilter @@ -28,10 +28,10 @@ class TestLogic: @pytest.mark.parametrize( "case,type_", [ - [or_f(Text(text="test"), Text(text="test")), _OrFilter], - [and_f(Text(text="test"), Text(text="test")), _AndFilter], - [invert_f(Text(text="test")), _InvertFilter], - [~Text(text="test"), _InvertFilter], + [or_f(Command("test"), Command("test")), _OrFilter], + [and_f(Command("test"), Command("test")), _AndFilter], + [invert_f(Command("test")), _InvertFilter], + [~Command("test"), _InvertFilter], ], ) def test_dunder_methods(self, case, type_): diff --git a/tests/test_filters/test_text.py b/tests/test_filters/test_text.py deleted file mode 100644 index de823097..00000000 --- a/tests/test_filters/test_text.py +++ /dev/null @@ -1,245 +0,0 @@ -import datetime -from itertools import permutations -from typing import Sequence, Type - -import pytest - -from aiogram.filters import Text -from aiogram.types import ( - CallbackQuery, - Chat, - InlineQuery, - Message, - Poll, - PollOption, - User, -) - - -class TestText: - @pytest.mark.parametrize( - "kwargs", - [ - {}, - {"ignore_case": True}, - {"ignore_case": False}, - ], - ) - def test_not_enough_arguments(self, kwargs): - with pytest.raises(ValueError): - Text(**kwargs) - - @pytest.mark.parametrize( - "first,last", - permutations(["text", "contains", "startswith", "endswith"], 2), - ) - @pytest.mark.parametrize("ignore_case", [True, False]) - def test_validator_too_few_arguments(self, first, last, ignore_case): - kwargs = {first: "test", last: "test", "ignore_case": ignore_case} - - with pytest.raises(ValueError): - Text(**kwargs) - - @pytest.mark.parametrize("argument", ["text", "contains", "startswith", "endswith"]) - @pytest.mark.parametrize("input_type", [str, list, tuple]) - def test_validator_convert_to_list(self, argument: str, input_type: Type): - text = Text(**{argument: input_type("test")}) - assert hasattr(text, argument) - assert isinstance(getattr(text, argument), Sequence) - - @pytest.mark.parametrize( - "argument,ignore_case,input_value,update_type,result", - [ - [ - "text", - False, - "test", - Message( - message_id=42, - date=datetime.datetime.now(), - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - False, - ], - [ - "text", - False, - "test", - Message( - message_id=42, - date=datetime.datetime.now(), - caption="test", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "text", - False, - "test", - Message( - message_id=42, - date=datetime.datetime.now(), - text="test", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "text", - True, - "TEst", - Message( - message_id=42, - date=datetime.datetime.now(), - text="tesT", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "text", - False, - "TEst", - Message( - message_id=42, - date=datetime.datetime.now(), - text="tesT", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - False, - ], - [ - "startswith", - False, - "test", - Message( - message_id=42, - date=datetime.datetime.now(), - text="test case", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "endswith", - False, - "case", - Message( - message_id=42, - date=datetime.datetime.now(), - text="test case", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "contains", - False, - " ", - Message( - message_id=42, - date=datetime.datetime.now(), - text="test case", - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "startswith", - True, - "question", - Message( - message_id=42, - date=datetime.datetime.now(), - poll=Poll( - id="poll id", - question="Question?", - options=[PollOption(text="A", voter_count=0)], - is_closed=False, - is_anonymous=False, - type="regular", - allows_multiple_answers=False, - total_voter_count=0, - ), - chat=Chat(id=42, type="private"), - from_user=User(id=42, is_bot=False, first_name="Test"), - ), - True, - ], - [ - "startswith", - True, - "callback:", - CallbackQuery( - id="query id", - from_user=User(id=42, is_bot=False, first_name="Test"), - chat_instance="instance", - data="callback:data", - ), - True, - ], - [ - "startswith", - True, - "query", - InlineQuery( - id="query id", - from_user=User(id=42, is_bot=False, first_name="Test"), - query="query line", - offset="offset", - ), - True, - ], - [ - "text", - True, - "question", - Poll( - id="poll id", - question="Question", - options=[PollOption(text="A", voter_count=0)], - is_closed=False, - is_anonymous=False, - type="regular", - allows_multiple_answers=False, - total_voter_count=0, - ), - True, - ], - [ - "text", - True, - ["question", "another question"], - Poll( - id="poll id", - question="Another question", - options=[PollOption(text="A", voter_count=0)], - is_closed=False, - is_anonymous=False, - type="quiz", - allows_multiple_answers=False, - total_voter_count=0, - correct_option_id=0, - ), - True, - ], - ["text", True, ["question", "another question"], object(), False], - ], - ) - async def test_check_text(self, argument, ignore_case, input_value, result, update_type): - text = Text(**{argument: input_value}, ignore_case=ignore_case) - test = await text(update_type) - assert test is result - - def test_str(self): - text = Text("test") - assert str(text) == "Text(text=['test'], ignore_case=False)"