Skip to content

Error when using Lock from thread in asyncio #773

@davidbrochart

Description

@davidbrochart

Things to check first

  • I have searched the existing issues and didn't find my bug already reported there

  • I have checked that my bug is still present in the latest release

AnyIO version

4.4.0

Python version

3.12.5

What happened?

With the asyncio backend, this code fails with TypeError: cannot create weak reference to 'NoneType' object. It works with the trio backend.

Traceback
Traceback (most recent call last):
  File "/home/david/git/pycrdt/foo.py", line 11, in 
    run(main)
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_core/_eventloop.py", line 74, in run
    return async_backend.run(func, args, {}, backend_options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2034, in run
    return runner.run(wrapper())
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2022, in wrapper
    return await func(*args)
           ^^^^^^^^^^^^^^^^^
  File "/home/david/git/pycrdt/foo.py", line 9, in main
    await to_thread.run_sync(worker, lock)
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/to_thread.py", line 56, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2177, in run_sync_in_worker_thread
    return await future
           ^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 859, in run
    result = context.run(func, *args)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/git/pycrdt/foo.py", line 5, in worker
    from_thread.run_sync(lock.release)
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/from_thread.py", line 80, in run_sync
    return async_backend.run_sync_from_thread(func, args, token=token)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2239, in run_sync_from_thread
    return f.result()
           ^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/concurrent/futures/_base.py", line 456, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2230, in wrapper
    f.set_result(func(*args))
                 ^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_core/_synchronization.py", line 202, in release
    if self._owner_task != get_current_task():
                           ^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_core/_testing.py", line 63, in get_current_task
    return get_async_backend().get_current_task()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2484, in get_current_task
    return AsyncIOTaskInfo(current_task())  # type: ignore[arg-type]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 1839, in __init__
    task_state = _task_states.get(task)
                 ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/micromamba/envs/pycrdt/lib/python3.12/weakref.py", line 452, in get
    return self.data.get(ref(key),default)
                         ^^^^^^^^
TypeError: cannot create weak reference to 'NoneType' object

How can we reproduce the bug?

from anyio import Lock, from_thread, to_thread, run

def worker(lock):
    from_thread.run(lock.acquire)
    from_thread.run_sync(lock.release)

async def main():
    lock = Lock()
    await to_thread.run_sync(worker, lock)

run(main)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions