1
1
from __future__ import annotations
2
2
3
- from collections .abc import Generator
4
- import contextlib
5
3
import gc
6
4
import sys
7
5
from unittest import mock
@@ -229,19 +227,13 @@ def _set_gc_state(enabled: bool) -> bool:
229
227
return was_enabled
230
228
231
229
232
- @contextlib .contextmanager
233
- def _disable_gc () -> Generator [None ]:
234
- was_enabled = _set_gc_state (enabled = False )
235
- try :
236
- yield
237
- finally :
238
- _set_gc_state (enabled = was_enabled )
239
-
240
-
241
230
def test_refcycle_unraisable (pytester : Pytester ) -> None :
242
231
# see: https://github.com/pytest-dev/pytest/issues/10404
243
232
pytester .makepyfile (
244
233
test_it = """
234
+ # Should catch the unraisable exception even if gc is disabled.
235
+ import gc; gc.disable()
236
+
245
237
import pytest
246
238
247
239
class BrokenDel:
@@ -256,23 +248,22 @@ def test_it():
256
248
"""
257
249
)
258
250
259
- with _disable_gc ():
260
- result = pytester .runpytest ()
251
+ result = pytester .runpytest_subprocess (
252
+ "-Wdefault::pytest.PytestUnraisableExceptionWarning"
253
+ )
261
254
262
- # TODO: should be a test failure or error
263
- assert result .ret == pytest .ExitCode .INTERNAL_ERROR
255
+ assert result .ret == 0
264
256
265
257
result .assert_outcomes (passed = 1 )
266
258
result .stderr .fnmatch_lines ("ValueError: del is broken" )
267
259
268
260
269
- @pytest .mark .filterwarnings ("default::pytest.PytestUnraisableExceptionWarning" )
270
261
def test_refcycle_unraisable_warning_filter (pytester : Pytester ) -> None :
271
- # note that the host pytest warning filter is disabled and the pytester
272
- # warning filter applies during config teardown of unraisablehook.
273
- # see: https://github.com/pytest-dev/pytest/issues/10404
274
262
pytester .makepyfile (
275
263
test_it = """
264
+ # Should catch the unraisable exception even if gc is disabled.
265
+ import gc; gc.disable()
266
+
276
267
import pytest
277
268
278
269
class BrokenDel:
@@ -287,17 +278,18 @@ def test_it():
287
278
"""
288
279
)
289
280
290
- with _disable_gc ():
291
- result = pytester .runpytest ("-Werror" )
281
+ result = pytester .runpytest_subprocess (
282
+ "-Werror::pytest.PytestUnraisableExceptionWarning"
283
+ )
292
284
293
- # TODO: should be a test failure or error
294
- assert result .ret == pytest .ExitCode .INTERNAL_ERROR
285
+ # TODO: Should be a test failure or error. Currently the exception
286
+ # propagates all the way to the top resulting in exit code 1.
287
+ assert result .ret == 1
295
288
296
289
result .assert_outcomes (passed = 1 )
297
290
result .stderr .fnmatch_lines ("ValueError: del is broken" )
298
291
299
292
300
- @pytest .mark .filterwarnings ("default::pytest.PytestUnraisableExceptionWarning" )
301
293
def test_create_task_raises_unraisable_warning_filter (pytester : Pytester ) -> None :
302
294
# note that the host pytest warning filter is disabled and the pytester
303
295
# warning filter applies during config teardown of unraisablehook.
@@ -306,6 +298,9 @@ def test_create_task_raises_unraisable_warning_filter(pytester: Pytester) -> Non
306
298
# the issue
307
299
pytester .makepyfile (
308
300
test_it = """
301
+ # Should catch the unraisable exception even if gc is disabled.
302
+ import gc; gc.disable()
303
+
309
304
import asyncio
310
305
import pytest
311
306
@@ -318,11 +313,11 @@ def test_scheduler_must_be_created_within_running_loop() -> None:
318
313
"""
319
314
)
320
315
321
- with _disable_gc ():
322
- result = pytester .runpytest ("-Werror" )
316
+ result = pytester .runpytest_subprocess ("-Werror" )
323
317
324
- # TODO: should be a test failure or error
325
- assert result .ret == pytest .ExitCode .INTERNAL_ERROR
318
+ # TODO: Should be a test failure or error. Currently the exception
319
+ # propagates all the way to the top resulting in exit code 1.
320
+ assert result .ret == 1
326
321
327
322
result .assert_outcomes (passed = 1 )
328
323
result .stderr .fnmatch_lines ("RuntimeWarning: coroutine 'my_task' was never awaited" )
0 commit comments