Browse Source

[tasks] Remove support for awaitables due to gotchas.

Fixes #2079
pull/2133/head
Rapptz 6 years ago
parent
commit
55e3e242ff
  1. 34
      discord/ext/tasks/__init__.py
  2. 20
      docs/ext/tasks/index.rst

34
discord/ext/tasks/__init__.py

@ -57,13 +57,10 @@ class Loop:
if coro is None: if coro is None:
return return
if inspect.iscoroutinefunction(coro): if self._injected is not None:
if self._injected is not None: await coro(self._injected)
await coro(self._injected)
else:
await coro()
else: else:
await coro await coro()
async def _loop(self, *args, **kwargs): async def _loop(self, *args, **kwargs):
backoff = ExponentialBackoff() backoff = ExponentialBackoff()
@ -193,14 +190,16 @@ class Loop:
return self._task return self._task
def before_loop(self, coro): def before_loop(self, coro):
"""A function that also acts as a decorator to register a coroutine to be """A decorator that registers a coroutine to be called before the loop starts running.
called before the loop starts running. This is useful if you want to wait
for some bot state before the loop starts, This is useful if you want to wait for some bot state before the loop starts,
such as :meth:`discord.Client.wait_until_ready`. such as :meth:`discord.Client.wait_until_ready`.
The coroutine must take no arguments (except ``self`` in a class context).
Parameters Parameters
------------ ------------
coro: :term:`py:awaitable` coro: :ref:`coroutine <coroutine>`
The coroutine to register before the loop runs. The coroutine to register before the loop runs.
Raises Raises
@ -209,19 +208,20 @@ class Loop:
The function was not a coroutine. The function was not a coroutine.
""" """
if not (inspect.iscoroutinefunction(coro) or inspect.isawaitable(coro)): if not inspect.iscoroutinefunction(coro):
raise TypeError('Expected coroutine or awaitable, received {0.__name__!r}.'.format(type(coro))) raise TypeError('Expected coroutine function, received {0.__name__!r}.'.format(type(coro)))
self._before_loop = coro self._before_loop = coro
def after_loop(self, coro): def after_loop(self, coro):
"""A function that also acts as a decorator to register a coroutine to be """A decorator that register a coroutine to be called after the loop finished running.
called after the loop finished running.
The coroutine must take no arguments (except ``self`` in a class context).
Parameters Parameters
------------ ------------
coro: :term:`py:awaitable` coro: :ref:`coroutine <coroutine>`
The coroutine to register after the loop finishes. The coroutine to register after the loop finishes.
Raises Raises
@ -230,8 +230,8 @@ class Loop:
The function was not a coroutine. The function was not a coroutine.
""" """
if not (inspect.iscoroutinefunction(coro) or inspect.isawaitable(coro)): if not inspect.iscoroutinefunction(coro):
raise TypeError('Expected coroutine or awaitable, received {0.__name__!r}.'.format(type(coro))) raise TypeError('Expected coroutine function, received {0.__name__!r}.'.format(type(coro)))
self._after_loop = coro self._after_loop = coro

20
docs/ext/tasks/index.rst

@ -74,26 +74,6 @@ Looping a certain amount of times before exiting:
Waiting until the bot is ready before the loop starts: Waiting until the bot is ready before the loop starts:
.. code-block:: python3
from discord.ext import tasks, commands
class MyCog(commands.Cog):
def __init__(self, bot):
self.index = 0
self.printer.before_loop(bot.wait_until_ready())
self.printer.start()
def cog_unload(self):
self.printer.cancel()
@tasks.loop(seconds=5.0)
async def printer(self):
print(self.index)
self.index += 1
:meth:`~.tasks.Loop.before_loop` can be used as a decorator as well:
.. code-block:: python3 .. code-block:: python3
from discord.ext import tasks, commands from discord.ext import tasks, commands

Loading…
Cancel
Save