erdewit/nest_asyncio

nest-asyncio fail to reset ContextVar

uriyyo opened this issue · 1 comments

nest-asyncio breaks ContextVar.reset method.

I think the problem is at these lines as it creates a separate context for each call to coroutine:

ctx = self._context.copy()
ctx.run(self._callback, *self._args)
if ctx:
self._context.run(update_from_context, ctx)

When I have removed Handle patching, this issue disappeared.

Code to reproduce issue:

from asyncio import run, sleep
from contextvars import ContextVar

from nest_asyncio import apply

ctx_var: ContextVar[int] = ContextVar('ctx_var')


async def main() -> None:
    token = ctx_var.set(1)
    await sleep(1)
    ctx_var.reset(token)


if __name__ == '__main__':
    apply()
    run(main())

Will produce such traceback:

Traceback (most recent call last):
  File "/Users/yuriikarabas/PycharmProjects/sandbox/main.py", line 17, in <module>
    run(main())
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/Users/yuriikarabas/PycharmProjects/sandbox/venv/lib/python3.9/site-packages/nest_asyncio.py", line 98, in run_until_complete
    return f.result()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/tasks.py", line 256, in __step
    result = coro.send(None)
  File "/Users/yuriikarabas/PycharmProjects/sandbox/toy_io.py", line 12, in main
    ctx_var.reset(token)
ValueError: <Token var=<ContextVar name='ctx_var' at 0x7fbde8933ea0> at 0x7fbde8ed4ac0> was created in a different Context

Your fix is released in v1.5.0.