Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/1600.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
|tasks| Retain original ``**kwargs`` of a :class:`~ext.tasks.Loop` for copying the loop, which helps avoid having to re-implement :meth:`Loop.clone <ext.tasks.Loop.clone>` in custom subclasses.
27 changes: 17 additions & 10 deletions disnake/ext/tasks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ class Loop(Generic[LF]):
The main interface to create this is through :func:`loop`.
"""

# (args, kwargs), used for cloning the loop later
__original_args__: tuple[tuple[Any, ...], dict[str, Any]]

def __new__(cls, *args: Any, **kwargs: Any) -> Self:
self = super().__new__(cls)
# These are captured in __new__ (rather than __init__), such that we run
# before any subclass __init__'s and snapshot the original set of arguments.
# (n.b. while custom *args aren't supported in `Loop`, we capture *args here
# nonetheless, in case a subclass __init__ wraps the callback; using self.coro
# instead of the original arg for cloning would wrap it a second time)
self.__original_args__ = (args, kwargs)
return self

def __init__(
self,
coro: LF,
Expand Down Expand Up @@ -200,20 +213,14 @@ def __get__(self, obj: T, objtype: type[T]) -> Self:
return clone

def clone(self) -> Self:
instance = type(self)(
self.coro,
seconds=self._seconds,
hours=self._hours,
minutes=self._minutes,
time=self._time,
count=self.count,
reconnect=self.reconnect,
loop=self.loop,
)
args, kwargs = self.__original_args__
instance = type(self)(*args, **kwargs)

instance._before_loop = self._before_loop
instance._after_loop = self._after_loop
instance._error = self._error
instance._injected = self._injected

return instance

@property
Expand Down
12 changes: 0 additions & 12 deletions tests/ext/tasks/test_loops.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,6 @@ def __init__(self, coro: LF, time_tup: tuple[float, float, float]) -> None:
s, m, h = time_tup
super().__init__(coro, seconds=s, minutes=m, hours=h)

def clone(self):
instance = type(self)(self.coro, (self._seconds, self._minutes, self._hours))
instance._time = self._time
instance.count = self.count
instance.reconnect = self.reconnect
instance.loop = self.loop
instance._before_loop = self._before_loop
instance._after_loop = self._after_loop
instance._error = self._error
instance._injected = self._injected
return instance

async def callback() -> None:
pass

Expand Down