Open jakkdl opened 2 weeks ago
How did you run the first snippet with trio as backend? I put it in a single test module, and ran pytest with the module as argument plus -k trio
. I didn't see any issues there. I can repro the issue with snippet 2, but as for snippet 3, I don't get that RuntimeError
.
How did you run the first snippet with trio as backend? I put it in a single test module, and ran pytest with the module as argument plus
-k trio
. I didn't see any issues there. I can repro the issue with snippet 2, but as for snippet 3, I don't get thatRuntimeError
.
ah hmm, for snippet 1 I only get it when I run both asyncio&trio, so I suppose it's something about the fixture not being torn down & re-set up properly? I tested it just now with pytest-random-order and if running trio 1st and asyncio 2nd I get a similar error:
| File "/tmp/anyio_pytest/foo_1.py", line 14, in my_simple_fixture
| async with anyio.create_task_group() as tg:
| File "/tmp/anyio_pytest/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 736, in __aexit__
| raise BaseExceptionGroup(
| ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "/tmp/anyio_pytest/foo_1.py", line 8, in die_soon
| await my_event.wait()
| File "/tmp/anyio_pytest/.venv/lib/python3.12/site-packages/anyio/_core/_synchronization.py", line 130, in wait
| await self._event.wait()
| File "/tmp/anyio_pytest/.venv/lib/python3.12/site-packages/anyio/_backends/_trio.py", line 647, in wait
| return await self.__original.wait()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/tmp/anyio_pytest/.venv/lib/python3.12/site-packages/trio/_sync.py", line 86, in wait
| await trio.lowlevel.checkpoint()
| File "/tmp/anyio_pytest/.venv/lib/python3.12/site-packages/trio/_core/_run.py", line 2788, in checkpoint
| await cancel_shielded_checkpoint()
| File "/tmp/anyio_pytest/.venv/lib/python3.12/site-packages/trio/_core/_traps.py", line 51, in cancel_shielded_checkpoint
| (await _async_yield(CancelShieldedCheckpoint)).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/tmp/anyio_pytest/.venv/lib/python3.12/site-packages/trio/_core/_traps.py", line 29, in _async_yield
| return (yield obj)
| ^^^^^^^^^
| RuntimeError: Task got bad yield: <class 'trio._core._traps.CancelShieldedCheckpoint'>
+------------------------------------
Not sure how to help you repro the 2nd snippet, I can reliably re-repro it in new venv's.
I noticed that you had a global Event
object, but it will bind to the first back-end it's used with, so that won't work in a test suite involving two back-ends. Make it a fixture instead.
I noticed that you had a global
Event
object, but it will bind to the first back-end it's used with, so that won't work in a test suite involving two back-ends. Make it a fixture instead.
Ah thanks. Making it a fixture resolved it when using my_simple_fixture
as a context manager, but switching it back to being a fixture resurfaces problems
import anyio
import pytest
@pytest.fixture
def my_event():
return anyio.Event()
async def die_soon(my_event, task_status):
print("entering die_soon")
task_status.started()
await my_event.wait()
print("crashing")
raise RuntimeError('OOPS')
@pytest.fixture
async def my_simple_fixture(my_event):
async with anyio.create_task_group() as tg:
await tg.start(die_soon, my_event)
print("yielding")
yield
print("continuing")
@pytest.mark.anyio
async def test_try(my_simple_fixture, my_event):
print("in test")
my_event.set()
print("end of test")
I'm now getting anyio.ClosedResourceError
on asyncio and a hang on trio, but if i random-order to get trio first I get trio passing and then a hang.
This randomness is due to Trio's non-deterministic scheduling. If you know how to turn that off, please let me know! It's supremely annoying when running tests.
This randomness is due to Trio's non-deterministic scheduling. If you know how to turn that off, please let me know! It's supremely annoying when running tests.
sorry, with random-order
I meant running with https://pypi.org/project/pytest-random-order/ in order to see if running trio before asyncio was different from running asyncio before trio.
If you know how to turn that off, please let me know! It's supremely annoying when running tests.
Well, that's easy.
env PYTHONHASHSEED=123 pytest …
Also, in conftest.py
:
from trio._core import _run
_run._ALLOW_DETERMINISTIC_SCHEDULING = True
I think I'll ask around about this particular variable and its future.
On second look a better solution is to call _run._r.seed(123)
instead, but the same caveat applies.
Trio should probably export a way to explicitly set that seed. I'd recommend to submit a PR.
It's not just the random scheduling I'd like to tackle, but I'd really like to make trio schedule tasks in the FIFO order. Does _ALLOW_DETERMINISTIC_SCHEDULING = True
do that?
No. If you want that, you need to monkeypatch run._r.random()
to always return >= 0.5.
Things to check first
[X] I have searched the existing issues and didn't find my bug already reported there
[X] I have checked that my bug is still present in the latest release
AnyIO version
4.6.0
Python version
3.12.4
What happened?
I'm encountering several weird things, where it will either hang in weird places or crash.
This is from trying to rewrite pytest-trio and encountering the test that was added after https://github.com/python-trio/pytest-trio/pull/77 in https://github.com/python-trio/pytest-trio/pull/83
How can we reproduce the bug?
Running this with trio as the backend gives:
if I remove the decorator and directly run
anyio.run(test_try, backend="trio")
it correctly gives a group with our "OOPS"RuntimeError
, same if running anyio-pytest with asyncio as backend.2
This gives a teardown error and a messy traceback
Error:
3
but if we make
anyio_backend
return"trio"
we instead get a hang. KeyboardInterrupt traceback ends with