Skip to content

Commit 15d877f

Browse files
committed
extmod/asyncio: Add cpython task methods.
Signed-off-by: James Ward <james@notjam.es>
1 parent 7b44b06 commit 15d877f

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

extmod/asyncio/core.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ class TimeoutError(Exception):
2323
pass
2424

2525

26+
class InvalidStateError(Exception):
27+
pass
28+
29+
2630
# Used when calling Loop.call_exception_handler
2731
_exc_context = {"message": "Task exception wasn't retrieved", "exception": None, "future": None}
2832

extmod/asyncio/task.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,82 @@ def cancel(self):
175175
core._task_queue.push(self)
176176
self.data = core.CancelledError
177177
return True
178+
179+
def add_done_callback(self, callback):
180+
if not self.state:
181+
callback(self, self.data)
182+
183+
if self.state is not True:
184+
raise RuntimeError("Tasks only support one done callback.")
185+
186+
self.state = callback
187+
188+
def remove_done_callback(self, callback):
189+
if self.state is not callback:
190+
return 0
191+
192+
self.state = True
193+
return 1
194+
195+
def set_result(self, result):
196+
raise RuntimeError()
197+
198+
def result(self):
199+
"""
200+
Return the result of the Task.
201+
If the Task is done, the result of the wrapped coroutine is returned (or if the coroutine raised an exception, that exception is re-raised.)
202+
If the Task has been cancelled, this method raises a CancelledError exception.
203+
If the Task’s result isn’t yet available, this method raises a InvalidStateError exception.
204+
"""
205+
if not self.done():
206+
raise core.InvalidStateError()
207+
208+
exception = self.exception()
209+
210+
if exception is not None:
211+
raise exception
212+
213+
if not isinstance(self.data, StopIteration):
214+
# If this isn't the case then we're in an odd state.
215+
return None
216+
217+
return self.data.value
218+
219+
def set_exception(self, exception):
220+
raise RuntimeError()
221+
222+
def exception(self):
223+
"""
224+
Return the exception that was set on this Task.
225+
The exception (or None if no exception was set) is returned only if the Task is done.
226+
If the Task has been cancelled, this method raises a CancelledError exception.
227+
If the Task isn’t done yet, this method raises an InvalidStateError exception.
228+
"""
229+
if not self.done():
230+
raise core.InvalidStateError()
231+
232+
if isinstance(self.data, core.CancelledError):
233+
raise self.data
234+
235+
if isinstance(self.data, StopIteration):
236+
# If the data is a stop iteration we can assume this
237+
# was a successful run rather than any possible exception
238+
return None
239+
240+
if not isinstance(self.data, BaseException):
241+
# If the data is not any type of exception we can treat it as
242+
# something else we don't understand but not an exception.
243+
return None
244+
245+
return self.data
246+
247+
def cancelled(self) -> bool:
248+
"""
249+
Return True if the Task is cancelled.
250+
The Task is cancelled when the cancellation was requested with cancel() and
251+
the wrapped coroutine propagated the CancelledError exception thrown into it.
252+
"""
253+
if not self.done():
254+
return False
255+
256+
return isinstance(self.data, core.CancelledError)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy