test errors_handler args

This commit is contained in:
Oleg A 2018-11-15 10:29:59 +03:00
parent fb9fb68130
commit 37d46d9250
2 changed files with 114 additions and 5 deletions

View file

@ -4,7 +4,7 @@ import itertools
import logging
import time
import typing
from inspect import signature
import inspect
from .filters import Command, ContentTypeFilter, ExceptionsFilter, FiltersFactory, FuncFilter, HashTag, Regexp, \
RegexpCommandsFilter, StateFilter, Text
@ -814,10 +814,20 @@ class Dispatcher(DataMixin, ContextInstanceMixin):
:param run_task: run callback in task (no wait results)
"""
# Check number of arguments of the callback, cause only two arguments accepted.
sig = signature(callback)
if len(sig.parameters) != 2:
raise RuntimeError('Errors handlers should accept only two arguments (current update and exception)')
# Check number of arguments of the callback, cause only two arguments accepted (except self, *args and **kwargs)
signature = inspect.signature(callback)
arguments = inspect.getfullargspec(callback)
amount_of_params = 2
if arguments.varargs:
amount_of_params += 1
if arguments.varkw:
amount_of_params += 1
if len(signature.parameters) != amount_of_params:
raise RuntimeError(f'Errors handlers should accept only 2 arguments '
f'(current update and exception). Also you may use *args and **kwargs after that.')
filters_set = self.filters_factory.resolve(self.errors_handlers,
*custom_filters,

99
tests/test_dispatcher.py Normal file
View file

@ -0,0 +1,99 @@
from asyncio import BaseEventLoop
import pytest
from aiogram import Bot, types, Dispatcher
from aiogram.dispatcher.handler import Handler
pytestmark = pytest.mark.asyncio
TOKEN = '123456789:AABBCCDDEEFFaabbccddeeff-1234567890'
@pytest.yield_fixture()
async def bot(event_loop: BaseEventLoop):
""" Bot fixture """
_bot = Bot(TOKEN, loop=event_loop, parse_mode=types.ParseMode.HTML)
yield _bot
await _bot.close()
@pytest.yield_fixture()
async def dp(event_loop: BaseEventLoop, bot: Bot):
"""
Dispatcher fixture
:rtype: Dispatcher
"""
_dp = Dispatcher(bot=bot, loop=event_loop)
yield _dp
class TestErrorsHandlerArgs:
@staticmethod
def get_handler_from(handler_category: Handler):
filters, handler = handler_category.handlers.pop()
return handler
def method_with_3_args(self, two, three):
pass
def method_with_4_args(self, two, three, four):
pass
def method_with_varargs(self, two, three, *args):
pass
def method_with_varkw(self, two, three, **kwargs):
pass
def method_with_varargs_and_varkw(self, two, three, *args, **kwargs):
pass
async def test_errors_handler_func_with_2_args(self, dp: Dispatcher):
""" Test handler as func with 2 args """
async def func(one, two):
pass
dp.register_errors_handler(func)
assert func == self.get_handler_from(dp.errors_handlers)
async def test_errors_handler_func_with_3_args(self, dp: Dispatcher):
""" Test handler with 3 args """
async def func(one, two, three):
pass
with pytest.raises(RuntimeError):
dp.register_errors_handler(func)
assert len(dp.errors_handlers.handlers) == 0
async def test_errors_handler_method_with_3_args(self, dp: Dispatcher):
""" Test handler as class method with 3 args """
dp.register_errors_handler(self.method_with_3_args)
assert self.method_with_3_args == self.get_handler_from(dp.errors_handlers)
async def test_errors_handler_method_with_4_args(self, dp: Dispatcher):
""" Test handler as class method with 4 args """
with pytest.raises(RuntimeError):
dp.register_errors_handler(self.method_with_4_args)
async def test_errors_handler_method_with_varargs(self, dp: Dispatcher):
""" Test handler as class method with 2 args (except self) and *args """
dp.register_errors_handler(self.method_with_varargs)
assert self.method_with_varargs == self.get_handler_from(dp.errors_handlers)
async def test_errors_handler_method_with_varkw(self, dp: Dispatcher):
""" Test handler as class method with 2 args (except self) and **kwargs """
dp.register_errors_handler(self.method_with_varkw)
assert self.method_with_varkw == self.get_handler_from(dp.errors_handlers)
async def test_errors_handler_method_with_varargs_and_varkw(self, dp: Dispatcher):
""" Test handler as class method with 2 args (except self), *args and **kwargs """
dp.register_errors_handler(self.method_with_varargs_and_varkw)
assert self.method_with_varargs_and_varkw == self.get_handler_from(dp.errors_handlers)