Removed Text filter

This commit is contained in:
Alex Root Junior 2023-04-22 19:55:27 +03:00
parent dad3cdc409
commit 0c7b6b7adb
No known key found for this signature in database
GPG key ID: 074C1D455EBEA4AC
4 changed files with 5 additions and 388 deletions

View file

@ -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",

View file

@ -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 <magic-filters>`. 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)

View file

@ -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_):

View file

@ -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)"