🐛 修复一个函数无法注册多个 handler 的问题

This commit is contained in:
Karako 2022-09-08 10:44:09 +08:00
parent 54599b3474
commit f084685852
No known key found for this signature in database
GPG Key ID: 5920831B0095D4A0

View File

@ -35,9 +35,16 @@ _EXCLUDE_ATTRS = ['handlers', 'jobs', 'error_handlers']
class _Plugin: class _Plugin:
def _make_handler(self, data: Dict) -> HandlerType: def _make_handler(self, datas: Union[List[Dict], Dict]) -> List[HandlerType]:
func = getattr(self, data.pop('func')) result = []
return data.pop('type')(callback=func, **data.pop('kwargs')) if isinstance(datas, list):
for data in filter(lambda x: x, datas):
func = getattr(self, data.pop('func'))
result.append(data.pop('type')(callback=func, **data.pop('kwargs')))
else:
func = getattr(self, datas.pop('func'))
result.append(datas.pop('type')(callback=func, **datas.pop('kwargs')))
return result
@property @property
def handlers(self) -> List[HandlerType]: def handlers(self) -> List[HandlerType]:
@ -49,11 +56,11 @@ class _Plugin:
and and
isinstance(func := getattr(self, attr), MethodType) isinstance(func := getattr(self, attr), MethodType)
and and
(data := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None)) (datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
): ):
if data['type'] not in ['error', 'new_chat_member']: for data in datas:
result.append(self._make_handler(data)) if data['type'] not in ['error', 'new_chat_member']:
result.extend(self._make_handler(data))
return result return result
def _new_chat_members_handler_funcs(self) -> List[Tuple[int, Callable]]: def _new_chat_members_handler_funcs(self) -> List[Tuple[int, Callable]]:
@ -66,10 +73,11 @@ class _Plugin:
and and
isinstance(func := getattr(self, attr), MethodType) isinstance(func := getattr(self, attr), MethodType)
and and
(data := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None)) (datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
): ):
if data['type'] == 'new_chat_member': for data in datas:
result.append((data['priority'], func)) if data and data['type'] == 'new_chat_member':
result.append((data['priority'], func))
return result return result
@ -83,10 +91,11 @@ class _Plugin:
and and
isinstance(func := getattr(self, attr), MethodType) isinstance(func := getattr(self, attr), MethodType)
and and
(data := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None)) (datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
): ):
if data['type'] == 'error': for data in datas:
result.update({func: data['block']}) if data and data['type'] == 'error':
result.update({func: data['block']})
return result return result
@property @property
@ -100,13 +109,14 @@ class _Plugin:
and and
isinstance(func := getattr(self, attr), MethodType) isinstance(func := getattr(self, attr), MethodType)
and and
(data := getattr(func, _JOB_ATTR_NAME, None)) (datas := getattr(func, _JOB_ATTR_NAME, None))
): ):
_job = getattr(bot.job_queue, data.pop('type'))( for data in datas:
callback=func, **data.pop('kwargs'), _job = getattr(bot.job_queue, data.pop('type'))(
**{key: data.pop(key) for key in list(data.keys())} callback=func, **data.pop('kwargs'),
) **{key: data.pop(key) for key in list(data.keys())}
result.append(_job) )
result.append(_job)
return result return result
@ -132,21 +142,21 @@ class _Conversation(_Plugin):
and and
isinstance(func := getattr(self, attr), Callable) isinstance(func := getattr(self, attr), Callable)
and and
(handler_data := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None)) (handler_datas := getattr(func, _NORMAL_HANDLER_ATTR_NAME, None))
): ):
_handler = self._make_handler(handler_data) _handlers = self._make_handler(handler_datas)
if conversation_data := getattr(func, _CONVERSATION_HANDLER_ATTR_NAME, None): if conversation_data := getattr(func, _CONVERSATION_HANDLER_ATTR_NAME, None):
if (_type := conversation_data.pop('type')) == 'entry': if (_type := conversation_data.pop('type')) == 'entry':
entry_points.append(_handler) entry_points.extend(_handlers)
elif _type == 'state': elif _type == 'state':
if (key := conversation_data.pop('state')) in states: if (key := conversation_data.pop('state')) in states:
states[key].append(_handler) states[key].extend(_handlers)
else: else:
states[key] = [_handler] states[key] = _handlers
elif _type == 'fallback': elif _type == 'fallback':
fallbacks.append(_handler) fallbacks.extend(_handlers)
else: else:
result.append(_handler) result.extend(_handlers)
if entry_points or states or fallbacks: if entry_points or states or fallbacks:
result.append( result.append(
ConversationHandler( ConversationHandler(
@ -170,7 +180,13 @@ class _Handler:
return getattr(_Module, f"{self.__class__.__name__.strip('_')}Handler") return getattr(_Module, f"{self.__class__.__name__.strip('_')}Handler")
def __call__(self, func: Callable[P, T]) -> Callable[P, T]: def __call__(self, func: Callable[P, T]) -> Callable[P, T]:
setattr(func, _NORMAL_HANDLER_ATTR_NAME, {'type': self._type, 'func': func.__name__, 'kwargs': self.kwargs}) data = {'type': self._type, 'func': func.__name__, 'kwargs': self.kwargs}
if hasattr(func, _NORMAL_HANDLER_ATTR_NAME):
handler_datas = getattr(func, _NORMAL_HANDLER_ATTR_NAME)
handler_datas.append(data)
setattr(func, _NORMAL_HANDLER_ATTR_NAME, handler_datas)
else:
setattr(func, _NORMAL_HANDLER_ATTR_NAME, [data])
return func return func
@ -221,11 +237,14 @@ class _MessageNewChatMembers(_Handler):
def __call__(self, func: Callable[P, T] = None) -> Callable[P, T]: def __call__(self, func: Callable[P, T] = None) -> Callable[P, T]:
self.func = self.func or func self.func = self.func or func
setattr( data = {'type': 'new_chat_member', 'priority': self.priority}
self.func, _NORMAL_HANDLER_ATTR_NAME, if hasattr(func, _NORMAL_HANDLER_ATTR_NAME):
{'type': 'new_chat_member', 'priority': self.priority} handler_datas = getattr(func, _NORMAL_HANDLER_ATTR_NAME)
) handler_datas.append(data)
return self.func setattr(func, _NORMAL_HANDLER_ATTR_NAME, handler_datas)
else:
setattr(func, _NORMAL_HANDLER_ATTR_NAME, [data])
return func
class _Message(_Handler): class _Message(_Handler):
@ -323,8 +342,14 @@ class error_handler:
def __call__(self, func: Callable[P, T] = None) -> Callable[P, T]: def __call__(self, func: Callable[P, T] = None) -> Callable[P, T]:
self._func = func or self._func self._func = func or self._func
setattr(self._func, _NORMAL_HANDLER_ATTR_NAME, {'type': 'error', 'block': self._block}) data = {'type': 'error', 'block': self._block}
return self._func if hasattr(func, _NORMAL_HANDLER_ATTR_NAME):
handler_datas = getattr(func, _NORMAL_HANDLER_ATTR_NAME)
handler_datas.append(data)
setattr(func, _NORMAL_HANDLER_ATTR_NAME, handler_datas)
else:
setattr(func, _NORMAL_HANDLER_ATTR_NAME, [data])
return func
def _entry(func: Callable[P, T]) -> Callable[P, T]: def _entry(func: Callable[P, T]) -> Callable[P, T]:
@ -368,11 +393,17 @@ class _Job:
self.kwargs = kwargs self.kwargs = kwargs
def __call__(self, func: JobCallback) -> JobCallback: def __call__(self, func: JobCallback) -> JobCallback:
setattr(func, _JOB_ATTR_NAME, { data = {
'name': self.name, 'data': self.data, 'chat_id': self.chat_id, 'user_id': self.user_id, 'name': self.name, 'data': self.data, 'chat_id': self.chat_id, 'user_id': self.user_id,
'job_kwargs': self.job_kwargs, 'kwargs': self.kwargs, 'job_kwargs': self.job_kwargs, 'kwargs': self.kwargs,
'type': re.sub(r'([A-Z])', lambda x: '_' + x.group().lower(), self.__class__.__name__).lstrip('_') 'type': re.sub(r'([A-Z])', lambda x: '_' + x.group().lower(), self.__class__.__name__).lstrip('_')
}) }
if hasattr(func, _JOB_ATTR_NAME):
job_datas = getattr(func, _JOB_ATTR_NAME)
job_datas.append(data)
setattr(func, _JOB_ATTR_NAME, job_datas)
else:
setattr(func, _JOB_ATTR_NAME, [data])
return func return func