Skip to content

Commit 8c5cf71

Browse files
artem30801pre-commit-ci[bot]artem30801LordOfPolls
authored
feat: pass event object based on listeners signature (#1367)
* feat: pass event object based on listeners signature * Moved inspection to Listener.create, added warnings * ci: correct from checks. * fixed listeners in cogs * feat: defer param processing until after binding --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: artem30801 <artem3080@gmail.com> Co-authored-by: LordOfPolls <dev@lordofpolls.com>
1 parent d4a411c commit 8c5cf71

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

interactions/client/client.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -571,11 +571,17 @@ async def _async_wrap(_coro: Listener, _event: BaseEvent, *_args, **_kwargs) ->
571571
):
572572
await self.wait_until_ready()
573573

574-
if len(_event.__attrs_attrs__) == 2 and coro.event != "event":
575-
# override_name & bot & logging
576-
await _coro()
577-
else:
574+
# don't pass event object if listener doesn't expect it
575+
if _coro.pass_event_object:
578576
await _coro(_event, *_args, **_kwargs)
577+
else:
578+
if not _coro.warned_no_event_arg and len(_event.__attrs_attrs__) > 2 and _coro.event != "event":
579+
self.logger.warning(
580+
f"{_coro} is listening to {_coro.event} event which contains event data. "
581+
f"Add an event argument to this listener to receive the event data object."
582+
)
583+
_coro.warned_no_event_arg = True
584+
await _coro()
579585
except asyncio.CancelledError:
580586
pass
581587
except Exception as e:
@@ -1202,6 +1208,8 @@ def add_listener(self, listener: Listener) -> None:
12021208
self.logger.debug(f"Listener {listener} has already been hooked, not re-hooking it again")
12031209
return
12041210

1211+
listener.lazy_parse_params()
1212+
12051213
if listener.event not in self.listeners:
12061214
self.listeners[listener.event] = []
12071215
self.listeners[listener.event].append(listener)

interactions/models/internal/extension.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def __new__(cls, bot: "Client", *args, **kwargs) -> "Extension":
101101
for _name, val in callables:
102102
if isinstance(val, models.BaseCommand):
103103
val.extension = instance
104-
val = wrap_partial(val, instance)
104+
val = val.copy_with_binding(instance)
105105
bot.add_command(val)
106106
instance._commands.append(val)
107107

@@ -110,12 +110,12 @@ def __new__(cls, bot: "Client", *args, **kwargs) -> "Extension":
110110

111111
elif isinstance(val, models.Listener):
112112
val.extension = instance
113-
val = wrap_partial(val, instance)
113+
val = val.copy_with_binding(instance)
114114
bot.add_listener(val) # type: ignore
115115
instance._listeners.append(val)
116116
elif isinstance(val, models.GlobalAutoComplete):
117117
val.extension = instance
118-
val = wrap_partial(val, instance)
118+
val = val.copy_with_binding(instance)
119119
bot.add_global_autocomplete(val)
120120
bot.dispatch(events.ExtensionCommandParse(extension=instance, callables=callables))
121121

interactions/models/internal/listener.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def __init__(
3030
delay_until_ready: bool = False,
3131
is_default_listener: bool = False,
3232
disable_default_listeners: bool = False,
33+
pass_event_object: Absent[bool] = MISSING,
3334
) -> None:
3435
super().__init__()
3536

@@ -42,6 +43,10 @@ def __init__(
4243
self.is_default_listener = is_default_listener
4344
self.disable_default_listeners = disable_default_listeners
4445

46+
self._params = inspect.signature(func).parameters.copy()
47+
self.pass_event_object = pass_event_object
48+
self.warned_no_event_arg = False
49+
4550
def __repr__(self) -> str:
4651
return f"<Listener event={self.event!r} callback={self.callback!r}>"
4752

@@ -98,6 +103,17 @@ def wrapper(coro: AsyncCallable) -> "Listener":
98103

99104
return wrapper
100105

106+
def lazy_parse_params(self):
107+
"""Process the parameters of this listener."""
108+
if self.pass_event_object is not MISSING:
109+
return
110+
111+
if self.has_binding:
112+
# discard the first parameter, which is the class instance
113+
self._params = list(self._params.values())[1:]
114+
115+
self.pass_event_object = len(self._params) != 0
116+
101117

102118
def listen(
103119
event_name: Absent[str | BaseEvent] = MISSING,

0 commit comments

Comments
 (0)