2626
2727
2828class CancelledError (BaseException ):
29+ """Injected into a task when calling `Task.cancel()`"""
30+
2931 pass
3032
3133
3234class TimeoutError (Exception ):
35+ """Raised when waiting for a task longer than the specified timeout."""
36+
3337 pass
3438
3539
@@ -65,13 +69,23 @@ def __next__(self):
6569# Pause task execution for the given time (integer in milliseconds, uPy extension)
6670# Use a SingletonGenerator to do it without allocating on the heap
6771def sleep_ms (t , sgen = SingletonGenerator ()):
72+ """Sleep for `t` milliseconds.
73+
74+ This is a coroutine, and a MicroPython extension.
75+ """
76+
6877 assert sgen .state is None , "Check for a missing `await` in your code"
6978 sgen .state = ticks_add (ticks (), max (0 , t ))
7079 return sgen
7180
7281
7382# Pause task execution for the given time (in seconds)
7483def sleep (t ):
84+ """Sleep for `t` seconds
85+
86+ This is a coroutine.
87+ """
88+
7589 return sleep_ms (int (t * 1000 ))
7690
7791
@@ -152,6 +166,11 @@ def _promote_to_task(aw):
152166
153167# Create and schedule a new task from a coroutine
154168def create_task (coro ):
169+ """Create a new task from the given coroutine and schedule it to run.
170+
171+ Returns the corresponding `Task` object.
172+ """
173+
155174 if not hasattr (coro , "send" ):
156175 raise TypeError ("coroutine expected" )
157176 t = Task (coro , globals ())
@@ -161,6 +180,8 @@ def create_task(coro):
161180
162181# Keep scheduling tasks until there are none left to schedule
163182def run_until_complete (main_task = None ):
183+ """Run the given _main_task_ until it completes."""
184+
164185 global cur_task
165186 excs_all = (CancelledError , Exception ) # To prevent heap allocation in loop
166187 excs_stop = (CancelledError , StopIteration ) # To prevent heap allocation in loop
@@ -232,6 +253,11 @@ def run_until_complete(main_task=None):
232253
233254# Create a new task from a coroutine and run it until it finishes
234255def run (coro ):
256+ """Create a new task from the given coroutine and run it until it completes.
257+
258+ Returns the value returned be *coro*.
259+ """
260+
235261 return run_until_complete (create_task (coro ))
236262
237263
@@ -247,54 +273,92 @@ async def _stopper():
247273
248274
249275class Loop :
276+ """Class representing the event loop"""
277+
250278 _exc_handler = None
251279
252280 def create_task (coro ):
281+ """Create a task from the given *coro* and return the new `Task` object."""
282+
253283 return create_task (coro )
254284
255285 def run_forever ():
286+ """Run the event loop until `stop()` is called."""
287+
256288 global _stop_task
257289 _stop_task = Task (_stopper (), globals ())
258290 run_until_complete (_stop_task )
259291 # TODO should keep running until .stop() is called, even if there're no tasks left
260292
261293 def run_until_complete (aw ):
294+ """Run the given *awaitable* until it completes. If *awaitable* is not a task then
295+ it will be promoted to one.
296+ """
297+
262298 return run_until_complete (_promote_to_task (aw ))
263299
264300 def stop ():
301+ """Stop the event loop"""
302+
265303 global _stop_task
266304 if _stop_task is not None :
267305 _task_queue .push_head (_stop_task )
268306 # If stop() is called again, do nothing
269307 _stop_task = None
270308
271309 def close ():
310+ """Close the event loop."""
311+
272312 pass
273313
274314 def set_exception_handler (handler ):
315+ """Set the exception handler to call when a Task raises an exception that is not
316+ caught. The *handler* should accept two arguments: ``(loop, context)``
317+ """
318+
275319 Loop ._exc_handler = handler
276320
277321 def get_exception_handler ():
322+ """Get the current exception handler. Returns the handler, or ``None`` if no
323+ custom handler is set.
324+ """
325+
278326 return Loop ._exc_handler
279327
280328 def default_exception_handler (loop , context ):
329+ """The default exception handler that is called."""
330+
281331 exc = context ["exception" ]
282332 traceback .print_exception (None , exc , exc .__traceback__ )
283333
284334 def call_exception_handler (context ):
335+ """Call the current exception handler. The argument *context* is passed through
336+ and is a dictionary containing keys:
337+ ``'message'``, ``'exception'``, ``'future'``
338+ """
285339 (Loop ._exc_handler or Loop .default_exception_handler )(Loop , context )
286340
287341
288342# The runq_len and waitq_len arguments are for legacy uasyncio compatibility
289343def get_event_loop (runq_len = 0 , waitq_len = 0 ):
344+ """Return the event loop used to schedule and run tasks. See `Loop`."""
345+
290346 return Loop
291347
292348
293349def current_task ():
350+ """Return the `Task` object associated with the currently running task."""
351+
294352 return cur_task
295353
296354
297355def new_event_loop ():
356+ """Reset the event loop and return it.
357+
358+ **NOTE**: Since MicroPython only has a single event loop, this function just resets
359+ the loop's state, it does not create a new one
360+ """
361+
298362 global _task_queue , _io_queue
299363 # TaskQueue of Task instances
300364 _task_queue = TaskQueue ()
0 commit comments