File tree Expand file tree Collapse file tree 3 files changed +42
-5
lines changed Expand file tree Collapse file tree 3 files changed +42
-5
lines changed Original file line number Diff line number Diff line change @@ -4,9 +4,10 @@ Changelog
4
4
5
5
0.26.0 (UNRELEASED)
6
6
===================
7
- - Adds configuration option that sets default event loop scope for all testss `#793 <https://github.com/pytest-dev/pytest-asyncio/issues/793 >`_
7
+ - Adds configuration option that sets default event loop scope for all tests `#793 <https://github.com/pytest-dev/pytest-asyncio/issues/793 >`_
8
8
- Improved type annotations for ``pytest_asyncio.fixture `` `#1045 <https://github.com/pytest-dev/pytest-asyncio/pull/1045 >`_
9
9
- Added ``typing-extensions `` as additional dependency for Python ``<3.10 `` `#1045 <https://github.com/pytest-dev/pytest-asyncio/pull/1045 >`_
10
+ - Avoid errors in cleanup when event loop is already closed `#1051 <https://github.com/pytest-dev/pytest-asyncio/issues/1051 >`_
10
11
11
12
12
13
0.25.2 (2025-01-08)
Original file line number Diff line number Diff line change @@ -1190,10 +1190,14 @@ def _provide_event_loop() -> Iterator[asyncio.AbstractEventLoop]:
1190
1190
try :
1191
1191
yield loop
1192
1192
finally :
1193
- try :
1194
- loop .run_until_complete (loop .shutdown_asyncgens ())
1195
- finally :
1196
- loop .close ()
1193
+ # cleanup the event loop if it hasn't been cleaned up already
1194
+ if not loop .is_closed ():
1195
+ try :
1196
+ loop .run_until_complete (loop .shutdown_asyncgens ())
1197
+ except Exception as e :
1198
+ warnings .warn (f"Error cleaning up asyncio loop: { e } " , RuntimeWarning )
1199
+ finally :
1200
+ loop .close ()
1197
1201
1198
1202
1199
1203
@pytest .fixture (scope = "session" )
Original file line number Diff line number Diff line change @@ -80,3 +80,35 @@ async def generator_fn():
80
80
)
81
81
result = pytester .runpytest_subprocess ("--asyncio-mode=strict" , "-W" , "default" )
82
82
result .assert_outcomes (passed = 1 , warnings = 0 )
83
+
84
+
85
+ def test_event_loop_already_closed (
86
+ pytester : Pytester ,
87
+ ):
88
+ pytester .makeini ("[pytest]\n asyncio_default_fixture_loop_scope = function" )
89
+ pytester .makepyfile (
90
+ dedent (
91
+ """\
92
+ import asyncio
93
+ import pytest
94
+ import pytest_asyncio
95
+ pytest_plugins = 'pytest_asyncio'
96
+
97
+ @pytest_asyncio.fixture
98
+ async def _event_loop():
99
+ return asyncio.get_running_loop()
100
+
101
+ @pytest.fixture
102
+ def cleanup_after(_event_loop):
103
+ yield
104
+ # fixture has its own cleanup code
105
+ _event_loop.close()
106
+
107
+ @pytest.mark.asyncio
108
+ async def test_something(cleanup_after):
109
+ await asyncio.sleep(0.01)
110
+ """
111
+ )
112
+ )
113
+ result = pytester .runpytest_subprocess ("--asyncio-mode=strict" , "-W" , "default" )
114
+ result .assert_outcomes (passed = 1 , warnings = 0 )
You can’t perform that action at this time.
0 commit comments