-
Notifications
You must be signed in to change notification settings - Fork 149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loop is closed before fixture teardown completes #708
Comments
Thinking this over a bit more, I guess what I need is a way to insert my fixture's finalizer before the event_loop finalizer to the pytest request. |
also #706 (comment) |
Thanks. This topic was briefly touched in #705. I haven't looked into the specific example of the OP, yet. I did look into the reproducer provided in the referenced issue, though. Here is @albertferras-vrf 's reproducer for reference: import pytest
import asyncio
@pytest.fixture
def get_marks(request):
marks = [repr(m) for m in request.node.iter_markers()]
if request.node.parent:
marks += [repr(m) for m in request.node.parent.iter_markers()]
yield marks
@pytest.fixture(scope="session")
async def myfixture():
await asyncio.sleep(0.1)
yield 5
async def test_one(get_marks, myfixture):
print(get_marks)
await asyncio.sleep(0.1)
assert True
async def test_two(get_marks, myfixture):
print(get_marks)
await asyncio.sleep(0.1)
assert True In this case, myfixture runs in a session-scoped loop, which is setup at the beginning of the test run and torn down at the end. The fixture finalizer is run during teardown. The test cases run in a function-scoped loop. For backwards compatibility, whenever a function-scoped loop is used, pytest-asyncio v0.23 uses pytest-asyncio tries to close any event loop before installing the loop provided by the This loop closing behavior was deprecated in v0.21. I think it's possible to address this in a patch release. I'll also want to look at the OP's example, because it doesn't involve different loop scopes. |
@jpwright Can you confirm that your issue is resolved with |
I do still get the |
I've seen a similar issue, possibly more similar to this description #706 (comment), namely |
@jpwright I fixed a different issue (related to larger-scoped fixtures and function-scoped tests) and pinged the wrong person while I was travelling. Thank you for testing, but sorry for taking your time. I'll reopen this issue for the time being. |
@jpwright I got a chance to look at the issue. I was able to reproduce the error for certain Python versions (3.10, 3.11), but not for others (e.g. 3.12). The output of Here's my understanding of what happens: When you call If my assumption is correct, it means that the pytest run (i.e. the parent process) cleans up the event loop before the subprocess is fully killed. When the subprocess is eventually killed, the child watcher thread monitoring the subprocess tries to run the cleanup callbacks, but the loop has already been closed. You can try adding In my opinion, the correct way to terminate your subprocess is to call I cannot confirm that the error wasn't there with pytest-asyncio v0.21.1. In fact, I could reproduce the error with that version of pytest-asyncio: $ python3 -m pytest --log-cli-level=INFO test_a.py
===== test session starts =====
platform linux -- Python 3.11.7, pytest-7.4.3, pluggy-1.3.0
rootdir: /tmp/tst
plugins: asyncio-0.21.1
asyncio: mode=Mode.STRICT
collected 1 item
test_a.py::test_echo
----- live log call -----INFO test_a:test_a.py:21 <Process 33072>
PASSED [100%]
----- live log teardown -----WARNING asyncio:unix_events.py:1420 Loop <_UnixSelectorEventLoop running=False closed=True debug=False> that handles pid 33072 is closed
===== 1 passed in 0.01s =====```
Given this information, I'll close this issue as invalid, because it's unrelated to pytest-asyncio. Let me know if you have a different opinion. |
I am looking to use pytest-asyncio to create a fixture that spawns a subprocess and then kills the subprocess when the fixture teardown is complete. I've noticed that the event loop can be closed before the fixture teardown is complete, which can lead to the subprocess kill not working.
Here is a simple example (tested using pytest-asyncio 0.23.2):
Which produces the following output:
I am invoking the test using
python3 -m pytest --log-cli-level=INFO ./test.py
. I noticed that the issue is intermittent without logging to CLI... perhaps timing-related.In my actual use case the warning cannot be ignored as the subprocess will not terminate on its own.
The text was updated successfully, but these errors were encountered: