Fixed exception propagation inside except blocks when a task is cancelled, base functionality completed

This commit is contained in:
nocturn9x 2020-04-05 11:40:31 +00:00
parent 9f7286c69b
commit 7f22977480
3 changed files with 14 additions and 13 deletions

View File

@ -4,13 +4,13 @@ loop = giambio.EventLoop()
""" """
What works and what does not (5 Apr 2020 12:06 AM): What works and what does not (5 Apr 2020 13:35)
- Run tasks concurrently: V - Run tasks concurrently: V
- Join mechanism: V - Join mechanism: V
- Sleep mechanism: V - Sleep mechanism: V
- Cancellation mechanism: V - Cancellation mechanism: V
- Exception propagation: X Note: Almost ready - Exception propagation: V
- Concurrent I/O: V - Concurrent I/O: V
- Return values of coroutines: V - Return values of coroutines: V
- Scheduling tasks for future execution: V - Scheduling tasks for future execution: V
@ -26,6 +26,7 @@ What's left to implement:
- Debugging tools - Debugging tools
""" """
async def countdown(n): async def countdown(n):
try: try:
while n > 0: while n > 0:
@ -38,7 +39,7 @@ async def countdown(n):
return "Count DOWN over" return "Count DOWN over"
except giambio.CancelledError: except giambio.CancelledError:
print("countdown cancelled!") print("countdown cancelled!")
raise Exception("Oh no!") # TODO Propagate this # raise Exception("Oh no!") # This will propagate
async def count(stop, step=1): async def count(stop, step=1):
try: try:
@ -51,7 +52,7 @@ async def count(stop, step=1):
return "Count UP over" return "Count UP over"
except giambio.CancelledError: except giambio.CancelledError:
print("count cancelled!") print("count cancelled!")
# raise BaseException # This will propagate
async def main(): async def main():
try: try:
@ -59,11 +60,12 @@ async def main():
async with giambio.TaskManager(loop) as manager: async with giambio.TaskManager(loop) as manager:
task = manager.spawn(countdown(8)) task = manager.spawn(countdown(8))
task2 = manager.schedule(count(8, 2), 4) task2 = manager.schedule(count(8, 2), 4)
await task.cancel() # This works, but other tasks continue running # await giambio.sleep(3)
# await task.cancel() # This works, but other tasks continue running
for task, ret in manager.values.items(): for task, ret in manager.values.items():
print(f"Function '{task.coroutine.__name__}' at {hex(id(task.coroutine))} returned an object of type '{type(ret).__name__}': {repr(ret)}") print(f"Function '{task.coroutine.__name__}' at {hex(id(task.coroutine))} returned an object of type '{type(ret).__name__}': {repr(ret)}")
except Exception as e: except Exception as e:
print(f"Actually I prefer to catch it here: {e}") # Everything works just as expected, the try/except block below won't trigger print(f"Actually I prefer to catch it here: {repr(e)}") # Everything works just as expected, the try/except block below won't trigger
try: try:

View File

@ -147,8 +147,10 @@ class EventLoop:
def want_cancel(self, task): def want_cancel(self, task):
self.to_run.extend(self.joined.pop(self.running, ())) self.to_run.extend(self.joined.pop(self.running, ()))
self.to_run.append(self.running) # Reschedules the parent task self.to_run.append(self.running) # Reschedules the parent task
task.throw(CancelledError()) try:
task.throw(CancelledError())
except Exception as e:
task.result.exc = e
async def connect_sock(self, sock: socket.socket, addr: tuple): async def connect_sock(self, sock: socket.socket, addr: tuple):
try: # "Borrowed" from curio try: # "Borrowed" from curio

View File

@ -19,11 +19,8 @@ class TaskManager:
async def _cancel_and_raise(self, exc): async def _cancel_and_raise(self, exc):
if not isinstance(exc, CancelledError): if not isinstance(exc, CancelledError):
self.loop._exiting = True # Tells the loop not to catch all exceptions self.loop._exiting = True # Tells the loop not to catch all exceptions
try: for task in self.tasks:
for task in self.tasks: await task.cancel()
await task.cancel()
except Exception:
pass
raise exc raise exc
async def __aenter__(self): async def __aenter__(self):