bluesky
bluesky copied to clipboard
*loop* parameter was removed from asyncio.Queue() in Py3.10
As part of unit testing a new feature in apstools, encountered this error in the Py3.10 unit testing workflow:
> RE(my_plan(msg, default, agree, bypass))
/home/runner/work/apstools/apstools/apstools/plans/tests/test_input_plan.py:38:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/site-packages/bluesky/run_engine.py:893: in __call__
plan_return = self._resume_task(init_func=_build_task)
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/site-packages/bluesky/run_engine.py:1032: in _resume_task
raise exc
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/site-packages/bluesky/run_engine.py:1663: in _run
raise err
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/site-packages/bluesky/run_engine.py:1498: in _run
msg = self._plan_stack[-1].throw(stashed_exception or resp)
/home/runner/work/apstools/apstools/apstools/plans/tests/test_input_plan.py:13: in my_plan
yield from request_input(
/home/runner/work/apstools/apstools/apstools/plans/input_plan.py:45: in request_input
r = yield from bps.input_plan(full_text)
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/site-packages/bluesky/plan_stubs.py:554: in input_plan
return (yield Msg('input', prompt=prompt))
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/site-packages/bluesky/run_engine.py:1583: in _run
new_response = await coro(msg)
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/site-packages/bluesky/run_engine.py:2431: in _input
async_input = AsyncInput(self.loop)
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/site-packages/bluesky/utils/__init__.py:1052: in __init__
self.q = asyncio.Queue(loop=self.loop)
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/asyncio/queues.py:34: in __init__
super().__init__(loop=loop)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'Queue' object has no attribute '_maxsize'") raised in repr()] Queue object at 0x7fce7f4ae9b0>
def __init__(self, *, loop=_marker):
if loop is not _marker:
> raise TypeError(
f'As of 3.10, the *loop* parameter was removed from '
f'{type(self).__name__}() since it is no longer necessary'
)
E TypeError: As of 3.10, the *loop* parameter was removed from Queue() since it is no longer necessary
/home/runner/micromamba-root/envs/anaconda-test-env-py-3.10/lib/python3.10/asyncio/mixins.py:17: TypeError
The code in question is: https://github.com/bluesky/bluesky/blob/72ea2473359e3020a27f4338bad5446534dc7d02/bluesky/utils/init.py#L1052
Since it breaks unit tests at this time, it is labeled High Priority here.
I could have sworn I got all of these.
We apparently do not set that code.....
My understanding is that in python 3.10 asyncio synchronization primitives like Lock and Queue can be instantiated anywhere without tying them to a specific loop at instantiation. The high-level asyncio API then reads the currently running loop using the _get_loop()
method of the primitive when needed, i.e., where we would await self.q.get()
, for example. I think the main advantage is that loop capturing is now automatically handled in a thread-safe way, also leading to cleaner code if one were to stick to python 3.10+.
See this discussion for a more detailed reasoning behind this change in python.
I propose we simply let python handle the loop parameter on capable versions.
Closed by #1566