Skip to content

Conversation

@p-sawicki
Copy link
Collaborator

@p-sawicki p-sawicki commented Jan 8, 2026

Fixes mypyc/mypyc#1177.

Fixed incorrect behavior seen when a function compiled with mypyc awaits an expression in which a future raises an exception, eg.

async def inner():
  try:
    return await future_that_raises
  except Exception:
    # do something

async def outer():
  return await inner()

It seems like this case is different from a regular async function raising an exception in that the exception raised by the future is available in the handled exception state seen by the delegating generator (meaning the outer function compiled with mypyc) even when the exception is caught in the inner function.

The delegating generator reraises the exception from the handled exception state in CPy_YieldFromErrorHandle which ends up reraising an already caught exception.

The fix is to also return the function early when the delegated generator throws an exception other than StopIteration (for StopIteration it already returns), meaning res is NULL in line 71 and also in line 80. This is now consistent with the implementation in cpython which does not reraise on exception in the delegated generator (the reraising happens under label throw_here which is reached under different conditions).

Copy link
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a pretty tricky issue. Thanks for writing detailed test coverage!

@JukkaL JukkaL merged commit d61ad17 into python:master Jan 8, 2026
16 checks passed
@p-sawicki p-sawicki deleted the exception-reraise-await-future branch January 8, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exceptions are resurrected in a context manager after awaiting a future

2 participants