diff --git a/Lib/test/libregrtest/tsan.py b/Lib/test/libregrtest/tsan.py index f1f8c8bde920ae..b41bea996638f3 100644 --- a/Lib/test/libregrtest/tsan.py +++ b/Lib/test/libregrtest/tsan.py @@ -36,6 +36,7 @@ # the regression test runner with the `--parallel-threads` option enabled. TSAN_PARALLEL_TESTS = [ 'test_abc', + 'test_exceptions', 'test_hashlib', ] diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index cea2f09aae5d51..f86a0d858e1b0c 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2913,7 +2913,7 @@ def force_colorized(func): def wrapper(*args, **kwargs): with force_color(True): return func(*args, **kwargs) - return wrapper + return thread_unsafe(wrapper) # modifying the environment is thread-unsafe def force_not_colorized(func): diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 57d0656487d4db..f3897d0c58288e 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -60,6 +60,7 @@ def raise_catch(self, exc, excname): self.assertEqual(buf1, buf2) self.assertEqual(exc.__name__, excname) + @support.thread_unsafe("TESTFN") def testRaising(self): self.raise_catch(AttributeError, "AttributeError") self.assertRaises(AttributeError, getattr, sys, "undefined_attribute") @@ -1398,6 +1399,7 @@ def __str__(self): self.assertRaises(TypeError, str, exc) @no_tracing + @support.thread_unsafe("captures stderr") def test_badisinstance(self): # Bug #2542: if issubclass(e, MyException) raises an exception, # it should be ignored @@ -1523,6 +1525,7 @@ def test_recursion_normalizing_infinite_exception(self): self.assertIn(b'Done.', out) + @support.thread_unsafe("uses sys.setrecursionlimit") @support.skip_emscripten_stack_overflow() def test_recursion_in_except_handler(self): @@ -1659,6 +1662,7 @@ class C(object): @cpython_only @unittest.skipIf(_testcapi is None, "requires _testcapi") + @support.thread_unsafe("gc_collect()") def test_memory_error_cleanup(self): # Issue #5437: preallocated MemoryError instances should not keep # traceback objects alive. @@ -1708,6 +1712,7 @@ def test_errno_ENOTDIR(self): os.listdir(__file__) self.assertEqual(cm.exception.errno, errno.ENOTDIR, cm.exception) + @support.thread_unsafe("uses catch_unraisable_exception") def test_unraisable(self): # Issue #22836: PyErr_WriteUnraisable() should give sensible reports class BrokenDel: @@ -1727,6 +1732,7 @@ def __del__(self): f"deallocator {obj_repr}") self.assertIsNotNone(cm.unraisable.exc_traceback) + @support.thread_unsafe("captures stderr") def test_unhandled(self): # Check for sensible reporting of unhandled exceptions for exc_type in (ValueError, BrokenStrException): @@ -1826,6 +1832,7 @@ def g(): next(i) @unittest.skipUnless(__debug__, "Won't work if __debug__ is False") + @support.thread_unsafe("modifies global AssertionError") def test_assert_shadowing(self): # Shadowing AssertionError would cause the assert statement to # misbehave. @@ -1917,6 +1924,7 @@ def test_name_error_has_name(self): except NameError as exc: self.assertEqual("bluch", exc.name) + @support.thread_unsafe("captures stderr") def test_issue45826(self): # regression test for bpo-45826 def f(): @@ -1933,6 +1941,7 @@ def f(): self.assertIn("aab", err.getvalue()) + @support.thread_unsafe("captures stderr") def test_issue45826_focused(self): def f(): try: @@ -2053,6 +2062,7 @@ def test_reset_attributes(self): self.assertEqual(exc.name, None) self.assertEqual(exc.path, None) + @support.thread_unsafe("check_warnings") def test_non_str_argument(self): # Issue #15778 with check_warnings(('', BytesWarning), quiet=True): @@ -2335,6 +2345,7 @@ class MySyntaxError(SyntaxError): ^^^^^ """, err.getvalue()) + @support.thread_unsafe("TESTFN") def test_encodings(self): self.addCleanup(unlink, TESTFN) source = ( diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c index dbd19d7755c237..28d803e6f999f9 100644 --- a/Python/legacy_tracing.c +++ b/Python/legacy_tracing.c @@ -528,6 +528,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) static Py_ssize_t setup_tracing(PyThreadState *tstate, Py_tracefunc func, PyObject *arg, PyObject **old_traceobj) { + assert(tstate->interp->sys_tracing_threads >= 0); *old_traceobj = NULL; /* Setup PEP 669 monitoring callbacks and events. */ if (!tstate->interp->sys_trace_initialized) {