From 6622c55fd478956c5de1666a2c3752ca02327244 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Sat, 19 Jul 2025 13:23:55 +0200 Subject: [PATCH 01/29] gh-135427: Fix DeprecationWarning for os.fork when run in threads with -Werror --- Lib/test/_test_multiprocessing.py | 66 ++++++++++++++++++++++++++++++- Modules/posixmodule.c | 2 +- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index a1259ff1d63d18..3f2b776ed0e0f2 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -39,7 +39,7 @@ from test.support import socket_helper from test.support import threading_helper from test.support import warnings_helper - +from test.support.script_helper import run_python_until_end # Skip tests if _multiprocessing wasn't built. _multiprocessing = import_helper.import_module('_multiprocessing') @@ -7142,3 +7142,67 @@ class SemLock(_multiprocessing.SemLock): name = f'test_semlock_subclass-{os.getpid()}' s = SemLock(1, 0, 10, name, False) _multiprocessing.sem_unlink(name) + + +@unittest.skipIf(sys.platform != "linux", "Linux only") +class ForkInThreads(unittest.TestCase): + + def test_fork(self): + code = """ + import os, sys, threading, time + + t = threading.Thread(target=time.sleep, args=(1,), daemon=True) + t.start() + + assert threading.active_count() == 2 + + pid = os.fork() + if pid < 0: + print("Fork failed") + elif pid == 0: + print("In child") + sys.exit(0) + print("In parent") + """ + + res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='always') + self.assertIn(b'In child', res.out) + self.assertIn(b'In parent', res.out) + self.assertIn(b'DeprecationWarning', res.err) + self.assertIn(b'is multi-threaded, use of fork() may lead to deadlocks in the child', res.err) + + res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='error') + self.assertIn(b'In child', res.out) + self.assertIn(b'In parent', res.out) + self.assertIn(b'DeprecationWarning', res.err) + self.assertIn(b'is multi-threaded, use of fork() may lead to deadlocks in the child', res.err) + + def test_forkpty(self): + code = """ + import os, sys, threading, time + + t = threading.Thread(target=time.sleep, args=(1,), daemon=True) + t.start() + + assert threading.active_count() == 2 + + pid, _ = os.forkpty() + if pid < 0: + print(f"forkpty failed") + elif pid == 0: + print(f"In child") + sys.exit(0) + print(f"In parent") + """ + + res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='always') + print(res) + self.assertIn(b'In parent', res.out) + self.assertIn(b'DeprecationWarning', res.err) + self.assertIn(b'is multi-threaded, use of forkpty() may lead to deadlocks in the child', res.err) + + res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='error') + print(res) + self.assertIn(b'In parent', res.out) + self.assertIn(b'DeprecationWarning', res.err) + self.assertIn(b'is multi-threaded, use of forkpty() may lead to deadlocks in the child', res.err) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 47eaf5cd428a53..7edd7c1d47c0c1 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8086,7 +8086,7 @@ warn_about_fork_with_threads(const char* name) getpid(), #endif name); - PyErr_Clear(); + PyErr_WriteUnraisable(NULL); } } #endif // HAVE_FORK1 || HAVE_FORKPTY || HAVE_FORK From bf97fe0de9d4fb669117d5bc79ff3f151adc9e95 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sat, 19 Jul 2025 11:53:19 +0000 Subject: [PATCH 02/29] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst diff --git a/Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst b/Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst new file mode 100644 index 00000000000000..4e0999e2635ba9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst @@ -0,0 +1 @@ +A DeprecationWarning is now provided for os.fork and os.forkpty when run within a thread with -Werror. From 3482918ddbd73176c280aa4d54dccdeb03ccaac4 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Sat, 19 Jul 2025 15:34:41 +0200 Subject: [PATCH 03/29] gh-135427: check that exception occured, and also clear later the exception. --- Modules/posixmodule.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7edd7c1d47c0c1..47ed8e0cd8c0b7 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8086,7 +8086,10 @@ warn_about_fork_with_threads(const char* name) getpid(), #endif name); - PyErr_WriteUnraisable(NULL); + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(NULL); + PyErr_Clear(); + } } } #endif // HAVE_FORK1 || HAVE_FORKPTY || HAVE_FORK From 1a207482da195b674ce3d18a18b8bd45e489a95d Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Sun, 20 Jul 2025 15:06:22 +0200 Subject: [PATCH 04/29] Behavior changed to raise an exception when fork is used within a thread. Started to fix tests. --- Lib/test/_test_multiprocessing.py | 25 ++++++++++++++----------- Modules/posixmodule.c | 24 ++++++++++++------------ 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 3f2b776ed0e0f2..c0cdb1f1f330df 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -39,7 +39,7 @@ from test.support import socket_helper from test.support import threading_helper from test.support import warnings_helper -from test.support.script_helper import run_python_until_end +from test.support.script_helper import assert_python_failure, assert_python_ok # Skip tests if _multiprocessing wasn't built. _multiprocessing = import_helper.import_module('_multiprocessing') @@ -6284,7 +6284,15 @@ def test_list(self): def setUp(self): self.manager = self.manager_class() - self.manager.start() + # gh-135427 + # In some of the tests, a forked child forks another child of itself. In that case, using + # warnings_helper.ignore_warnings decorator does not actually ignore the warning from that + # child of child, and a warnings_helper.ignore_warnings exception is raised. + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', + message=".*fork.*may lead to deadlocks in the child.*", + category=DeprecationWarning) + self.manager.start() self.proc = None def tearDown(self): @@ -7165,15 +7173,13 @@ def test_fork(self): print("In parent") """ - res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='always') + res = assert_python_ok("-c", code, PYTHONWARNINGS='always') self.assertIn(b'In child', res.out) self.assertIn(b'In parent', res.out) self.assertIn(b'DeprecationWarning', res.err) self.assertIn(b'is multi-threaded, use of fork() may lead to deadlocks in the child', res.err) - res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='error') - self.assertIn(b'In child', res.out) - self.assertIn(b'In parent', res.out) + res = assert_python_failure("-c", code, PYTHONWARNINGS='error') self.assertIn(b'DeprecationWarning', res.err) self.assertIn(b'is multi-threaded, use of fork() may lead to deadlocks in the child', res.err) @@ -7195,14 +7201,11 @@ def test_forkpty(self): print(f"In parent") """ - res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='always') - print(res) + res = assert_python_ok("-c", code, PYTHONWARNINGS='always') self.assertIn(b'In parent', res.out) self.assertIn(b'DeprecationWarning', res.err) self.assertIn(b'is multi-threaded, use of forkpty() may lead to deadlocks in the child', res.err) - res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='error') - print(res) - self.assertIn(b'In parent', res.out) + res = assert_python_failure("-c", code, PYTHONWARNINGS='error') self.assertIn(b'DeprecationWarning', res.err) self.assertIn(b'is multi-threaded, use of forkpty() may lead to deadlocks in the child', res.err) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 47ed8e0cd8c0b7..a770c1b7794da4 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7992,7 +7992,7 @@ os_register_at_fork_impl(PyObject *module, PyObject *before, // // This should only be called from the parent process after // PyOS_AfterFork_Parent(). -static void +static int warn_about_fork_with_threads(const char* name) { // It's not safe to issue the warning while the world is stopped, because @@ -8043,14 +8043,14 @@ warn_about_fork_with_threads(const char* name) PyObject *threading = PyImport_GetModule(&_Py_ID(threading)); if (!threading) { PyErr_Clear(); - return; + return 0; } PyObject *threading_active = PyObject_GetAttr(threading, &_Py_ID(_active)); if (!threading_active) { PyErr_Clear(); Py_DECREF(threading); - return; + return 0; } PyObject *threading_limbo = PyObject_GetAttr(threading, &_Py_ID(_limbo)); @@ -8058,7 +8058,7 @@ warn_about_fork_with_threads(const char* name) PyErr_Clear(); Py_DECREF(threading); Py_DECREF(threading_active); - return; + return 0; } Py_DECREF(threading); // Duplicating what threading.active_count() does but without holding @@ -8074,7 +8074,7 @@ warn_about_fork_with_threads(const char* name) Py_DECREF(threading_limbo); } if (num_python_threads > 1) { - PyErr_WarnFormat( + return PyErr_WarnFormat( PyExc_DeprecationWarning, 1, #ifdef HAVE_GETPID "This process (pid=%d) is multi-threaded, " @@ -8086,11 +8086,8 @@ warn_about_fork_with_threads(const char* name) getpid(), #endif name); - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(NULL); - PyErr_Clear(); - } } + return 0; } #endif // HAVE_FORK1 || HAVE_FORKPTY || HAVE_FORK @@ -8129,7 +8126,8 @@ os_fork1_impl(PyObject *module) /* parent: release the import lock. */ PyOS_AfterFork_Parent(); // After PyOS_AfterFork_Parent() starts the world to avoid deadlock. - warn_about_fork_with_threads("fork1"); + if (warn_about_fork_with_threads("fork1") < 0) + return NULL; } if (pid == -1) { errno = saved_errno; @@ -8178,7 +8176,8 @@ os_fork_impl(PyObject *module) /* parent: release the import lock. */ PyOS_AfterFork_Parent(); // After PyOS_AfterFork_Parent() starts the world to avoid deadlock. - warn_about_fork_with_threads("fork"); + if (warn_about_fork_with_threads("fork") < 0) + return NULL; } if (pid == -1) { errno = saved_errno; @@ -9033,7 +9032,8 @@ os_forkpty_impl(PyObject *module) /* parent: release the import lock. */ PyOS_AfterFork_Parent(); // After PyOS_AfterFork_Parent() starts the world to avoid deadlock. - warn_about_fork_with_threads("forkpty"); + if (warn_about_fork_with_threads("forkpty") < 0) + return NULL; } if (pid == -1) { return posix_error(); From 9bead0e39d45d34117aaf8485472c7d82c943576 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Sun, 20 Jul 2025 16:02:34 +0200 Subject: [PATCH 05/29] Seems like test_multiprocessing fork deprecation warnings are suppressed. --- Lib/test/_test_multiprocessing.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index c0cdb1f1f330df..794a12211a751e 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -1765,6 +1765,7 @@ def test_notify(self): threading_helper.join_thread(t) join_process(p) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_notify_all(self): cond = self.Condition() sleeping = self.Semaphore(0) @@ -1834,6 +1835,7 @@ def test_notify_all(self): # NOTE: join_process and join_thread are the same threading_helper.join_thread(w) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_notify_n(self): cond = self.Condition() sleeping = self.Semaphore(0) @@ -1974,6 +1976,7 @@ def _test_wait_result(cls, c, pid): if pid is not None: os.kill(pid, signal.SIGINT) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_wait_result(self): if isinstance(self, ProcessesMixin) and sys.platform != 'win32': pid = os.getpid() @@ -2801,8 +2804,16 @@ class _TestPool(BaseTestCase): @classmethod def setUpClass(cls): - super().setUpClass() - cls.pool = cls.Pool(4) + # gh-135427 + # In some of the tests, a forked child forks another child of itself. In that case, using + # warnings_helper.ignore_warnings decorator does not actually ignore the warning from that + # child of child, and a warnings_helper.ignore_warnings exception is raised. + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', + message=".*fork.*may lead to deadlocks in the child.*", + category=DeprecationWarning) + super().setUpClass() + cls.pool = cls.Pool(4) @classmethod def tearDownClass(cls): @@ -6982,8 +6993,16 @@ def Pool(cls, *args, **kwds): @classmethod def setUpClass(cls): - super().setUpClass() - cls.manager = multiprocessing.Manager() + # gh-135427 + # In some of the tests, a forked child forks another child of itself. In that case, using + # warnings_helper.ignore_warnings decorator does not actually ignore the warning from that + # child of child, and a warnings_helper.ignore_warnings exception is raised. + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', + message=".*fork.*may lead to deadlocks in the child.*", + category=DeprecationWarning) + super().setUpClass() + cls.manager = multiprocessing.Manager() @classmethod def tearDownClass(cls): From d5336dc0109bfd53809271d9a4c0a46060ebf8af Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Sun, 20 Jul 2025 16:56:22 +0200 Subject: [PATCH 06/29] Warning of deprecated fork are suppressed in more tests. --- Lib/test/_test_multiprocessing.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 794a12211a751e..b79200a6d1566a 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -1118,6 +1118,7 @@ def _test_put(cls, queue, child_can_start, parent_can_continue): queue.get() parent_can_continue.set() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_put(self): MAXSIZE = 6 queue = self.Queue(maxsize=MAXSIZE) @@ -1187,6 +1188,7 @@ def _test_get(cls, queue, child_can_start, parent_can_continue): queue.put(5) parent_can_continue.set() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_get(self): queue = self.Queue() child_can_start = self.Event() @@ -1248,6 +1250,7 @@ def _test_fork(cls, queue): # process cannot shutdown until the feeder thread has finished # pushing items onto the pipe. + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_fork(self): # Old versions of Queue would fail to create a new feeder # thread for a forked process if the original process had its @@ -1298,6 +1301,7 @@ def _test_task_done(cls, q): time.sleep(DELTA) q.task_done() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_task_done(self): queue = self.JoinableQueue() @@ -2912,6 +2916,7 @@ def test_async(self): self.assertEqual(get(), 49) self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_async_timeout(self): p = self.Pool(3) try: @@ -3009,6 +3014,7 @@ def test_imap_unordered_handle_iterable_exception(self): self.assertIn(value, expected_values) expected_values.remove(value) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_make_pool(self): expected_error = (RemoteError if self.TYPE == 'manager' else ValueError) @@ -3024,6 +3030,7 @@ def test_make_pool(self): p.close() p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_terminate(self): # Simulate slow tasks which take "forever" to complete sleep_time = support.LONG_TIMEOUT @@ -3041,6 +3048,7 @@ def test_terminate(self): p.terminate() p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_empty_iterable(self): # See Issue 12157 p = self.Pool(1) @@ -3053,6 +3061,7 @@ def test_empty_iterable(self): p.close() p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_context(self): if self.TYPE == 'processes': L = list(range(10)) @@ -3067,6 +3076,7 @@ def test_context(self): def _test_traceback(cls): raise RuntimeError(123) # some comment + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_traceback(self): # We want ensure that the traceback from the child process is # contained in the traceback raised in the main process. @@ -3106,9 +3116,11 @@ def test_traceback(self): p.join() @classmethod + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def _test_wrapped_exception(cls): raise RuntimeError('foo') + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_wrapped_exception(self): # Issue #20980: Should not wrap exception when using thread pool with self.Pool(1) as p: @@ -3116,6 +3128,7 @@ def test_wrapped_exception(self): p.apply(self._test_wrapped_exception) p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_map_no_failfast(self): # Issue #23992: the fail-fast behaviour when an exception is raised # during map() would make Pool.join() deadlock, because a worker @@ -3151,6 +3164,7 @@ def test_release_task_refs(self): # they were released too. self.assertEqual(CountedObject.n_instances, 0) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_enter(self): if self.TYPE == 'manager': self.skipTest("test not applicable to manager") @@ -3167,6 +3181,7 @@ def test_enter(self): pass pool.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_resource_warning(self): if self.TYPE == 'manager': self.skipTest("test not applicable to manager") @@ -3232,6 +3247,7 @@ def errback(exc): class _TestPoolWorkerLifetime(BaseTestCase): ALLOWED_TYPES = ('processes', ) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_pool_worker_lifetime(self): p = multiprocessing.Pool(3, maxtasksperchild=10) self.assertEqual(3, len(p._pool)) @@ -3261,6 +3277,7 @@ def test_pool_worker_lifetime(self): p.close() p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_pool_worker_lifetime_early_close(self): # Issue #10332: closing a pool whose workers have limited lifetimes # before all the tasks completed would make join() hang. @@ -4048,6 +4065,7 @@ def _remote(cls, conn): conn.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_pickling(self): families = self.connection.families From ae3a5ed6a4c71743fb8a7b94ec52aea90a813546 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Sun, 20 Jul 2025 17:54:10 +0200 Subject: [PATCH 07/29] WIP - suppressing warnings in tests that fail in the tests running online --- Lib/test/test_asyncio/test_unix_events.py | 6 +++++- Lib/test/test_builtin.py | 2 ++ Lib/test/test_fork1.py | 4 +++- Lib/test/test_mailbox.py | 3 ++- Lib/test/test_pty.py | 4 +++- Lib/test/test_random.py | 3 +++ Lib/test/test_support.py | 1 + 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 22982dc9d8aefe..f2d17cb3187f26 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -15,7 +15,7 @@ from unittest import mock from test import support -from test.support import os_helper +from test.support import os_helper, warnings_helper from test.support import socket_helper from test.support import wait_process from test.support import hashlib_helper @@ -1182,6 +1182,7 @@ async def runner(): @support.requires_fork() class TestFork(unittest.IsolatedAsyncioTestCase): + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 async def test_fork_not_share_event_loop(self): # The forked process should not share the event loop with the parent loop = asyncio.get_running_loop() @@ -1206,6 +1207,7 @@ async def test_fork_not_share_event_loop(self): self.assertEqual(result, b'NO LOOP') wait_process(pid, exitcode=0) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @hashlib_helper.requires_hashdigest('md5') @support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True) def test_fork_signal_handling(self): @@ -1253,6 +1255,7 @@ async def func(): self.assertFalse(parent_handled.is_set()) self.assertTrue(child_handled.is_set()) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @hashlib_helper.requires_hashdigest('md5') @support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True) def test_fork_asyncio_run(self): @@ -1273,6 +1276,7 @@ async def child_main(): self.assertEqual(result.value, 42) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @hashlib_helper.requires_hashdigest('md5') @support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True) def test_fork_asyncio_subprocess(self): diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 8830641f0abdc7..dab7db762137ac 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -31,6 +31,7 @@ from test import support from test.support import cpython_only, swap_attr from test.support import async_yield, run_yielding_async_fn +from test.support import warnings_helper from test.support.import_helper import import_module from test.support.os_helper import (EnvironmentVarGuard, TESTFN, unlink) from test.support.script_helper import assert_python_ok @@ -2545,6 +2546,7 @@ def run_child(self, child, terminal_input): finally: signal.signal(signal.SIGHUP, old_sighup) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def _run_child(self, child, terminal_input): r, w = os.pipe() # Pipe test results from child back to parent try: diff --git a/Lib/test/test_fork1.py b/Lib/test/test_fork1.py index a6523bbc518176..d7306f5b132b34 100644 --- a/Lib/test/test_fork1.py +++ b/Lib/test/test_fork1.py @@ -11,6 +11,7 @@ from test.fork_wait import ForkWait from test import support +from test.support import warnings_helper # Skip test if fork does not exist. @@ -19,6 +20,7 @@ class ForkTest(ForkWait): + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_threaded_import_lock_fork(self): """Check fork() in main thread works while a subthread is doing an import""" import_started = threading.Event() @@ -61,7 +63,7 @@ def importer(): except OSError: pass - + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_nested_import_lock_fork(self): """Check fork() in main thread works while the main thread is doing an import""" exitcode = 42 diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 0169948e453438..a80efdbb1a0f39 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -8,7 +8,7 @@ import io import tempfile from test import support -from test.support import import_helper +from test.support import import_helper, warnings_helper from test.support import os_helper from test.support import refleak_helper from test.support import socket_helper @@ -1212,6 +1212,7 @@ def test_add_and_close(self): self.assertEqual(contents, f.read()) self._box = self._factory(self._path) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.requires_fork() @unittest.skipUnless(hasattr(socket, 'socketpair'), "Test needs socketpair().") def test_lock_conflict(self): diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index 4836f38c388c05..fc18854785dab7 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -1,6 +1,6 @@ import unittest from test.support import ( - is_android, is_apple_mobile, is_emscripten, is_wasi, reap_children, verbose + is_android, is_apple_mobile, is_emscripten, is_wasi, reap_children, verbose, warnings_helper ) from test.support.import_helper import import_module from test.support.os_helper import TESTFN, unlink @@ -194,6 +194,7 @@ def test_openpty(self): s2 = _readline(master_fd) self.assertEqual(b'For my pet fish, Eric.\n', normalize_output(s2)) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_fork(self): debug("calling pty.fork()") pid, master_fd = pty.fork() @@ -295,6 +296,7 @@ def test_master_read(self): self.assertEqual(data, b"") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_spawn_doesnt_hang(self): self.addCleanup(unlink, TESTFN) with open(TESTFN, 'wb') as f: diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index 0217ebd132b110..f2b6dc57f0a5ad 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -14,6 +14,8 @@ from fractions import Fraction from collections import abc, Counter +from test.support import warnings_helper + class MyIndex: def __init__(self, value): @@ -1399,6 +1401,7 @@ def test__all__(self): # tests validity but not completeness of the __all__ list self.assertTrue(set(random.__all__) <= set(dir(random))) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @test.support.requires_fork() def test_after_fork(self): # Test the global Random instance gets reseeded in child diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index cb31122fee9642..4e45456210fa42 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -484,6 +484,7 @@ def test_check__all__(self): self.assertRaises(AssertionError, support.check__all__, self, unittest) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(hasattr(os, 'waitpid') and hasattr(os, 'WNOHANG'), 'need os.waitpid() and os.WNOHANG') @support.requires_fork() From f768f5d7a0a0f921433a50c5dcdecbf3911232f0 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Mon, 21 Jul 2025 16:56:29 +0200 Subject: [PATCH 08/29] WIP - continuing suppressing warnings in tests. --- Lib/test/test_os.py | 18 ++++++++++++++++++ Lib/test/test_socketserver.py | 7 +++++++ Lib/test/test_tracemalloc.py | 1 + Lib/test/test_uuid.py | 1 + 4 files changed, 27 insertions(+) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index de3a17fe893170..7c3d91ea8ed738 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3518,6 +3518,7 @@ def test_getppid(self): self.assertEqual(error, b'') self.assertEqual(int(stdout), os.getpid()) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def check_waitpid(self, code, exitcode, callback=None): if sys.platform == 'win32': # On Windows, os.spawnv() simply joins arguments with spaces: @@ -3620,30 +3621,35 @@ def create_args(self, *, with_env=False, use_bytes=False): return program, args + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnl') def test_spawnl(self): program, args = self.create_args() exitcode = os.spawnl(os.P_WAIT, program, *args) self.assertEqual(exitcode, self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnle') def test_spawnle(self): program, args = self.create_args(with_env=True) exitcode = os.spawnle(os.P_WAIT, program, *args, self.env) self.assertEqual(exitcode, self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnlp') def test_spawnlp(self): program, args = self.create_args() exitcode = os.spawnlp(os.P_WAIT, program, *args) self.assertEqual(exitcode, self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnlpe') def test_spawnlpe(self): program, args = self.create_args(with_env=True) exitcode = os.spawnlpe(os.P_WAIT, program, *args, self.env) self.assertEqual(exitcode, self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnv') def test_spawnv(self): program, args = self.create_args() @@ -3654,30 +3660,35 @@ def test_spawnv(self): exitcode = os.spawnv(os.P_WAIT, FakePath(program), args) self.assertEqual(exitcode, self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnve') def test_spawnve(self): program, args = self.create_args(with_env=True) exitcode = os.spawnve(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnvp') def test_spawnvp(self): program, args = self.create_args() exitcode = os.spawnvp(os.P_WAIT, program, args) self.assertEqual(exitcode, self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnvpe') def test_spawnvpe(self): program, args = self.create_args(with_env=True) exitcode = os.spawnvpe(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnv') def test_nowait(self): program, args = self.create_args() pid = os.spawnv(os.P_NOWAIT, program, args) support.wait_process(pid, exitcode=self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnve') def test_spawnve_bytes(self): # Test bytes handling in parse_arglist and parse_envlist (#28114) @@ -3685,18 +3696,21 @@ def test_spawnve_bytes(self): exitcode = os.spawnve(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnl') def test_spawnl_noargs(self): program, __ = self.create_args() self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program) self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program, '') + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnle') def test_spawnle_noargs(self): program, __ = self.create_args() self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, {}) self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, '', {}) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnv') def test_spawnv_noargs(self): program, __ = self.create_args() @@ -3705,6 +3719,7 @@ def test_spawnv_noargs(self): self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ('',)) self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ['']) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnve') def test_spawnve_noargs(self): program, __ = self.create_args() @@ -3761,10 +3776,12 @@ def _test_invalid_env(self, spawn): exitcode = spawn(os.P_WAIT, program, args, newenv) self.assertEqual(exitcode, 0) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnve') def test_spawnve_invalid_env(self): self._test_invalid_env(os.spawnve) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_os_func('spawnvpe') def test_spawnvpe_invalid_env(self): self._test_invalid_env(os.spawnvpe) @@ -4881,6 +4898,7 @@ def test_posix_pty_functions(self): self.addCleanup(os.close, son_fd) self.assertEqual(os.ptsname(mother_fd), os.ttyname(son_fd)) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(hasattr(os, 'spawnl'), "need os.spawnl()") @support.requires_subprocess() def test_pipe_spawnl(self): diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 0f62f9eb200e42..958adda78db4fa 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -43,6 +43,7 @@ def receive(sock, n, timeout=test.support.SHORT_TIMEOUT): raise RuntimeError("timed out on %r" % (sock,)) +@warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @test.support.requires_fork() @contextlib.contextmanager def simple_subprocess(testcase): @@ -173,6 +174,7 @@ def test_ThreadingTCPServer(self): socketserver.StreamRequestHandler, self.stream_examine) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_forking def test_ForkingTCPServer(self): with simple_subprocess(self): @@ -192,6 +194,7 @@ def test_ThreadingUnixStreamServer(self): socketserver.StreamRequestHandler, self.stream_examine) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_unix_sockets @requires_forking def test_ForkingUnixStreamServer(self): @@ -210,6 +213,7 @@ def test_ThreadingUDPServer(self): socketserver.DatagramRequestHandler, self.dgram_examine) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_forking def test_ForkingUDPServer(self): with simple_subprocess(self): @@ -229,6 +233,7 @@ def test_ThreadingUnixDatagramServer(self): socketserver.DatagramRequestHandler, self.dgram_examine) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_unix_sockets @requires_forking def test_ForkingUnixDatagramServer(self): @@ -314,11 +319,13 @@ def test_threading_not_handled(self): self.assertIs(cm.exc_type, SystemExit) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_forking def test_forking_handled(self): ForkingErrorTestServer(ValueError) self.check_result(handled=True) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @requires_forking def test_forking_not_handled(self): ForkingErrorTestServer(SystemExit) diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index 6dc6880ff8c356..3b7cc5a7738e98 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -354,6 +354,7 @@ def fork_child(self): # everything is fine return 0 + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.requires_fork() def test_fork(self): # check that tracemalloc is still working after fork diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index 0e1a723ce3a151..f582744e15575b 100755 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -1112,6 +1112,7 @@ def test_uuid8_uniqueness(self): versions = {u.version for u in uuids} self.assertSetEqual(versions, {8}) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.requires_fork() def testIssue8621(self): # On at least some versions of OSX self.uuid.uuid4 generates From 6308e192891379c2dd88140c8232d93a44d27663 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Mon, 21 Jul 2025 17:13:40 +0200 Subject: [PATCH 09/29] WIP - fix imports. --- Lib/test/test_socketserver.py | 1 + Lib/test/test_tracemalloc.py | 2 +- Lib/test/test_uuid.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 958adda78db4fa..4b2e479060bc5a 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -17,6 +17,7 @@ from test.support import os_helper from test.support import socket_helper from test.support import threading_helper +from test.support import warnings_helper test.support.requires("network") diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index 3b7cc5a7738e98..1d560be43700ac 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -8,7 +8,7 @@ from test.support.script_helper import (assert_python_ok, assert_python_failure, interpreter_requires_environment) from test import support -from test.support import force_not_colorized +from test.support import force_not_colorized, warnings_helper from test.support import os_helper from test.support import threading_helper diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index f582744e15575b..225dd70d0d2762 100755 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -13,7 +13,7 @@ from unittest import mock from test import support -from test.support import import_helper +from test.support import import_helper, warnings_helper from test.support.script_helper import assert_python_ok py_uuid = import_helper.import_fresh_module('uuid', blocked=['_uuid']) From 8955136bc9d23ab83262e78452e0ae01b9d253f8 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Mon, 21 Jul 2025 17:50:07 +0200 Subject: [PATCH 10/29] WIP - more suppressing of warnings --- Lib/test/test_concurrent_futures/util.py | 11 ++++++++++- Lib/test/test_logging.py | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_concurrent_futures/util.py b/Lib/test/test_concurrent_futures/util.py index b12940414d9142..6e63aa1307cdc8 100644 --- a/Lib/test/test_concurrent_futures/util.py +++ b/Lib/test/test_concurrent_futures/util.py @@ -11,6 +11,7 @@ from test import support from test.support import threading_helper +import warnings def create_future(state=PENDING, exception=None, result=None): @@ -51,7 +52,15 @@ def setUp(self): max_workers=self.worker_count, mp_context=self.get_context(), **self.executor_kwargs) - self.manager = self.get_context().Manager() + # gh-135427 + # In some of the tests, a forked child forks another child of itself. In that case, using + # warnings_helper.ignore_warnings decorator does not actually ignore the warning from that + # child of child, and a warnings_helper.ignore_warnings exception is raised. + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', + message=".*fork.*may lead to deadlocks in the child.*", + category=DeprecationWarning) + self.manager = self.get_context().Manager() else: self.executor = self.executor_type( max_workers=self.worker_count, diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 275f7ce47d09b5..81eaeadd86cf0e 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -730,6 +730,7 @@ def remove_loop(fname, tries): # based on os.fork existing because that is what users and this test use. # This helps ensure that when fork exists (the important concept) that the # register_at_fork mechanism is also present and used. + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.requires_fork() @threading_helper.requires_working_threading() @skip_if_asan_fork @@ -4067,6 +4068,7 @@ def test_config_reject_simple_queue_handler_multiprocessing_context(self): with self.assertRaises(ValueError): self._apply_simple_queue_listener_configuration(qspec) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @skip_if_tsan_fork @support.requires_subprocess() @unittest.skipUnless(support.Py_DEBUG, "requires a debug build for testing" From 8731cbadeeab3216e73972009fb562a8711ef667 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Mon, 21 Jul 2025 18:44:51 +0200 Subject: [PATCH 11/29] WIP - fix ignore_warnings to wrap also async functions --- Lib/test/support/warnings_helper.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Lib/test/support/warnings_helper.py b/Lib/test/support/warnings_helper.py index 5f6f14afd74a6e..536a4f88278456 100644 --- a/Lib/test/support/warnings_helper.py +++ b/Lib/test/support/warnings_helper.py @@ -5,6 +5,8 @@ import sys import warnings +import inspect + def import_deprecated(name): """Import *name* while suppressing DeprecationWarning.""" @@ -49,12 +51,20 @@ def ignore_warnings(*, category): more noisy and tools like 'git blame' less useful. """ def decorator(test): - @functools.wraps(test) - def wrapper(self, *args, **kwargs): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=category) - return test(self, *args, **kwargs) - return wrapper + if inspect.iscoroutinefunction(test): + @functools.wraps(test) + async def async_wrapper(self, *args, **kwargs): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=category) + return await test(self, *args, **kwargs) + return async_wrapper + else: + @functools.wraps(test) + def wrapper(self, *args, **kwargs): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=category) + return test(self, *args, **kwargs) + return wrapper return decorator From 41e833775607662780ba51aa82a1762518dae1f3 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Mon, 21 Jul 2025 21:12:12 +0200 Subject: [PATCH 12/29] WIP - more suppress of warnings. --- .../test_concurrent_futures/test_as_completed.py | 4 ++++ Lib/test/test_concurrent_futures/test_shutdown.py | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_concurrent_futures/test_as_completed.py b/Lib/test/test_concurrent_futures/test_as_completed.py index c90b0021d85fc7..9e5d06c01af993 100644 --- a/Lib/test/test_concurrent_futures/test_as_completed.py +++ b/Lib/test/test_concurrent_futures/test_as_completed.py @@ -7,6 +7,7 @@ CANCELLED_AND_NOTIFIED, FINISHED, Future) from test import support +from test.support import warnings_helper from .util import ( PENDING_FUTURE, RUNNING_FUTURE, @@ -19,6 +20,7 @@ def mul(x, y): class AsCompletedTests: + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_no_timeout(self): future1 = self.executor.submit(mul, 2, 21) future2 = self.executor.submit(mul, 7, 6) @@ -35,6 +37,7 @@ def test_no_timeout(self): future1, future2]), completed) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_future_times_out(self): """Test ``futures.as_completed`` timing out before completing it's final future.""" @@ -62,6 +65,7 @@ def test_future_times_out(self): # Check that ``future`` wasn't completed. self.assertEqual(completed_futures, already_completed) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_duplicate_futures(self): # Issue 20367. Duplicate futures should not raise exceptions or give # duplicate responses. diff --git a/Lib/test/test_concurrent_futures/test_shutdown.py b/Lib/test/test_concurrent_futures/test_shutdown.py index 99b315b47e2530..70feeab4d04cd3 100644 --- a/Lib/test/test_concurrent_futures/test_shutdown.py +++ b/Lib/test/test_concurrent_futures/test_shutdown.py @@ -6,6 +6,7 @@ from concurrent import futures from test import support +from test.support import warnings_helper from test.support.script_helper import assert_python_ok from .util import ( @@ -77,12 +78,14 @@ def run_last(): self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) self.assertEqual(out.strip(), b"runtime-error") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_hang_issue12364(self): fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] self.executor.shutdown() for f in fs: f.result() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_cancel_futures(self): assert self.worker_count <= 5, "test needs few workers" fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] @@ -128,6 +131,7 @@ def test_hang_gh83386(self): self.assertFalse(err) self.assertEqual(out.strip(), b"apple") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_hang_gh94440(self): """shutdown(wait=True) doesn't hang when a future was submitted and quickly canceled right before shutdown. @@ -171,6 +175,7 @@ def acquire_lock(lock): for t in self.executor._threads: t.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_context_manager_shutdown(self): with futures.ThreadPoolExecutor(max_workers=5) as e: executor = e @@ -180,6 +185,7 @@ def test_context_manager_shutdown(self): for t in executor._threads: t.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_del_shutdown(self): executor = futures.ThreadPoolExecutor(max_workers=5) res = executor.map(abs, range(-5, 5)) @@ -193,6 +199,7 @@ def test_del_shutdown(self): # executor got shutdown. assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_shutdown_no_wait(self): # Ensure that the executor cleans up the threads when calling # shutdown with wait=False @@ -207,7 +214,7 @@ def test_shutdown_no_wait(self): # executor got shutdown. assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_thread_names_assigned(self): executor = futures.ThreadPoolExecutor( max_workers=5, thread_name_prefix='SpecialPool') @@ -220,6 +227,7 @@ def test_thread_names_assigned(self): self.assertRegex(t.name, r'^SpecialPool_[0-4]$') t.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_thread_names_default(self): executor = futures.ThreadPoolExecutor(max_workers=5) executor.map(abs, range(-5, 5)) @@ -253,6 +261,7 @@ def test_cancel_futures_wait_false(self): class ProcessPoolShutdownTest(ExecutorShutdownTest): + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_processes_terminate(self): def acquire_lock(lock): lock.acquire() @@ -276,6 +285,7 @@ def acquire_lock(lock): for p in processes.values(): p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_context_manager_shutdown(self): with futures.ProcessPoolExecutor( max_workers=5, mp_context=self.get_context()) as e: @@ -286,6 +296,7 @@ def test_context_manager_shutdown(self): for p in processes.values(): p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_del_shutdown(self): executor = futures.ProcessPoolExecutor( max_workers=5, mp_context=self.get_context()) @@ -308,6 +319,7 @@ def test_del_shutdown(self): # executor got shutdown. assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_shutdown_no_wait(self): # Ensure that the executor cleans up the processes when calling # shutdown with wait=False From 359b0ede5a9fc404758409d6db05f8792b606157 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Mon, 21 Jul 2025 21:24:58 +0200 Subject: [PATCH 13/29] WIP - more suppress of warnings. --- Lib/test/test_concurrent_futures/test_deadlock.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Lib/test/test_concurrent_futures/test_deadlock.py b/Lib/test/test_concurrent_futures/test_deadlock.py index a465400509d411..daf23f73efcfff 100644 --- a/Lib/test/test_concurrent_futures/test_deadlock.py +++ b/Lib/test/test_concurrent_futures/test_deadlock.py @@ -10,6 +10,7 @@ from concurrent.futures.process import BrokenProcessPool, _ThreadWakeup from test import support +from test.support import warnings_helper from .util import ( create_executor_tests, setup_module, @@ -111,6 +112,7 @@ def _fail_on_deadlock(self, executor): print(f"\nTraceback:\n {tb}", file=sys.__stderr__) self.fail(f"Executor deadlock:\n\n{tb}") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def _check_error(self, error, func, *args, ignore_stderr=False): # test for deadlock caused by crashes or exiting in a pool self.executor.shutdown(wait=True) @@ -199,6 +201,7 @@ def test_exit_during_result_unpickle_in_result_handler(self): # the result_handler thread self._check_error(BrokenProcessPool, _return_instance, ExitAtUnpickle) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.skip_if_sanitizer("UBSan: explicit SIGSEV not allowed", ub=True) def test_shutdown_deadlock(self): # Test that the pool calling shutdown do not cause deadlock @@ -212,6 +215,7 @@ def test_shutdown_deadlock(self): with self.assertRaises(BrokenProcessPool): f.result() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_shutdown_deadlock_pickle(self): # Test that the pool calling shutdown with wait=False does not cause # a deadlock if a task fails at pickle after the shutdown call. @@ -238,6 +242,7 @@ def test_shutdown_deadlock_pickle(self): # dangling threads executor_manager.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.skip_if_sanitizer("UBSan: explicit SIGSEV not allowed", ub=True) def test_crash_big_data(self): # Test that there is a clean exception instead of a deadlock when a @@ -254,6 +259,7 @@ def test_crash_big_data(self): executor.shutdown(wait=True) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_gh105829_should_not_deadlock_if_wakeup_pipe_full(self): # Issue #105829: The _ExecutorManagerThread wakeup pipe could # fill up and block. See: https://github.com/python/cpython/issues/105829 From 5277d4c50a2769800dcc2d4aef135fcdc9354a7a Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Mon, 21 Jul 2025 23:02:04 +0200 Subject: [PATCH 14/29] WIP - test.test_multiprocessing_fork gives no errors on local ubuntu 24.02 run --- Lib/test/_test_multiprocessing.py | 122 +++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 4 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index b79200a6d1566a..1d596666fe6877 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -325,6 +325,7 @@ def test_current(self): self.assertEqual(current.ident, os.getpid()) self.assertEqual(current.exitcode, None) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_set_executable(self): if self.TYPE == 'threads': self.skipTest(f'test not appropriate for {self.TYPE}') @@ -388,6 +389,7 @@ def _test(cls, q, *args, **kwds): q.put(bytes(current.authkey)) q.put(current.pid) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_parent_process_attributes(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -408,6 +410,7 @@ def _test_send_parent_process(cls, wconn): from multiprocessing.process import parent_process wconn.send([parent_process().pid, parent_process().name]) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_parent_process(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -446,6 +449,7 @@ def _test_report_parent_status(cls, wconn): parent_process().join(timeout=support.SHORT_TIMEOUT) wconn.send("alive" if parent_process().is_alive() else "not alive") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_process(self): q = self.Queue(1) e = self.Event() @@ -486,6 +490,7 @@ def test_process(self): self.assertNotIn(p, self.active_children()) close_queue(q) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(threading._HAVE_THREAD_NATIVE_ID, "needs native_id") def test_process_mainthread_native_id(self): if self.TYPE == 'threads': @@ -583,6 +588,7 @@ def handler(*args): return p.exitcode + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipIf(os.name == 'nt', "POSIX only") def test_interrupt(self): exitcode = self._kill_process(multiprocessing.Process.interrupt) @@ -591,15 +597,18 @@ def test_interrupt(self): # (KeyboardInterrupt in this case) # in multiprocessing.BaseProcess._bootstrap + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipIf(os.name == 'nt', "POSIX only") def test_interrupt_no_handler(self): exitcode = self._kill_process(multiprocessing.Process.interrupt, target=self._sleep_no_int_handler) self.assertEqual(exitcode, -signal.SIGINT) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_terminate(self): exitcode = self._kill_process(multiprocessing.Process.terminate) self.assertEqual(exitcode, -signal.SIGTERM) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_kill(self): exitcode = self._kill_process(multiprocessing.Process.kill) if os.name != 'nt': @@ -615,6 +624,7 @@ def test_cpu_count(self): self.assertIsInstance(cpus, int) self.assertGreaterEqual(cpus, 1) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_active_children(self): self.assertEqual(type(self.active_children()), list) @@ -643,6 +653,7 @@ def _test_recursion(cls, wconn, id): p.start() p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_recursion(self): rconn, wconn = self.Pipe(duplex=False) self._test_recursion(wconn, []) @@ -667,6 +678,7 @@ def test_recursion(self): def _test_sentinel(cls, event): event.wait(10.0) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_sentinel(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -689,6 +701,7 @@ def _test_close(cls, rc=0, q=None): q.get() sys.exit(rc) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_close(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -721,6 +734,7 @@ def test_close(self): close_queue(q) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.requires_resource('walltime') def test_many_processes(self): if self.TYPE == 'threads': @@ -757,6 +771,7 @@ def test_many_processes(self): for p in procs: self.assertIn(p.exitcode, exitcodes) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_lose_target_ref(self): c = DummyCallable() wr = weakref.ref(c) @@ -819,6 +834,7 @@ def func2(): threading.Thread(target=func1).start() threading.Thread(target=func2, daemon=True).start() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_wait_for_threads(self): # A child process should wait for non-daemonic threads to end # before exiting @@ -843,6 +859,7 @@ def _test_error_on_stdio_flush(self, evt, break_std_streams={}): setattr(sys, stream_name, None) evt.set() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_error_on_stdio_flush_1(self): # Check that Process works with broken standard streams streams = [io.StringIO(), None] @@ -862,6 +879,7 @@ def test_error_on_stdio_flush_1(self): finally: setattr(sys, stream_name, old_stream) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_error_on_stdio_flush_2(self): # Same as test_error_on_stdio_flush_1(), but standard streams are # broken by the child process @@ -1012,6 +1030,7 @@ class _TestSubclassingProcess(BaseTestCase): ALLOWED_TYPES = ('processes',) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_subclassing(self): uppercaser = _UpperCaser() uppercaser.daemon = True @@ -1021,6 +1040,7 @@ def test_subclassing(self): uppercaser.stop() uppercaser.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_stderr_flush(self): # sys.stderr is flushed at process shutdown (issue #13812) if self.TYPE == "threads": @@ -1051,6 +1071,7 @@ def _test_sys_exit(cls, reason, testfn): sys.stderr = open(fd, 'w', encoding="utf-8", closefd=False) sys.exit(reason) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_sys_exit(self): # See Issue 13854 if self.TYPE == 'threads': @@ -1345,6 +1366,7 @@ def test_no_import_lock_contention(self): self.fail("Probable regression on import lock contention;" " see Issue #22853") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_timeout(self): q = multiprocessing.Queue() start = time.monotonic() @@ -1468,6 +1490,7 @@ def _acquire_event(lock, event): event.set() time.sleep(1.0) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_repr_lock(self): if self.TYPE != 'processes': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -1557,6 +1580,7 @@ def _acquire_release(lock, timeout, l=None, n=1): for _ in range(n): lock.release() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_repr_rlock(self): if self.TYPE != 'processes': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -1727,6 +1751,7 @@ def check_invariant(self, cond): except NotImplementedError: pass + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_notify(self): cond = self.Condition() sleeping = self.Semaphore(0) @@ -2009,6 +2034,7 @@ def _test_event(cls, event): time.sleep(TIMEOUT2) event.set() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_event(self): event = self.Event() wait = TimingWrapper(event.wait) @@ -2205,6 +2231,7 @@ def multipass(cls, barrier, results, n): pass assert not barrier.broken + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_barrier(self, passes=1): """ Test that a barrier is passed in lockstep @@ -2212,6 +2239,7 @@ def test_barrier(self, passes=1): results = [self.DummyList(), self.DummyList()] self.run_threads(self.multipass, (self.barrier, results, passes)) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_barrier_10(self): """ Test that a barrier works for 10 consecutive runs @@ -2223,6 +2251,7 @@ def _test_wait_return_f(cls, barrier, queue): res = barrier.wait() queue.put(res) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_wait_return(self): """ test the return value from barrier.wait @@ -2239,6 +2268,7 @@ def _test_action_f(cls, barrier, results): if len(results) != 1: raise RuntimeError + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_action(self): """ Test the 'action' callback @@ -2261,6 +2291,7 @@ def _test_abort_f(cls, barrier, results1, results2): except RuntimeError: barrier.abort() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_abort(self): """ Test that an abort will put the barrier in a broken state @@ -2291,6 +2322,7 @@ def _test_reset_f(cls, barrier, results1, results2, results3): barrier.wait() results3.append(True) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_reset(self): """ Test that a 'reset' on a barrier frees the waiting threads @@ -2326,6 +2358,7 @@ def _test_abort_and_reset_f(cls, barrier, barrier2, barrier.wait() results3.append(True) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_abort_and_reset(self): """ Test that a barrier can be reset after being broken. @@ -2352,6 +2385,7 @@ def _test_timeout_f(cls, barrier, results): except threading.BrokenBarrierError: results.append(True) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_timeout(self): """ Test wait(timeout) @@ -2371,6 +2405,7 @@ def _test_default_timeout_f(cls, barrier, results): except threading.BrokenBarrierError: results.append(True) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_default_timeout(self): """ Test the barrier's default timeout @@ -2392,6 +2427,7 @@ def _test_thousand_f(cls, barrier, passes, conn, lock): with lock: conn.send(i) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_thousand(self): if self.TYPE == 'manager': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -3207,6 +3243,7 @@ def unpickleable_result(): class _TestPoolWorkerErrors(BaseTestCase): ALLOWED_TYPES = ('processes', ) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_async_error_callback(self): p = multiprocessing.Pool(2) @@ -3222,6 +3259,7 @@ def errback(exc): p.close() p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_unpickleable_result(self): from multiprocessing.pool import MaybeEncodingError p = multiprocessing.Pool(2) @@ -3351,6 +3389,7 @@ class _TestMyManager(BaseTestCase): ALLOWED_TYPES = ('manager',) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_mymanager(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) manager.start() @@ -3362,6 +3401,7 @@ def test_mymanager(self): # which happens on slow buildbots. self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM)) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_mymanager_context(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) with manager: @@ -3371,6 +3411,7 @@ def test_mymanager_context(self): # which happens on slow buildbots. self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM)) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_mymanager_context_prestarted(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) manager.start() @@ -3441,6 +3482,7 @@ def _putter(cls, address, authkey): # Note that xmlrpclib will deserialize object as a list not a tuple queue.put(tuple(cls.values)) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_remote(self): authkey = os.urandom(32) @@ -3482,6 +3524,7 @@ def _putter(cls, address, authkey): queue = manager.get_queue() queue.put('hello world') + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_rapid_restart(self): authkey = os.urandom(32) manager = QueueManager( @@ -3534,12 +3577,21 @@ def recv(self): class TestManagerExceptions(unittest.TestCase): # Issue 106558: Manager exceptions avoids creating cyclic references. def setUp(self): - self.mgr = multiprocessing.Manager() + # gh-135427 + # In some of the tests, a forked child forks another child of itself. In that case, using + # warnings_helper.ignore_warnings decorator does not actually ignore the warning from that + # child of child, and a warnings_helper.ignore_warnings exception is raised. + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', + message=".*fork.*may lead to deadlocks in the child.*", + category=DeprecationWarning) + self.mgr = multiprocessing.Manager() def tearDown(self): self.mgr.shutdown() self.mgr.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_queue_get(self): queue = self.mgr.Queue() if gc.isenabled(): @@ -3551,6 +3603,7 @@ def test_queue_get(self): wr = weakref.ref(e) self.assertEqual(wr(), None) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_dispatch(self): if gc.isenabled(): gc.disable() @@ -3577,6 +3630,7 @@ def _echo(cls, conn): conn.send_bytes(msg) conn.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_connection(self): conn, child_conn = self.Pipe() @@ -3669,6 +3723,7 @@ def test_duplex_false(self): self.assertRaises(OSError, writer.recv) self.assertRaises(OSError, writer.poll) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_spawn_close(self): # We test that a pipe connection can be closed by parent # process immediately after child is spawned. On Windows this @@ -3745,6 +3800,7 @@ def _writefd(cls, conn, data, create_dummy_fds=False): os.write(fd, data) os.close(fd) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") def test_fd_transfer(self): if self.TYPE != 'processes': @@ -3764,6 +3820,7 @@ def test_fd_transfer(self): with open(os_helper.TESTFN, "rb") as f: self.assertEqual(f.read(), b"foo") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") @unittest.skipIf(sys.platform == "win32", "test semantics don't make sense on Windows") @@ -3801,6 +3858,7 @@ def test_large_fd_transfer(self): def _send_data_without_fd(self, conn): os.write(conn.fileno(), b"\0") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") @unittest.skipIf(sys.platform == "win32", "doesn't make sense on Windows") def test_missing_fd_transfer(self): @@ -3900,6 +3958,7 @@ def _test(cls, address): conn.send('hello') conn.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_listener_client(self): for family in self.connection.families: l = self.connection.Listener(family=family) @@ -3911,6 +3970,7 @@ def test_listener_client(self): p.join() l.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_issue14725(self): l = self.connection.Listener() p = self.Process(target=self._test, args=(l.address,)) @@ -3956,6 +4016,7 @@ def _child_strings(cls, conn, strings): conn.send_bytes(s) conn.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_strings(self): strings = (b'hello', b'', b'a', b'b', b'', b'bye', b'', b'lop') a, b = self.Pipe() @@ -3979,6 +4040,7 @@ def _child_boundaries(cls, r): # read from it. r.poll(5) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_boundaries(self): r, w = self.Pipe(False) p = self.Process(target=self._child_boundaries, args=(r,)) @@ -3997,6 +4059,7 @@ def _child_dont_merge(cls, b): b.send_bytes(b'b') b.send_bytes(b'cd') + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_dont_merge(self): a, b = self.Pipe() self.assertEqual(a.poll(0.0), False) @@ -4124,6 +4187,7 @@ def child_access(cls, conn): conn.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_access(self): # On Windows, if we do not specify a destination pid when # using DupHandle then we need to be careful to use the @@ -4548,6 +4612,7 @@ def test_shared_memory_pickle_unpickle_dead_object(self): with self.assertRaises(FileNotFoundError): pickle.loads(pickled_sms) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_shared_memory_across_processes(self): # bpo-40135: don't define shared memory block's name in case of # the failure when we run multiprocessing tests in parallel. @@ -4576,6 +4641,7 @@ def test_shared_memory_across_processes(self): sms.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipIf(os.name != "posix", "not feasible in non-posix platforms") def test_shared_memory_SharedMemoryServer_ignores_sigint(self): # bpo-36368: protect SharedMemoryManager server process from @@ -4621,6 +4687,7 @@ def test_shared_memory_SharedMemoryManager_reuses_resource_tracker(self): # properly released sl. self.assertFalse(err) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_shared_memory_SharedMemoryManager_basics(self): smm1 = multiprocessing.managers.SharedMemoryManager() with self.assertRaises(ValueError): @@ -4960,6 +5027,7 @@ class Foo(object): conn.close() os._exit(0) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_finalize(self): conn, child_conn = self.Pipe() @@ -5087,6 +5155,7 @@ def _test_level(cls, conn): logger = multiprocessing.get_logger() conn.send(logger.getEffectiveLevel()) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_level(self): LEVEL1 = 32 LEVEL2 = 37 @@ -5171,6 +5240,7 @@ def _killer(cls, pid): time.sleep(0.1) os.kill(pid, signal.SIGUSR1) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1') def test_poll_eintr(self): got_signal = [False] @@ -5293,14 +5363,23 @@ def initializer(ns): @hashlib_helper.requires_hashdigest('sha256') class TestInitializers(unittest.TestCase): def setUp(self): - self.mgr = multiprocessing.Manager() - self.ns = self.mgr.Namespace() - self.ns.test = 0 + # gh-135427 + # In some of the tests, a forked child forks another child of itself. In that case, using + # warnings_helper.ignore_warnings decorator does not actually ignore the warning from that + # child of child, and a warnings_helper.ignore_warnings exception is raised. + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', + message=".*fork.*may lead to deadlocks in the child.*", + category=DeprecationWarning) + self.mgr = multiprocessing.Manager() + self.ns = self.mgr.Namespace() + self.ns.test = 0 def tearDown(self): self.mgr.shutdown() self.mgr.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_manager_initializer(self): m = multiprocessing.managers.SyncManager() self.assertRaises(TypeError, m.start, 1) @@ -5309,6 +5388,7 @@ def test_manager_initializer(self): m.shutdown() m.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_pool_initializer(self): self.assertRaises(TypeError, multiprocessing.Pool, initializer=1) p = multiprocessing.Pool(1, initializer, (self.ns,)) @@ -5366,16 +5446,19 @@ def flush(self): class TestStdinBadfiledescriptor(unittest.TestCase): + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_queue_in_process(self): proc = multiprocessing.Process(target=_test_process) proc.start() proc.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_pool_in_process(self): p = multiprocessing.Process(target=pool_in_process) p.start() p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_flushing(self): sio = io.StringIO() flike = _file_like(sio) @@ -5395,6 +5478,7 @@ def _child_test_wait(cls, w, slow): w.send((i, os.getpid())) w.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_wait(self, slow=False): from multiprocessing.connection import wait readers = [] @@ -5435,6 +5519,7 @@ def _child_test_wait_socket(cls, address, slow): s.sendall(('%s\n' % i).encode('ascii')) s.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_wait_socket(self, slow=False): from multiprocessing.connection import wait l = socket.create_server((socket_helper.HOST, 0)) @@ -5543,6 +5628,7 @@ def test_wait_integer(self): p.terminate() p.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_neg_timeout(self): from multiprocessing.connection import wait a, b = multiprocessing.Pipe() @@ -5620,6 +5706,7 @@ def _test_timeout(cls, child, address): conn.send(456) conn.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_timeout(self): old_timeout = socket.getdefaulttimeout() try: @@ -5677,6 +5764,7 @@ def child(cls, n, conn): conn.send(len(util._afterfork_registry)) conn.close() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_lock(self): r, w = multiprocessing.Pipe(False) l = util.ForkAwareThreadLock() @@ -5728,6 +5816,7 @@ def _test_closefds(cls, conn, fd): s.close() conn.send(None) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_closefd(self): if not HAS_REDUCTION: raise unittest.SkipTest('requires fd pickling') @@ -5773,6 +5862,7 @@ def handler(signum, frame): conn.send(x) conn.send_bytes(b'x' * cls.CONN_MAX_SIZE) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1') def test_ignore(self): conn, child_conn = multiprocessing.Pipe() @@ -5806,6 +5896,7 @@ def handler(signum, frame): a = l.accept() a.send('welcome') + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1') def test_ignore_listener(self): conn, child_conn = multiprocessing.Pipe() @@ -5840,6 +5931,7 @@ def check_context(self, ctx): p.join() self.assertEqual(child_method, ctx.get_start_method()) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_context(self): for method in ('fork', 'spawn', 'forkserver'): try: @@ -5860,6 +5952,7 @@ def test_context_check_module_types(self): with self.assertRaisesRegex(TypeError, 'module_names must be a list of strings'): ctx.set_forkserver_preload([1, 2, 3]) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_set_get(self): multiprocessing.set_forkserver_preload(PRELOAD) count = 0 @@ -5950,6 +6043,7 @@ def _put_two_and_nest_once(cls, queue): process.start() process.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_nested_startmethod(self): # gh-108520: Regression test to ensure that child process can send its # arguments to another process @@ -6105,6 +6199,7 @@ def _is_resource_tracker_reused(conn, pid): reused &= _resource_tracker._check_alive() conn.send(reused) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_resource_tracker_reused(self): from multiprocessing.resource_tracker import _resource_tracker _resource_tracker.ensure_running() @@ -6206,6 +6301,7 @@ def test_empty_exceptions(self): with self.assertRaisesRegex(OSError, 'is closed'): q.empty() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_empty(self): queue = multiprocessing.SimpleQueue() child_can_start = multiprocessing.Event() @@ -6370,6 +6466,7 @@ def _test_event(cls, obj): obj.clear() obj.wait(0.001) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_event(self): o = self.manager.Event() o.set() @@ -6382,6 +6479,7 @@ def _test_lock(cls, obj): obj.acquire() obj.locked() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_lock(self, lname="Lock"): o = getattr(self.manager, lname)() self.run_worker(self._test_lock, o) @@ -6394,6 +6492,7 @@ def _test_rlock(cls, obj): obj.release() obj.locked() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_rlock(self, lname="RLock"): o = getattr(self.manager, lname)() self.run_worker(self._test_rlock, o) @@ -6402,6 +6501,7 @@ def test_rlock(self, lname="RLock"): def _test_semaphore(cls, obj): obj.acquire() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_semaphore(self, sname="Semaphore"): o = getattr(self.manager, sname)() self.run_worker(self._test_semaphore, o) @@ -6415,6 +6515,7 @@ def _test_condition(cls, obj): obj.acquire() obj.release() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_condition(self): o = self.manager.Condition() self.run_worker(self._test_condition, o) @@ -6424,6 +6525,7 @@ def _test_barrier(cls, obj): assert obj.parties == 5 obj.reset() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_barrier(self): o = self.manager.Barrier(5) self.run_worker(self._test_barrier, o) @@ -6434,6 +6536,7 @@ def _test_pool(cls, obj): with obj: pass + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_pool(self): o = self.manager.Pool(processes=4) self.run_worker(self._test_pool, o) @@ -6448,6 +6551,7 @@ def _test_queue(cls, obj): assert obj.get() == 6 assert obj.empty() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_queue(self, qname="Queue"): o = getattr(self.manager, qname)(2) o.put(5) @@ -6456,6 +6560,7 @@ def test_queue(self, qname="Queue"): assert o.empty() assert not o.full() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_joinable_queue(self): self.test_queue("JoinableQueue") @@ -6490,6 +6595,7 @@ def _test_list(cls, obj): obj.clear() case.assertEqual(len(obj), 0) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_list(self): o = self.manager.list() o.append(5) @@ -6531,6 +6637,7 @@ def _test_dict(cls, obj): obj.clear() case.assertEqual(len(obj), 0) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_dict(self): o = self.manager.dict() o['foo'] = 5 @@ -6545,6 +6652,7 @@ def _test_value(cls, obj): case.assertEqual(obj.get(), 1) obj.set(2) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_value(self): o = self.manager.Value('i', 1) self.run_worker(self._test_value, o) @@ -6559,6 +6667,7 @@ def _test_array(cls, obj): case.assertEqual(len(obj), 2) case.assertListEqual(list(obj), [0, 1]) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_array(self): o = self.manager.Array('i', [0, 1]) self.run_worker(self._test_array, o) @@ -6569,6 +6678,7 @@ def _test_namespace(cls, obj): case.assertEqual(obj.x, 0) case.assertEqual(obj.y, 1) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_namespace(self): o = self.manager.Namespace() o.x = 0 @@ -6688,6 +6798,7 @@ def _test_set_comparisons(cls, obj): case.assertGreater(obj, {'a'}) case.assertGreaterEqual(obj, {'a', 'b'}) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_set(self): o = self.manager.set() self.run_worker(self._test_set_operator_symbols, o) @@ -6705,6 +6816,7 @@ def test_set_init(self): self.assertSetEqual(o, {"a", "b", "c"}) self.assertRaises(RemoteError, self.manager.set, 1234) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_set_contain_all_method(self): o = self.manager.set() set_methods = { @@ -6758,6 +6870,7 @@ def exit_handler(): f.write("deadbeef") atexit.register(exit_handler) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_atexit(self): # gh-83856 with os_helper.temp_dir() as temp_dir: @@ -6910,6 +7023,7 @@ def f(x): return x*x self.assertEqual("332833500", out.decode('utf-8').strip()) self.assertFalse(err, msg=err.decode('utf-8')) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_forked_thread_not_started(self): # gh-134381: Ensure that a thread that has not been started yet in # the parent process can be started within a forked child process. From 204c642037b9ff726f789152c0a63d6e393dcb6c Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Tue, 22 Jul 2025 07:43:53 +0200 Subject: [PATCH 15/29] WIP - more suppression of warnings --- Lib/test/test_concurrent_futures/executor.py | 14 +++++++++++++- .../test_concurrent_futures/test_process_pool.py | 9 ++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_concurrent_futures/executor.py b/Lib/test/test_concurrent_futures/executor.py index 95bf8fcd25bf54..60f2c12e56a7bc 100644 --- a/Lib/test/test_concurrent_futures/executor.py +++ b/Lib/test/test_concurrent_futures/executor.py @@ -5,7 +5,7 @@ from concurrent import futures from operator import add from test import support -from test.support import Py_GIL_DISABLED +from test.support import Py_GIL_DISABLED, warnings_helper def mul(x, y): @@ -43,10 +43,12 @@ class ExecutorTest: # Executor.shutdown() and context manager usage is tested by # ExecutorShutdownTest. + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_submit(self): future = self.executor.submit(pow, 2, 8) self.assertEqual(256, future.result()) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_submit_keyword(self): future = self.executor.submit(mul, 2, y=8) self.assertEqual(16, future.result()) @@ -57,6 +59,7 @@ def test_submit_keyword(self): with self.assertRaises(TypeError): self.executor.submit(arg=1) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_map(self): self.assertEqual( list(self.executor.map(pow, range(10), range(10))), @@ -66,6 +69,7 @@ def test_map(self): list(self.executor.map(pow, range(10), range(10), chunksize=3)), list(map(pow, range(10), range(10)))) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_map_exception(self): i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) self.assertEqual(i.__next__(), (0, 1)) @@ -108,6 +112,7 @@ def test_map_buffersize_value_validation(self): ): self.executor.map(str, range(4), buffersize=buffersize) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_map_buffersize(self): ints = range(4) for buffersize in (1, 2, len(ints), len(ints) * 2): @@ -115,6 +120,7 @@ def test_map_buffersize(self): res = self.executor.map(str, ints, buffersize=buffersize) self.assertListEqual(list(res), ["0", "1", "2", "3"]) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_map_buffersize_on_multiple_iterables(self): ints = range(4) for buffersize in (1, 2, len(ints), len(ints) * 2): @@ -122,6 +128,7 @@ def test_map_buffersize_on_multiple_iterables(self): res = self.executor.map(add, ints, ints, buffersize=buffersize) self.assertListEqual(list(res), [0, 2, 4, 6]) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_map_buffersize_on_infinite_iterable(self): res = self.executor.map(str, itertools.count(), buffersize=2) self.assertEqual(next(res, None), "0") @@ -147,6 +154,7 @@ def test_map_buffersize_without_iterable(self): res = self.executor.map(str, buffersize=2) self.assertIsNone(next(res, None)) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_map_buffersize_when_buffer_is_full(self): ints = iter(range(4)) buffersize = 2 @@ -158,6 +166,7 @@ def test_map_buffersize_when_buffer_is_full(self): msg="should have fetched only `buffersize` elements from `ints`.", ) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_shutdown_race_issue12456(self): # Issue #12456: race condition at shutdown where trying to post a # sentinel in the call queue blocks (the queue is full while processes @@ -165,6 +174,7 @@ def test_shutdown_race_issue12456(self): self.executor.map(str, [2] * (self.worker_count + 1)) self.executor.shutdown() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.cpython_only def test_no_stale_references(self): # Issue #16284: check that the executors don't unnecessarily hang onto @@ -209,6 +219,7 @@ def test_max_workers_negative(self): "than 0"): self.executor_type(max_workers=number) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_free_reference(self): # Issue #14406: Result iterator should not keep an internal # reference to result objects. @@ -221,6 +232,7 @@ def test_free_reference(self): if wr() is None: break + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_swallows_falsey_exceptions(self): # see gh-132063: Prevent exceptions that evaluate as falsey # from being ignored. diff --git a/Lib/test/test_concurrent_futures/test_process_pool.py b/Lib/test/test_concurrent_futures/test_process_pool.py index 3f13a1900a4ca4..e3abad0255f4fb 100644 --- a/Lib/test/test_concurrent_futures/test_process_pool.py +++ b/Lib/test/test_concurrent_futures/test_process_pool.py @@ -9,7 +9,7 @@ from concurrent.futures.process import BrokenProcessPool from test import support -from test.support import hashlib_helper +from test.support import hashlib_helper, warnings_helper from test.test_importlib.metadata.fixtures import parameterize from .executor import ExecutorTest, mul @@ -49,6 +49,7 @@ def test_max_workers_too_large(self): "max_workers must be <= 61"): futures.ProcessPoolExecutor(max_workers=62) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_killed_child(self): # When a child process is abruptly terminated, the whole pool gets # "broken". @@ -61,6 +62,7 @@ def test_killed_child(self): # Submitting other jobs fails as well. self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_map_chunksize(self): def bad_map(): list(self.executor.map(pow, range(40), range(40), chunksize=-1)) @@ -81,6 +83,7 @@ def bad_map(): def _test_traceback(cls): raise RuntimeError(123) # some comment + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_traceback(self): # We want ensure that the traceback from the child process is # contained in the traceback raised in the main process. @@ -103,6 +106,7 @@ def test_traceback(self): self.assertIn('raise RuntimeError(123) # some comment', f1.getvalue()) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @hashlib_helper.requires_hashdigest('md5') def test_ressources_gced_in_workers(self): # Ensure that argument for a job are correctly gc-ed after the job @@ -123,6 +127,7 @@ def test_ressources_gced_in_workers(self): mgr.shutdown() mgr.join() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_saturation(self): executor = self.executor mp_context = self.get_context() @@ -208,6 +213,7 @@ def test_max_tasks_early_shutdown(self): for i, future in enumerate(futures): self.assertEqual(future.result(), mul(i, i)) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_python_finalization_error(self): # gh-109047: Catch RuntimeError on thread creation # during Python finalization. @@ -258,6 +264,7 @@ def test_force_shutdown_workers_invalid_op(self): executor._force_shutdown, operation='invalid operation'), + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @parameterize(*FORCE_SHUTDOWN_PARAMS) def test_force_shutdown_workers(self, function_name): manager = self.get_context().Manager() From 1b4453705c9085443326ffdd5efdbb5033b2c649 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Tue, 22 Jul 2025 21:13:51 +0200 Subject: [PATCH 16/29] WIP - adding more suppressing of the DeprecatinoWarning --- Lib/test/test_concurrent_futures/executor.py | 2 ++ Lib/test/test_concurrent_futures/test_wait.py | 11 +++++++++-- Lib/test/test_logging.py | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_concurrent_futures/executor.py b/Lib/test/test_concurrent_futures/executor.py index 60f2c12e56a7bc..b65da181f18516 100644 --- a/Lib/test/test_concurrent_futures/executor.py +++ b/Lib/test/test_concurrent_futures/executor.py @@ -77,6 +77,7 @@ def test_map_exception(self): with self.assertRaises(ZeroDivisionError): i.__next__() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.requires_resource('walltime') def test_map_timeout(self): results = [] @@ -135,6 +136,7 @@ def test_map_buffersize_on_infinite_iterable(self): self.assertEqual(next(res, None), "1") self.assertEqual(next(res, None), "2") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_map_buffersize_on_multiple_infinite_iterables(self): res = self.executor.map( add, diff --git a/Lib/test/test_concurrent_futures/test_wait.py b/Lib/test/test_concurrent_futures/test_wait.py index cc387883141b0e..f8b637eec87db3 100644 --- a/Lib/test/test_concurrent_futures/test_wait.py +++ b/Lib/test/test_concurrent_futures/test_wait.py @@ -3,7 +3,7 @@ import unittest from concurrent import futures from test import support -from test.support import threading_helper +from test.support import threading_helper, warnings_helper from .util import ( CANCELLED_FUTURE, CANCELLED_AND_NOTIFIED_FUTURE, EXCEPTION_FUTURE, @@ -22,6 +22,7 @@ def wait_and_raise(e): class WaitTests: + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_20369(self): # See https://bugs.python.org/issue20369 future = self.executor.submit(mul, 1, 2) @@ -30,7 +31,7 @@ def test_20369(self): self.assertEqual({future}, done) self.assertEqual(set(), not_done) - + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_first_completed(self): event = self.create_event() future1 = self.executor.submit(mul, 21, 2) @@ -47,6 +48,7 @@ def test_first_completed(self): event.set() future2.result() # wait for job to finish + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_first_completed_some_already_completed(self): event = self.create_event() future1 = self.executor.submit(event.wait) @@ -64,6 +66,7 @@ def test_first_completed_some_already_completed(self): event.set() future1.result() # wait for job to finish + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_first_exception(self): event1 = self.create_event() event2 = self.create_event() @@ -93,6 +96,7 @@ def wait_for_future1(): event2.set() future3.result() # wait for job to finish + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_first_exception_some_already_complete(self): event = self.create_event() future1 = self.executor.submit(divmod, 21, 0) @@ -114,6 +118,7 @@ def test_first_exception_some_already_complete(self): event.set() future2.result() # wait for job to finish + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_first_exception_one_already_failed(self): event = self.create_event() future1 = self.executor.submit(event.wait) @@ -129,6 +134,7 @@ def test_first_exception_one_already_failed(self): event.set() future1.result() # wait for job to finish + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_all_completed(self): future1 = self.executor.submit(divmod, 2, 0) future2 = self.executor.submit(mul, 2, 21) @@ -148,6 +154,7 @@ def test_all_completed(self): future2]), finished) self.assertEqual(set(), pending) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_timeout(self): short_timeout = 0.050 diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 81eaeadd86cf0e..f473270b812970 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4046,6 +4046,7 @@ def test_config_queue_handler_invalid_config_does_not_create_multiprocessing_man self._apply_simple_queue_listener_configuration(qspec) manager.assert_not_called() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @skip_if_tsan_fork @support.requires_subprocess() @unittest.skipUnless(support.Py_DEBUG, "requires a debug build for testing" @@ -4109,6 +4110,7 @@ def _mpinit_issue121723(qspec, message_to_log): # log a message (this creates a record put in the queue) logging.getLogger().info(message_to_log) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @skip_if_tsan_fork @support.requires_subprocess() def test_multiprocessing_queues(self): @@ -5339,6 +5341,7 @@ def _extract_logrecord_process_name(key, logMultiprocessing, conn=None): else: return results + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @skip_if_tsan_fork def test_multiprocessing(self): support.skip_if_broken_multiprocessing_synchronize() From c43b3c0949ad385f25f935ca2aa832e0fb146105 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Tue, 22 Jul 2025 22:01:52 +0200 Subject: [PATCH 17/29] WIP - more suppress of warnings. --- Lib/test/_test_multiprocessing.py | 12 +++++++++++- Lib/test/test_kqueue.py | 3 +++ Lib/test/test_platform.py | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 1d596666fe6877..1e1dc0fd64f211 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -342,6 +342,7 @@ def test_set_executable(self): p.join() self.assertEqual(p.exitcode, 0) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.requires_resource('cpu') def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could @@ -531,6 +532,7 @@ def _sleep_no_int_handler(cls, event): def _test_sleep(cls, delay): time.sleep(delay) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def _kill_process(self, meth, target=None): if self.TYPE == 'threads': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -1554,6 +1556,7 @@ def _test_lock_locked_2processes(cls, lock, event, res): res.value = lock.locked() event.set() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_lock_locked_2processes(self): if self.TYPE != 'processes': @@ -1640,6 +1643,7 @@ def test_rlock(self): self.assertFalse(lock.locked()) self.assertRaises((AssertionError, RuntimeError), lock.release) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_rlock_locked_2processes(self): if self.TYPE != 'processes': @@ -1938,6 +1942,7 @@ def _test_waitfor_f(cls, cond, state): if not result or state.value != 4: sys.exit(1) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_waitfor(self): # based on test in test/lock_tests.py @@ -1973,6 +1978,7 @@ def _test_waitfor_timeout_f(cls, cond, state, success, sem): if not result and (expected - CLOCK_RES) <= dt: success.value = True + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_waitfor_timeout(self): # based on test in test/lock_tests.py @@ -2469,7 +2475,7 @@ def _test(cls, values): for sv, cv in zip(values, cls.codes_values): sv.value = cv[2] - + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_value(self, raw=False): if raw: values = [self.RawValue(code, value) @@ -2533,6 +2539,7 @@ def f(cls, seq): for i in range(1, len(seq)): seq[i] += seq[i-1] + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipIf(c_int is None, "requires _ctypes") def test_array(self, raw=False): seq = [680, 626, 934, 821, 150, 233, 548, 982, 714, 831] @@ -4351,6 +4358,7 @@ def _double(cls, x, y, z, foo, arr, string): for i in range(len(arr)): arr[i] *= 2 + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_sharedctypes(self, lock=False): x = Value('i', 7, lock=lock) y = Value(c_double, 1.0/3.0, lock=lock) @@ -5584,6 +5592,7 @@ def signal_and_sleep(cls, sem, period): sem.release() time.sleep(period) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.requires_resource('walltime') def test_wait_integer(self): from multiprocessing.connection import wait @@ -6010,6 +6019,7 @@ def test_preload_resources(self): print(err) self.fail("failed spawning forkserver or grandchild") + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipIf(sys.platform == "win32", "Only Spawn on windows so no risk of mixing") @only_run_in_spawn_testsuite("avoids redundant testing.") diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py index e94edcbc107ba9..29c0690bc91f61 100644 --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -9,6 +9,8 @@ import time import unittest +from test.support import warnings_helper + if not hasattr(select, "kqueue"): raise unittest.SkipTest("test works only on BSD") @@ -257,6 +259,7 @@ def test_fd_non_inheritable(self): self.addCleanup(kqueue.close) self.assertEqual(os.get_inheritable(kqueue.fileno()), False) + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @support.requires_fork() def test_fork(self): # gh-110395: kqueue objects must be closed after fork diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 479649053abc01..a170fac4a4f3fc 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -11,7 +11,7 @@ from unittest import mock from test import support -from test.support import os_helper +from test.support import os_helper, warnings_helper try: # Some of the iOS tests need ctypes to operate. @@ -465,7 +465,7 @@ def test_mac_ver(self): else: self.assertEqual(res[2], 'PowerPC') - + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 @unittest.skipUnless(sys.platform == 'darwin', "OSX only test") def test_mac_ver_with_fork(self): # Issue7895: platform.mac_ver() crashes when using fork without exec From 868ffd6817a156cb660cde1d0ab26fa01a0a5054 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Tue, 22 Jul 2025 23:18:24 +0200 Subject: [PATCH 18/29] WIP - more suppress of warnings. --- Lib/test/test_concurrent_futures/test_init.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/test/test_concurrent_futures/test_init.py b/Lib/test/test_concurrent_futures/test_init.py index 6b8484c0d5f197..d3d62f9b263b1f 100644 --- a/Lib/test/test_concurrent_futures/test_init.py +++ b/Lib/test/test_concurrent_futures/test_init.py @@ -11,6 +11,7 @@ from logging.handlers import QueueHandler from test import support +from test.support import warnings_helper from .util import ExecutorMixin, create_executor_tests, setup_module @@ -48,6 +49,7 @@ def setUp(self): initargs=('initialized',)) super().setUp() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_initializer(self): futures = [self.executor.submit(get_init_status) for _ in range(self.worker_count)] @@ -74,6 +76,7 @@ def setUp(self): self.executor_kwargs = dict(initializer=init_fail) super().setUp() + @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 def test_initializer(self): with self._assert_logged('ValueError: error in initializer'): try: From e1398d83473e5dd251b2bfd5b99da5a430940587 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Thu, 24 Jul 2025 21:54:16 +0200 Subject: [PATCH 19/29] Add dedicated decorator to ignore only the fork in thread deprecation warnings --- Lib/test/support/warnings_helper.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Lib/test/support/warnings_helper.py b/Lib/test/support/warnings_helper.py index 536a4f88278456..7647278a316e8e 100644 --- a/Lib/test/support/warnings_helper.py +++ b/Lib/test/support/warnings_helper.py @@ -67,6 +67,29 @@ def wrapper(self, *args, **kwargs): return wrapper return decorator + +def ignore_fork_in_thread_deprecation_warnings(test): + """Decorator to suppress the deprecation warnings related to running a fork within a thread. + """ + if inspect.iscoroutinefunction(test): + @functools.wraps(test) + async def async_wrapper(self, *args, **kwargs): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', + message=".*fork.*may lead to deadlocks in the child.*", + category=DeprecationWarning) + return await test(self, *args, **kwargs) + return async_wrapper + else: + @functools.wraps(test) + def wrapper(self, *args, **kwargs): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', + message=".*fork.*may lead to deadlocks in the child.*", + category=DeprecationWarning) + return test(self, *args, **kwargs) + return wrapper + class WarningsRecorder(object): """Convenience wrapper for the warnings list returned on From b58b2cabb160c32d9fba8ba838c853a5e01c4855 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Thu, 24 Jul 2025 22:00:21 +0200 Subject: [PATCH 20/29] Replace the generic decorators to ignore deprecation errors with specific decorator to ignore only the fork in thread deprecation warnings --- Lib/test/_test_multiprocessing.py | 260 +++++++++--------- Lib/test/test_asyncio/test_unix_events.py | 8 +- Lib/test/test_builtin.py | 2 +- Lib/test/test_concurrent_futures/executor.py | 28 +- .../test_as_completed.py | 6 +- .../test_concurrent_futures/test_deadlock.py | 10 +- Lib/test/test_concurrent_futures/test_init.py | 4 +- .../test_process_pool.py | 14 +- .../test_concurrent_futures/test_shutdown.py | 24 +- Lib/test/test_concurrent_futures/test_wait.py | 16 +- Lib/test/test_fork1.py | 4 +- Lib/test/test_kqueue.py | 2 +- Lib/test/test_logging.py | 10 +- Lib/test/test_mailbox.py | 2 +- Lib/test/test_os.py | 36 +-- Lib/test/test_platform.py | 2 +- Lib/test/test_pty.py | 4 +- Lib/test/test_random.py | 2 +- Lib/test/test_socketserver.py | 14 +- Lib/test/test_support.py | 2 +- Lib/test/test_tracemalloc.py | 2 +- Lib/test/test_uuid.py | 2 +- 22 files changed, 227 insertions(+), 227 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 1e1dc0fd64f211..87194cc512a253 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -325,7 +325,7 @@ def test_current(self): self.assertEqual(current.ident, os.getpid()) self.assertEqual(current.exitcode, None) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_set_executable(self): if self.TYPE == 'threads': self.skipTest(f'test not appropriate for {self.TYPE}') @@ -342,7 +342,7 @@ def test_set_executable(self): p.join() self.assertEqual(p.exitcode, 0) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.requires_resource('cpu') def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could @@ -390,7 +390,7 @@ def _test(cls, q, *args, **kwds): q.put(bytes(current.authkey)) q.put(current.pid) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_parent_process_attributes(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -411,7 +411,7 @@ def _test_send_parent_process(cls, wconn): from multiprocessing.process import parent_process wconn.send([parent_process().pid, parent_process().name]) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_parent_process(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -450,7 +450,7 @@ def _test_report_parent_status(cls, wconn): parent_process().join(timeout=support.SHORT_TIMEOUT) wconn.send("alive" if parent_process().is_alive() else "not alive") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_process(self): q = self.Queue(1) e = self.Event() @@ -491,7 +491,7 @@ def test_process(self): self.assertNotIn(p, self.active_children()) close_queue(q) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(threading._HAVE_THREAD_NATIVE_ID, "needs native_id") def test_process_mainthread_native_id(self): if self.TYPE == 'threads': @@ -532,7 +532,7 @@ def _sleep_no_int_handler(cls, event): def _test_sleep(cls, delay): time.sleep(delay) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def _kill_process(self, meth, target=None): if self.TYPE == 'threads': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -590,7 +590,7 @@ def handler(*args): return p.exitcode - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipIf(os.name == 'nt', "POSIX only") def test_interrupt(self): exitcode = self._kill_process(multiprocessing.Process.interrupt) @@ -599,18 +599,18 @@ def test_interrupt(self): # (KeyboardInterrupt in this case) # in multiprocessing.BaseProcess._bootstrap - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipIf(os.name == 'nt', "POSIX only") def test_interrupt_no_handler(self): exitcode = self._kill_process(multiprocessing.Process.interrupt, target=self._sleep_no_int_handler) self.assertEqual(exitcode, -signal.SIGINT) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_terminate(self): exitcode = self._kill_process(multiprocessing.Process.terminate) self.assertEqual(exitcode, -signal.SIGTERM) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_kill(self): exitcode = self._kill_process(multiprocessing.Process.kill) if os.name != 'nt': @@ -626,7 +626,7 @@ def test_cpu_count(self): self.assertIsInstance(cpus, int) self.assertGreaterEqual(cpus, 1) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_active_children(self): self.assertEqual(type(self.active_children()), list) @@ -655,7 +655,7 @@ def _test_recursion(cls, wconn, id): p.start() p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_recursion(self): rconn, wconn = self.Pipe(duplex=False) self._test_recursion(wconn, []) @@ -680,7 +680,7 @@ def test_recursion(self): def _test_sentinel(cls, event): event.wait(10.0) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_sentinel(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -703,7 +703,7 @@ def _test_close(cls, rc=0, q=None): q.get() sys.exit(rc) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_close(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -736,7 +736,7 @@ def test_close(self): close_queue(q) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.requires_resource('walltime') def test_many_processes(self): if self.TYPE == 'threads': @@ -773,7 +773,7 @@ def test_many_processes(self): for p in procs: self.assertIn(p.exitcode, exitcodes) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_lose_target_ref(self): c = DummyCallable() wr = weakref.ref(c) @@ -836,7 +836,7 @@ def func2(): threading.Thread(target=func1).start() threading.Thread(target=func2, daemon=True).start() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_wait_for_threads(self): # A child process should wait for non-daemonic threads to end # before exiting @@ -861,7 +861,7 @@ def _test_error_on_stdio_flush(self, evt, break_std_streams={}): setattr(sys, stream_name, None) evt.set() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_error_on_stdio_flush_1(self): # Check that Process works with broken standard streams streams = [io.StringIO(), None] @@ -881,7 +881,7 @@ def test_error_on_stdio_flush_1(self): finally: setattr(sys, stream_name, old_stream) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_error_on_stdio_flush_2(self): # Same as test_error_on_stdio_flush_1(), but standard streams are # broken by the child process @@ -1032,7 +1032,7 @@ class _TestSubclassingProcess(BaseTestCase): ALLOWED_TYPES = ('processes',) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_subclassing(self): uppercaser = _UpperCaser() uppercaser.daemon = True @@ -1042,7 +1042,7 @@ def test_subclassing(self): uppercaser.stop() uppercaser.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_stderr_flush(self): # sys.stderr is flushed at process shutdown (issue #13812) if self.TYPE == "threads": @@ -1073,7 +1073,7 @@ def _test_sys_exit(cls, reason, testfn): sys.stderr = open(fd, 'w', encoding="utf-8", closefd=False) sys.exit(reason) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_sys_exit(self): # See Issue 13854 if self.TYPE == 'threads': @@ -1141,7 +1141,7 @@ def _test_put(cls, queue, child_can_start, parent_can_continue): queue.get() parent_can_continue.set() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_put(self): MAXSIZE = 6 queue = self.Queue(maxsize=MAXSIZE) @@ -1211,7 +1211,7 @@ def _test_get(cls, queue, child_can_start, parent_can_continue): queue.put(5) parent_can_continue.set() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_get(self): queue = self.Queue() child_can_start = self.Event() @@ -1273,7 +1273,7 @@ def _test_fork(cls, queue): # process cannot shutdown until the feeder thread has finished # pushing items onto the pipe. - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_fork(self): # Old versions of Queue would fail to create a new feeder # thread for a forked process if the original process had its @@ -1324,7 +1324,7 @@ def _test_task_done(cls, q): time.sleep(DELTA) q.task_done() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_task_done(self): queue = self.JoinableQueue() @@ -1368,7 +1368,7 @@ def test_no_import_lock_contention(self): self.fail("Probable regression on import lock contention;" " see Issue #22853") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_timeout(self): q = multiprocessing.Queue() start = time.monotonic() @@ -1492,7 +1492,7 @@ def _acquire_event(lock, event): event.set() time.sleep(1.0) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_repr_lock(self): if self.TYPE != 'processes': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -1556,7 +1556,7 @@ def _test_lock_locked_2processes(cls, lock, event, res): res.value = lock.locked() event.set() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_lock_locked_2processes(self): if self.TYPE != 'processes': @@ -1583,7 +1583,7 @@ def _acquire_release(lock, timeout, l=None, n=1): for _ in range(n): lock.release() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_repr_rlock(self): if self.TYPE != 'processes': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -1643,7 +1643,7 @@ def test_rlock(self): self.assertFalse(lock.locked()) self.assertRaises((AssertionError, RuntimeError), lock.release) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_rlock_locked_2processes(self): if self.TYPE != 'processes': @@ -1755,7 +1755,7 @@ def check_invariant(self, cond): except NotImplementedError: pass - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_notify(self): cond = self.Condition() sleeping = self.Semaphore(0) @@ -1798,7 +1798,7 @@ def test_notify(self): threading_helper.join_thread(t) join_process(p) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_notify_all(self): cond = self.Condition() sleeping = self.Semaphore(0) @@ -1868,7 +1868,7 @@ def test_notify_all(self): # NOTE: join_process and join_thread are the same threading_helper.join_thread(w) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_notify_n(self): cond = self.Condition() sleeping = self.Semaphore(0) @@ -1942,7 +1942,7 @@ def _test_waitfor_f(cls, cond, state): if not result or state.value != 4: sys.exit(1) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_waitfor(self): # based on test in test/lock_tests.py @@ -1978,7 +1978,7 @@ def _test_waitfor_timeout_f(cls, cond, state, success, sem): if not result and (expected - CLOCK_RES) <= dt: success.value = True - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_waitfor_timeout(self): # based on test in test/lock_tests.py @@ -2011,7 +2011,7 @@ def _test_wait_result(cls, c, pid): if pid is not None: os.kill(pid, signal.SIGINT) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_wait_result(self): if isinstance(self, ProcessesMixin) and sys.platform != 'win32': pid = os.getpid() @@ -2040,7 +2040,7 @@ def _test_event(cls, event): time.sleep(TIMEOUT2) event.set() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_event(self): event = self.Event() wait = TimingWrapper(event.wait) @@ -2237,7 +2237,7 @@ def multipass(cls, barrier, results, n): pass assert not barrier.broken - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_barrier(self, passes=1): """ Test that a barrier is passed in lockstep @@ -2245,7 +2245,7 @@ def test_barrier(self, passes=1): results = [self.DummyList(), self.DummyList()] self.run_threads(self.multipass, (self.barrier, results, passes)) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_barrier_10(self): """ Test that a barrier works for 10 consecutive runs @@ -2257,7 +2257,7 @@ def _test_wait_return_f(cls, barrier, queue): res = barrier.wait() queue.put(res) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_wait_return(self): """ test the return value from barrier.wait @@ -2274,7 +2274,7 @@ def _test_action_f(cls, barrier, results): if len(results) != 1: raise RuntimeError - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_action(self): """ Test the 'action' callback @@ -2297,7 +2297,7 @@ def _test_abort_f(cls, barrier, results1, results2): except RuntimeError: barrier.abort() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_abort(self): """ Test that an abort will put the barrier in a broken state @@ -2328,7 +2328,7 @@ def _test_reset_f(cls, barrier, results1, results2, results3): barrier.wait() results3.append(True) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_reset(self): """ Test that a 'reset' on a barrier frees the waiting threads @@ -2364,7 +2364,7 @@ def _test_abort_and_reset_f(cls, barrier, barrier2, barrier.wait() results3.append(True) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_abort_and_reset(self): """ Test that a barrier can be reset after being broken. @@ -2391,7 +2391,7 @@ def _test_timeout_f(cls, barrier, results): except threading.BrokenBarrierError: results.append(True) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_timeout(self): """ Test wait(timeout) @@ -2411,7 +2411,7 @@ def _test_default_timeout_f(cls, barrier, results): except threading.BrokenBarrierError: results.append(True) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_default_timeout(self): """ Test the barrier's default timeout @@ -2433,7 +2433,7 @@ def _test_thousand_f(cls, barrier, passes, conn, lock): with lock: conn.send(i) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_thousand(self): if self.TYPE == 'manager': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -2475,7 +2475,7 @@ def _test(cls, values): for sv, cv in zip(values, cls.codes_values): sv.value = cv[2] - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_value(self, raw=False): if raw: values = [self.RawValue(code, value) @@ -2539,7 +2539,7 @@ def f(cls, seq): for i in range(1, len(seq)): seq[i] += seq[i-1] - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipIf(c_int is None, "requires _ctypes") def test_array(self, raw=False): seq = [680, 626, 934, 821, 150, 233, 548, 982, 714, 831] @@ -2959,7 +2959,7 @@ def test_async(self): self.assertEqual(get(), 49) self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_async_timeout(self): p = self.Pool(3) try: @@ -3057,7 +3057,7 @@ def test_imap_unordered_handle_iterable_exception(self): self.assertIn(value, expected_values) expected_values.remove(value) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_make_pool(self): expected_error = (RemoteError if self.TYPE == 'manager' else ValueError) @@ -3073,7 +3073,7 @@ def test_make_pool(self): p.close() p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_terminate(self): # Simulate slow tasks which take "forever" to complete sleep_time = support.LONG_TIMEOUT @@ -3091,7 +3091,7 @@ def test_terminate(self): p.terminate() p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_empty_iterable(self): # See Issue 12157 p = self.Pool(1) @@ -3104,7 +3104,7 @@ def test_empty_iterable(self): p.close() p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_context(self): if self.TYPE == 'processes': L = list(range(10)) @@ -3119,7 +3119,7 @@ def test_context(self): def _test_traceback(cls): raise RuntimeError(123) # some comment - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_traceback(self): # We want ensure that the traceback from the child process is # contained in the traceback raised in the main process. @@ -3159,11 +3159,11 @@ def test_traceback(self): p.join() @classmethod - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def _test_wrapped_exception(cls): raise RuntimeError('foo') - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_wrapped_exception(self): # Issue #20980: Should not wrap exception when using thread pool with self.Pool(1) as p: @@ -3171,7 +3171,7 @@ def test_wrapped_exception(self): p.apply(self._test_wrapped_exception) p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_map_no_failfast(self): # Issue #23992: the fail-fast behaviour when an exception is raised # during map() would make Pool.join() deadlock, because a worker @@ -3207,7 +3207,7 @@ def test_release_task_refs(self): # they were released too. self.assertEqual(CountedObject.n_instances, 0) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_enter(self): if self.TYPE == 'manager': self.skipTest("test not applicable to manager") @@ -3224,7 +3224,7 @@ def test_enter(self): pass pool.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_resource_warning(self): if self.TYPE == 'manager': self.skipTest("test not applicable to manager") @@ -3250,7 +3250,7 @@ def unpickleable_result(): class _TestPoolWorkerErrors(BaseTestCase): ALLOWED_TYPES = ('processes', ) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_async_error_callback(self): p = multiprocessing.Pool(2) @@ -3266,7 +3266,7 @@ def errback(exc): p.close() p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_unpickleable_result(self): from multiprocessing.pool import MaybeEncodingError p = multiprocessing.Pool(2) @@ -3292,7 +3292,7 @@ def errback(exc): class _TestPoolWorkerLifetime(BaseTestCase): ALLOWED_TYPES = ('processes', ) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_pool_worker_lifetime(self): p = multiprocessing.Pool(3, maxtasksperchild=10) self.assertEqual(3, len(p._pool)) @@ -3322,7 +3322,7 @@ def test_pool_worker_lifetime(self): p.close() p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_pool_worker_lifetime_early_close(self): # Issue #10332: closing a pool whose workers have limited lifetimes # before all the tasks completed would make join() hang. @@ -3396,7 +3396,7 @@ class _TestMyManager(BaseTestCase): ALLOWED_TYPES = ('manager',) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_mymanager(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) manager.start() @@ -3408,7 +3408,7 @@ def test_mymanager(self): # which happens on slow buildbots. self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM)) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_mymanager_context(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) with manager: @@ -3418,7 +3418,7 @@ def test_mymanager_context(self): # which happens on slow buildbots. self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM)) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_mymanager_context_prestarted(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) manager.start() @@ -3489,7 +3489,7 @@ def _putter(cls, address, authkey): # Note that xmlrpclib will deserialize object as a list not a tuple queue.put(tuple(cls.values)) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_remote(self): authkey = os.urandom(32) @@ -3531,7 +3531,7 @@ def _putter(cls, address, authkey): queue = manager.get_queue() queue.put('hello world') - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_rapid_restart(self): authkey = os.urandom(32) manager = QueueManager( @@ -3598,7 +3598,7 @@ def tearDown(self): self.mgr.shutdown() self.mgr.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_queue_get(self): queue = self.mgr.Queue() if gc.isenabled(): @@ -3610,7 +3610,7 @@ def test_queue_get(self): wr = weakref.ref(e) self.assertEqual(wr(), None) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_dispatch(self): if gc.isenabled(): gc.disable() @@ -3637,7 +3637,7 @@ def _echo(cls, conn): conn.send_bytes(msg) conn.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_connection(self): conn, child_conn = self.Pipe() @@ -3730,7 +3730,7 @@ def test_duplex_false(self): self.assertRaises(OSError, writer.recv) self.assertRaises(OSError, writer.poll) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_spawn_close(self): # We test that a pipe connection can be closed by parent # process immediately after child is spawned. On Windows this @@ -3807,7 +3807,7 @@ def _writefd(cls, conn, data, create_dummy_fds=False): os.write(fd, data) os.close(fd) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") def test_fd_transfer(self): if self.TYPE != 'processes': @@ -3827,7 +3827,7 @@ def test_fd_transfer(self): with open(os_helper.TESTFN, "rb") as f: self.assertEqual(f.read(), b"foo") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") @unittest.skipIf(sys.platform == "win32", "test semantics don't make sense on Windows") @@ -3865,7 +3865,7 @@ def test_large_fd_transfer(self): def _send_data_without_fd(self, conn): os.write(conn.fileno(), b"\0") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") @unittest.skipIf(sys.platform == "win32", "doesn't make sense on Windows") def test_missing_fd_transfer(self): @@ -3965,7 +3965,7 @@ def _test(cls, address): conn.send('hello') conn.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_listener_client(self): for family in self.connection.families: l = self.connection.Listener(family=family) @@ -3977,7 +3977,7 @@ def test_listener_client(self): p.join() l.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_issue14725(self): l = self.connection.Listener() p = self.Process(target=self._test, args=(l.address,)) @@ -4023,7 +4023,7 @@ def _child_strings(cls, conn, strings): conn.send_bytes(s) conn.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_strings(self): strings = (b'hello', b'', b'a', b'b', b'', b'bye', b'', b'lop') a, b = self.Pipe() @@ -4047,7 +4047,7 @@ def _child_boundaries(cls, r): # read from it. r.poll(5) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_boundaries(self): r, w = self.Pipe(False) p = self.Process(target=self._child_boundaries, args=(r,)) @@ -4066,7 +4066,7 @@ def _child_dont_merge(cls, b): b.send_bytes(b'b') b.send_bytes(b'cd') - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_dont_merge(self): a, b = self.Pipe() self.assertEqual(a.poll(0.0), False) @@ -4135,7 +4135,7 @@ def _remote(cls, conn): conn.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_pickling(self): families = self.connection.families @@ -4194,7 +4194,7 @@ def child_access(cls, conn): conn.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_access(self): # On Windows, if we do not specify a destination pid when # using DupHandle then we need to be careful to use the @@ -4358,7 +4358,7 @@ def _double(cls, x, y, z, foo, arr, string): for i in range(len(arr)): arr[i] *= 2 - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_sharedctypes(self, lock=False): x = Value('i', 7, lock=lock) y = Value(c_double, 1.0/3.0, lock=lock) @@ -4620,7 +4620,7 @@ def test_shared_memory_pickle_unpickle_dead_object(self): with self.assertRaises(FileNotFoundError): pickle.loads(pickled_sms) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_shared_memory_across_processes(self): # bpo-40135: don't define shared memory block's name in case of # the failure when we run multiprocessing tests in parallel. @@ -4649,7 +4649,7 @@ def test_shared_memory_across_processes(self): sms.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipIf(os.name != "posix", "not feasible in non-posix platforms") def test_shared_memory_SharedMemoryServer_ignores_sigint(self): # bpo-36368: protect SharedMemoryManager server process from @@ -4695,7 +4695,7 @@ def test_shared_memory_SharedMemoryManager_reuses_resource_tracker(self): # properly released sl. self.assertFalse(err) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_shared_memory_SharedMemoryManager_basics(self): smm1 = multiprocessing.managers.SharedMemoryManager() with self.assertRaises(ValueError): @@ -5035,7 +5035,7 @@ class Foo(object): conn.close() os._exit(0) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_finalize(self): conn, child_conn = self.Pipe() @@ -5163,7 +5163,7 @@ def _test_level(cls, conn): logger = multiprocessing.get_logger() conn.send(logger.getEffectiveLevel()) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_level(self): LEVEL1 = 32 LEVEL2 = 37 @@ -5248,7 +5248,7 @@ def _killer(cls, pid): time.sleep(0.1) os.kill(pid, signal.SIGUSR1) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1') def test_poll_eintr(self): got_signal = [False] @@ -5387,7 +5387,7 @@ def tearDown(self): self.mgr.shutdown() self.mgr.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_manager_initializer(self): m = multiprocessing.managers.SyncManager() self.assertRaises(TypeError, m.start, 1) @@ -5396,7 +5396,7 @@ def test_manager_initializer(self): m.shutdown() m.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_pool_initializer(self): self.assertRaises(TypeError, multiprocessing.Pool, initializer=1) p = multiprocessing.Pool(1, initializer, (self.ns,)) @@ -5454,19 +5454,19 @@ def flush(self): class TestStdinBadfiledescriptor(unittest.TestCase): - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_queue_in_process(self): proc = multiprocessing.Process(target=_test_process) proc.start() proc.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_pool_in_process(self): p = multiprocessing.Process(target=pool_in_process) p.start() p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_flushing(self): sio = io.StringIO() flike = _file_like(sio) @@ -5486,7 +5486,7 @@ def _child_test_wait(cls, w, slow): w.send((i, os.getpid())) w.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_wait(self, slow=False): from multiprocessing.connection import wait readers = [] @@ -5527,7 +5527,7 @@ def _child_test_wait_socket(cls, address, slow): s.sendall(('%s\n' % i).encode('ascii')) s.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_wait_socket(self, slow=False): from multiprocessing.connection import wait l = socket.create_server((socket_helper.HOST, 0)) @@ -5592,7 +5592,7 @@ def signal_and_sleep(cls, sem, period): sem.release() time.sleep(period) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.requires_resource('walltime') def test_wait_integer(self): from multiprocessing.connection import wait @@ -5637,7 +5637,7 @@ def test_wait_integer(self): p.terminate() p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_neg_timeout(self): from multiprocessing.connection import wait a, b = multiprocessing.Pipe() @@ -5715,7 +5715,7 @@ def _test_timeout(cls, child, address): conn.send(456) conn.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_timeout(self): old_timeout = socket.getdefaulttimeout() try: @@ -5773,7 +5773,7 @@ def child(cls, n, conn): conn.send(len(util._afterfork_registry)) conn.close() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_lock(self): r, w = multiprocessing.Pipe(False) l = util.ForkAwareThreadLock() @@ -5825,7 +5825,7 @@ def _test_closefds(cls, conn, fd): s.close() conn.send(None) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_closefd(self): if not HAS_REDUCTION: raise unittest.SkipTest('requires fd pickling') @@ -5871,7 +5871,7 @@ def handler(signum, frame): conn.send(x) conn.send_bytes(b'x' * cls.CONN_MAX_SIZE) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1') def test_ignore(self): conn, child_conn = multiprocessing.Pipe() @@ -5905,7 +5905,7 @@ def handler(signum, frame): a = l.accept() a.send('welcome') - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1') def test_ignore_listener(self): conn, child_conn = multiprocessing.Pipe() @@ -5940,7 +5940,7 @@ def check_context(self, ctx): p.join() self.assertEqual(child_method, ctx.get_start_method()) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_context(self): for method in ('fork', 'spawn', 'forkserver'): try: @@ -5961,7 +5961,7 @@ def test_context_check_module_types(self): with self.assertRaisesRegex(TypeError, 'module_names must be a list of strings'): ctx.set_forkserver_preload([1, 2, 3]) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_set_get(self): multiprocessing.set_forkserver_preload(PRELOAD) count = 0 @@ -6019,7 +6019,7 @@ def test_preload_resources(self): print(err) self.fail("failed spawning forkserver or grandchild") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipIf(sys.platform == "win32", "Only Spawn on windows so no risk of mixing") @only_run_in_spawn_testsuite("avoids redundant testing.") @@ -6053,7 +6053,7 @@ def _put_two_and_nest_once(cls, queue): process.start() process.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_nested_startmethod(self): # gh-108520: Regression test to ensure that child process can send its # arguments to another process @@ -6209,7 +6209,7 @@ def _is_resource_tracker_reused(conn, pid): reused &= _resource_tracker._check_alive() conn.send(reused) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_resource_tracker_reused(self): from multiprocessing.resource_tracker import _resource_tracker _resource_tracker.ensure_running() @@ -6311,7 +6311,7 @@ def test_empty_exceptions(self): with self.assertRaisesRegex(OSError, 'is closed'): q.empty() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_empty(self): queue = multiprocessing.SimpleQueue() child_can_start = multiprocessing.Event() @@ -6476,7 +6476,7 @@ def _test_event(cls, obj): obj.clear() obj.wait(0.001) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_event(self): o = self.manager.Event() o.set() @@ -6489,7 +6489,7 @@ def _test_lock(cls, obj): obj.acquire() obj.locked() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_lock(self, lname="Lock"): o = getattr(self.manager, lname)() self.run_worker(self._test_lock, o) @@ -6502,7 +6502,7 @@ def _test_rlock(cls, obj): obj.release() obj.locked() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_rlock(self, lname="RLock"): o = getattr(self.manager, lname)() self.run_worker(self._test_rlock, o) @@ -6511,7 +6511,7 @@ def test_rlock(self, lname="RLock"): def _test_semaphore(cls, obj): obj.acquire() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_semaphore(self, sname="Semaphore"): o = getattr(self.manager, sname)() self.run_worker(self._test_semaphore, o) @@ -6525,7 +6525,7 @@ def _test_condition(cls, obj): obj.acquire() obj.release() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_condition(self): o = self.manager.Condition() self.run_worker(self._test_condition, o) @@ -6535,7 +6535,7 @@ def _test_barrier(cls, obj): assert obj.parties == 5 obj.reset() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_barrier(self): o = self.manager.Barrier(5) self.run_worker(self._test_barrier, o) @@ -6546,7 +6546,7 @@ def _test_pool(cls, obj): with obj: pass - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_pool(self): o = self.manager.Pool(processes=4) self.run_worker(self._test_pool, o) @@ -6561,7 +6561,7 @@ def _test_queue(cls, obj): assert obj.get() == 6 assert obj.empty() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_queue(self, qname="Queue"): o = getattr(self.manager, qname)(2) o.put(5) @@ -6570,7 +6570,7 @@ def test_queue(self, qname="Queue"): assert o.empty() assert not o.full() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_joinable_queue(self): self.test_queue("JoinableQueue") @@ -6605,7 +6605,7 @@ def _test_list(cls, obj): obj.clear() case.assertEqual(len(obj), 0) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_list(self): o = self.manager.list() o.append(5) @@ -6647,7 +6647,7 @@ def _test_dict(cls, obj): obj.clear() case.assertEqual(len(obj), 0) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_dict(self): o = self.manager.dict() o['foo'] = 5 @@ -6662,7 +6662,7 @@ def _test_value(cls, obj): case.assertEqual(obj.get(), 1) obj.set(2) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_value(self): o = self.manager.Value('i', 1) self.run_worker(self._test_value, o) @@ -6677,7 +6677,7 @@ def _test_array(cls, obj): case.assertEqual(len(obj), 2) case.assertListEqual(list(obj), [0, 1]) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_array(self): o = self.manager.Array('i', [0, 1]) self.run_worker(self._test_array, o) @@ -6688,7 +6688,7 @@ def _test_namespace(cls, obj): case.assertEqual(obj.x, 0) case.assertEqual(obj.y, 1) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_namespace(self): o = self.manager.Namespace() o.x = 0 @@ -6808,7 +6808,7 @@ def _test_set_comparisons(cls, obj): case.assertGreater(obj, {'a'}) case.assertGreaterEqual(obj, {'a', 'b'}) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_set(self): o = self.manager.set() self.run_worker(self._test_set_operator_symbols, o) @@ -6826,7 +6826,7 @@ def test_set_init(self): self.assertSetEqual(o, {"a", "b", "c"}) self.assertRaises(RemoteError, self.manager.set, 1234) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_set_contain_all_method(self): o = self.manager.set() set_methods = { @@ -6880,7 +6880,7 @@ def exit_handler(): f.write("deadbeef") atexit.register(exit_handler) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_atexit(self): # gh-83856 with os_helper.temp_dir() as temp_dir: @@ -7033,7 +7033,7 @@ def f(x): return x*x self.assertEqual("332833500", out.decode('utf-8').strip()) self.assertFalse(err, msg=err.decode('utf-8')) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_forked_thread_not_started(self): # gh-134381: Ensure that a thread that has not been started yet in # the parent process can be started within a forked child process. diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index f2d17cb3187f26..73f7350555d6ed 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1182,7 +1182,7 @@ async def runner(): @support.requires_fork() class TestFork(unittest.IsolatedAsyncioTestCase): - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 async def test_fork_not_share_event_loop(self): # The forked process should not share the event loop with the parent loop = asyncio.get_running_loop() @@ -1207,7 +1207,7 @@ async def test_fork_not_share_event_loop(self): self.assertEqual(result, b'NO LOOP') wait_process(pid, exitcode=0) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @hashlib_helper.requires_hashdigest('md5') @support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True) def test_fork_signal_handling(self): @@ -1255,7 +1255,7 @@ async def func(): self.assertFalse(parent_handled.is_set()) self.assertTrue(child_handled.is_set()) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @hashlib_helper.requires_hashdigest('md5') @support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True) def test_fork_asyncio_run(self): @@ -1276,7 +1276,7 @@ async def child_main(): self.assertEqual(result.value, 42) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @hashlib_helper.requires_hashdigest('md5') @support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True) def test_fork_asyncio_subprocess(self): diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index dab7db762137ac..8a3a5a584e41a5 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -2546,7 +2546,7 @@ def run_child(self, child, terminal_input): finally: signal.signal(signal.SIGHUP, old_sighup) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def _run_child(self, child, terminal_input): r, w = os.pipe() # Pipe test results from child back to parent try: diff --git a/Lib/test/test_concurrent_futures/executor.py b/Lib/test/test_concurrent_futures/executor.py index b65da181f18516..62aa568e86a011 100644 --- a/Lib/test/test_concurrent_futures/executor.py +++ b/Lib/test/test_concurrent_futures/executor.py @@ -43,12 +43,12 @@ class ExecutorTest: # Executor.shutdown() and context manager usage is tested by # ExecutorShutdownTest. - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_submit(self): future = self.executor.submit(pow, 2, 8) self.assertEqual(256, future.result()) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_submit_keyword(self): future = self.executor.submit(mul, 2, y=8) self.assertEqual(16, future.result()) @@ -59,7 +59,7 @@ def test_submit_keyword(self): with self.assertRaises(TypeError): self.executor.submit(arg=1) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_map(self): self.assertEqual( list(self.executor.map(pow, range(10), range(10))), @@ -69,7 +69,7 @@ def test_map(self): list(self.executor.map(pow, range(10), range(10), chunksize=3)), list(map(pow, range(10), range(10)))) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_map_exception(self): i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) self.assertEqual(i.__next__(), (0, 1)) @@ -77,7 +77,7 @@ def test_map_exception(self): with self.assertRaises(ZeroDivisionError): i.__next__() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.requires_resource('walltime') def test_map_timeout(self): results = [] @@ -113,7 +113,7 @@ def test_map_buffersize_value_validation(self): ): self.executor.map(str, range(4), buffersize=buffersize) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_map_buffersize(self): ints = range(4) for buffersize in (1, 2, len(ints), len(ints) * 2): @@ -121,7 +121,7 @@ def test_map_buffersize(self): res = self.executor.map(str, ints, buffersize=buffersize) self.assertListEqual(list(res), ["0", "1", "2", "3"]) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_map_buffersize_on_multiple_iterables(self): ints = range(4) for buffersize in (1, 2, len(ints), len(ints) * 2): @@ -129,14 +129,14 @@ def test_map_buffersize_on_multiple_iterables(self): res = self.executor.map(add, ints, ints, buffersize=buffersize) self.assertListEqual(list(res), [0, 2, 4, 6]) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_map_buffersize_on_infinite_iterable(self): res = self.executor.map(str, itertools.count(), buffersize=2) self.assertEqual(next(res, None), "0") self.assertEqual(next(res, None), "1") self.assertEqual(next(res, None), "2") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_map_buffersize_on_multiple_infinite_iterables(self): res = self.executor.map( add, @@ -156,7 +156,7 @@ def test_map_buffersize_without_iterable(self): res = self.executor.map(str, buffersize=2) self.assertIsNone(next(res, None)) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_map_buffersize_when_buffer_is_full(self): ints = iter(range(4)) buffersize = 2 @@ -168,7 +168,7 @@ def test_map_buffersize_when_buffer_is_full(self): msg="should have fetched only `buffersize` elements from `ints`.", ) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_shutdown_race_issue12456(self): # Issue #12456: race condition at shutdown where trying to post a # sentinel in the call queue blocks (the queue is full while processes @@ -176,7 +176,7 @@ def test_shutdown_race_issue12456(self): self.executor.map(str, [2] * (self.worker_count + 1)) self.executor.shutdown() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.cpython_only def test_no_stale_references(self): # Issue #16284: check that the executors don't unnecessarily hang onto @@ -221,7 +221,7 @@ def test_max_workers_negative(self): "than 0"): self.executor_type(max_workers=number) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_free_reference(self): # Issue #14406: Result iterator should not keep an internal # reference to result objects. @@ -234,7 +234,7 @@ def test_free_reference(self): if wr() is None: break - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_swallows_falsey_exceptions(self): # see gh-132063: Prevent exceptions that evaluate as falsey # from being ignored. diff --git a/Lib/test/test_concurrent_futures/test_as_completed.py b/Lib/test/test_concurrent_futures/test_as_completed.py index 9e5d06c01af993..9f7ecf18bbf0c8 100644 --- a/Lib/test/test_concurrent_futures/test_as_completed.py +++ b/Lib/test/test_concurrent_futures/test_as_completed.py @@ -20,7 +20,7 @@ def mul(x, y): class AsCompletedTests: - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_no_timeout(self): future1 = self.executor.submit(mul, 2, 21) future2 = self.executor.submit(mul, 7, 6) @@ -37,7 +37,7 @@ def test_no_timeout(self): future1, future2]), completed) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_future_times_out(self): """Test ``futures.as_completed`` timing out before completing it's final future.""" @@ -65,7 +65,7 @@ def test_future_times_out(self): # Check that ``future`` wasn't completed. self.assertEqual(completed_futures, already_completed) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_duplicate_futures(self): # Issue 20367. Duplicate futures should not raise exceptions or give # duplicate responses. diff --git a/Lib/test/test_concurrent_futures/test_deadlock.py b/Lib/test/test_concurrent_futures/test_deadlock.py index daf23f73efcfff..756a68a029b601 100644 --- a/Lib/test/test_concurrent_futures/test_deadlock.py +++ b/Lib/test/test_concurrent_futures/test_deadlock.py @@ -112,7 +112,7 @@ def _fail_on_deadlock(self, executor): print(f"\nTraceback:\n {tb}", file=sys.__stderr__) self.fail(f"Executor deadlock:\n\n{tb}") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def _check_error(self, error, func, *args, ignore_stderr=False): # test for deadlock caused by crashes or exiting in a pool self.executor.shutdown(wait=True) @@ -201,7 +201,7 @@ def test_exit_during_result_unpickle_in_result_handler(self): # the result_handler thread self._check_error(BrokenProcessPool, _return_instance, ExitAtUnpickle) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.skip_if_sanitizer("UBSan: explicit SIGSEV not allowed", ub=True) def test_shutdown_deadlock(self): # Test that the pool calling shutdown do not cause deadlock @@ -215,7 +215,7 @@ def test_shutdown_deadlock(self): with self.assertRaises(BrokenProcessPool): f.result() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_shutdown_deadlock_pickle(self): # Test that the pool calling shutdown with wait=False does not cause # a deadlock if a task fails at pickle after the shutdown call. @@ -242,7 +242,7 @@ def test_shutdown_deadlock_pickle(self): # dangling threads executor_manager.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.skip_if_sanitizer("UBSan: explicit SIGSEV not allowed", ub=True) def test_crash_big_data(self): # Test that there is a clean exception instead of a deadlock when a @@ -259,7 +259,7 @@ def test_crash_big_data(self): executor.shutdown(wait=True) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_gh105829_should_not_deadlock_if_wakeup_pipe_full(self): # Issue #105829: The _ExecutorManagerThread wakeup pipe could # fill up and block. See: https://github.com/python/cpython/issues/105829 diff --git a/Lib/test/test_concurrent_futures/test_init.py b/Lib/test/test_concurrent_futures/test_init.py index d3d62f9b263b1f..2937e80a5c8ed0 100644 --- a/Lib/test/test_concurrent_futures/test_init.py +++ b/Lib/test/test_concurrent_futures/test_init.py @@ -49,7 +49,7 @@ def setUp(self): initargs=('initialized',)) super().setUp() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_initializer(self): futures = [self.executor.submit(get_init_status) for _ in range(self.worker_count)] @@ -76,7 +76,7 @@ def setUp(self): self.executor_kwargs = dict(initializer=init_fail) super().setUp() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_initializer(self): with self._assert_logged('ValueError: error in initializer'): try: diff --git a/Lib/test/test_concurrent_futures/test_process_pool.py b/Lib/test/test_concurrent_futures/test_process_pool.py index e3abad0255f4fb..b47448de40caa7 100644 --- a/Lib/test/test_concurrent_futures/test_process_pool.py +++ b/Lib/test/test_concurrent_futures/test_process_pool.py @@ -49,7 +49,7 @@ def test_max_workers_too_large(self): "max_workers must be <= 61"): futures.ProcessPoolExecutor(max_workers=62) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_killed_child(self): # When a child process is abruptly terminated, the whole pool gets # "broken". @@ -62,7 +62,7 @@ def test_killed_child(self): # Submitting other jobs fails as well. self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_map_chunksize(self): def bad_map(): list(self.executor.map(pow, range(40), range(40), chunksize=-1)) @@ -83,7 +83,7 @@ def bad_map(): def _test_traceback(cls): raise RuntimeError(123) # some comment - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_traceback(self): # We want ensure that the traceback from the child process is # contained in the traceback raised in the main process. @@ -106,7 +106,7 @@ def test_traceback(self): self.assertIn('raise RuntimeError(123) # some comment', f1.getvalue()) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @hashlib_helper.requires_hashdigest('md5') def test_ressources_gced_in_workers(self): # Ensure that argument for a job are correctly gc-ed after the job @@ -127,7 +127,7 @@ def test_ressources_gced_in_workers(self): mgr.shutdown() mgr.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_saturation(self): executor = self.executor mp_context = self.get_context() @@ -213,7 +213,7 @@ def test_max_tasks_early_shutdown(self): for i, future in enumerate(futures): self.assertEqual(future.result(), mul(i, i)) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_python_finalization_error(self): # gh-109047: Catch RuntimeError on thread creation # during Python finalization. @@ -264,7 +264,7 @@ def test_force_shutdown_workers_invalid_op(self): executor._force_shutdown, operation='invalid operation'), - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @parameterize(*FORCE_SHUTDOWN_PARAMS) def test_force_shutdown_workers(self, function_name): manager = self.get_context().Manager() diff --git a/Lib/test/test_concurrent_futures/test_shutdown.py b/Lib/test/test_concurrent_futures/test_shutdown.py index 70feeab4d04cd3..854af20cd6b1a8 100644 --- a/Lib/test/test_concurrent_futures/test_shutdown.py +++ b/Lib/test/test_concurrent_futures/test_shutdown.py @@ -78,14 +78,14 @@ def run_last(): self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) self.assertEqual(out.strip(), b"runtime-error") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_hang_issue12364(self): fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] self.executor.shutdown() for f in fs: f.result() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_cancel_futures(self): assert self.worker_count <= 5, "test needs few workers" fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] @@ -131,7 +131,7 @@ def test_hang_gh83386(self): self.assertFalse(err) self.assertEqual(out.strip(), b"apple") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_hang_gh94440(self): """shutdown(wait=True) doesn't hang when a future was submitted and quickly canceled right before shutdown. @@ -175,7 +175,7 @@ def acquire_lock(lock): for t in self.executor._threads: t.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_context_manager_shutdown(self): with futures.ThreadPoolExecutor(max_workers=5) as e: executor = e @@ -185,7 +185,7 @@ def test_context_manager_shutdown(self): for t in executor._threads: t.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_del_shutdown(self): executor = futures.ThreadPoolExecutor(max_workers=5) res = executor.map(abs, range(-5, 5)) @@ -199,7 +199,7 @@ def test_del_shutdown(self): # executor got shutdown. assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_shutdown_no_wait(self): # Ensure that the executor cleans up the threads when calling # shutdown with wait=False @@ -214,7 +214,7 @@ def test_shutdown_no_wait(self): # executor got shutdown. assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_thread_names_assigned(self): executor = futures.ThreadPoolExecutor( max_workers=5, thread_name_prefix='SpecialPool') @@ -227,7 +227,7 @@ def test_thread_names_assigned(self): self.assertRegex(t.name, r'^SpecialPool_[0-4]$') t.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_thread_names_default(self): executor = futures.ThreadPoolExecutor(max_workers=5) executor.map(abs, range(-5, 5)) @@ -261,7 +261,7 @@ def test_cancel_futures_wait_false(self): class ProcessPoolShutdownTest(ExecutorShutdownTest): - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_processes_terminate(self): def acquire_lock(lock): lock.acquire() @@ -285,7 +285,7 @@ def acquire_lock(lock): for p in processes.values(): p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_context_manager_shutdown(self): with futures.ProcessPoolExecutor( max_workers=5, mp_context=self.get_context()) as e: @@ -296,7 +296,7 @@ def test_context_manager_shutdown(self): for p in processes.values(): p.join() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_del_shutdown(self): executor = futures.ProcessPoolExecutor( max_workers=5, mp_context=self.get_context()) @@ -319,7 +319,7 @@ def test_del_shutdown(self): # executor got shutdown. assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_shutdown_no_wait(self): # Ensure that the executor cleans up the processes when calling # shutdown with wait=False diff --git a/Lib/test/test_concurrent_futures/test_wait.py b/Lib/test/test_concurrent_futures/test_wait.py index f8b637eec87db3..9388d3f19bb6ee 100644 --- a/Lib/test/test_concurrent_futures/test_wait.py +++ b/Lib/test/test_concurrent_futures/test_wait.py @@ -22,7 +22,7 @@ def wait_and_raise(e): class WaitTests: - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_20369(self): # See https://bugs.python.org/issue20369 future = self.executor.submit(mul, 1, 2) @@ -31,7 +31,7 @@ def test_20369(self): self.assertEqual({future}, done) self.assertEqual(set(), not_done) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_first_completed(self): event = self.create_event() future1 = self.executor.submit(mul, 21, 2) @@ -48,7 +48,7 @@ def test_first_completed(self): event.set() future2.result() # wait for job to finish - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_first_completed_some_already_completed(self): event = self.create_event() future1 = self.executor.submit(event.wait) @@ -66,7 +66,7 @@ def test_first_completed_some_already_completed(self): event.set() future1.result() # wait for job to finish - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_first_exception(self): event1 = self.create_event() event2 = self.create_event() @@ -96,7 +96,7 @@ def wait_for_future1(): event2.set() future3.result() # wait for job to finish - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_first_exception_some_already_complete(self): event = self.create_event() future1 = self.executor.submit(divmod, 21, 0) @@ -118,7 +118,7 @@ def test_first_exception_some_already_complete(self): event.set() future2.result() # wait for job to finish - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_first_exception_one_already_failed(self): event = self.create_event() future1 = self.executor.submit(event.wait) @@ -134,7 +134,7 @@ def test_first_exception_one_already_failed(self): event.set() future1.result() # wait for job to finish - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_all_completed(self): future1 = self.executor.submit(divmod, 2, 0) future2 = self.executor.submit(mul, 2, 21) @@ -154,7 +154,7 @@ def test_all_completed(self): future2]), finished) self.assertEqual(set(), pending) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_timeout(self): short_timeout = 0.050 diff --git a/Lib/test/test_fork1.py b/Lib/test/test_fork1.py index d7306f5b132b34..0d34ae7aa27028 100644 --- a/Lib/test/test_fork1.py +++ b/Lib/test/test_fork1.py @@ -20,7 +20,7 @@ class ForkTest(ForkWait): - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_threaded_import_lock_fork(self): """Check fork() in main thread works while a subthread is doing an import""" import_started = threading.Event() @@ -63,7 +63,7 @@ def importer(): except OSError: pass - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_nested_import_lock_fork(self): """Check fork() in main thread works while the main thread is doing an import""" exitcode = 42 diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py index 29c0690bc91f61..77431fdac08f23 100644 --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -259,7 +259,7 @@ def test_fd_non_inheritable(self): self.addCleanup(kqueue.close) self.assertEqual(os.get_inheritable(kqueue.fileno()), False) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.requires_fork() def test_fork(self): # gh-110395: kqueue objects must be closed after fork diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index f473270b812970..dea2d5c8b18cf4 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -730,7 +730,7 @@ def remove_loop(fname, tries): # based on os.fork existing because that is what users and this test use. # This helps ensure that when fork exists (the important concept) that the # register_at_fork mechanism is also present and used. - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.requires_fork() @threading_helper.requires_working_threading() @skip_if_asan_fork @@ -4046,7 +4046,7 @@ def test_config_queue_handler_invalid_config_does_not_create_multiprocessing_man self._apply_simple_queue_listener_configuration(qspec) manager.assert_not_called() - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @skip_if_tsan_fork @support.requires_subprocess() @unittest.skipUnless(support.Py_DEBUG, "requires a debug build for testing" @@ -4069,7 +4069,7 @@ def test_config_reject_simple_queue_handler_multiprocessing_context(self): with self.assertRaises(ValueError): self._apply_simple_queue_listener_configuration(qspec) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @skip_if_tsan_fork @support.requires_subprocess() @unittest.skipUnless(support.Py_DEBUG, "requires a debug build for testing" @@ -4110,7 +4110,7 @@ def _mpinit_issue121723(qspec, message_to_log): # log a message (this creates a record put in the queue) logging.getLogger().info(message_to_log) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @skip_if_tsan_fork @support.requires_subprocess() def test_multiprocessing_queues(self): @@ -5341,7 +5341,7 @@ def _extract_logrecord_process_name(key, logMultiprocessing, conn=None): else: return results - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @skip_if_tsan_fork def test_multiprocessing(self): support.skip_if_broken_multiprocessing_synchronize() diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index a80efdbb1a0f39..6f3156ac93ceec 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -1212,7 +1212,7 @@ def test_add_and_close(self): self.assertEqual(contents, f.read()) self._box = self._factory(self._path) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.requires_fork() @unittest.skipUnless(hasattr(socket, 'socketpair'), "Test needs socketpair().") def test_lock_conflict(self): diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 7c3d91ea8ed738..4656373d075058 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3518,7 +3518,7 @@ def test_getppid(self): self.assertEqual(error, b'') self.assertEqual(int(stdout), os.getpid()) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def check_waitpid(self, code, exitcode, callback=None): if sys.platform == 'win32': # On Windows, os.spawnv() simply joins arguments with spaces: @@ -3621,35 +3621,35 @@ def create_args(self, *, with_env=False, use_bytes=False): return program, args - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnl') def test_spawnl(self): program, args = self.create_args() exitcode = os.spawnl(os.P_WAIT, program, *args) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnle') def test_spawnle(self): program, args = self.create_args(with_env=True) exitcode = os.spawnle(os.P_WAIT, program, *args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnlp') def test_spawnlp(self): program, args = self.create_args() exitcode = os.spawnlp(os.P_WAIT, program, *args) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnlpe') def test_spawnlpe(self): program, args = self.create_args(with_env=True) exitcode = os.spawnlpe(os.P_WAIT, program, *args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnv') def test_spawnv(self): program, args = self.create_args() @@ -3660,35 +3660,35 @@ def test_spawnv(self): exitcode = os.spawnv(os.P_WAIT, FakePath(program), args) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnve') def test_spawnve(self): program, args = self.create_args(with_env=True) exitcode = os.spawnve(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnvp') def test_spawnvp(self): program, args = self.create_args() exitcode = os.spawnvp(os.P_WAIT, program, args) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnvpe') def test_spawnvpe(self): program, args = self.create_args(with_env=True) exitcode = os.spawnvpe(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnv') def test_nowait(self): program, args = self.create_args() pid = os.spawnv(os.P_NOWAIT, program, args) support.wait_process(pid, exitcode=self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnve') def test_spawnve_bytes(self): # Test bytes handling in parse_arglist and parse_envlist (#28114) @@ -3696,21 +3696,21 @@ def test_spawnve_bytes(self): exitcode = os.spawnve(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnl') def test_spawnl_noargs(self): program, __ = self.create_args() self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program) self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program, '') - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnle') def test_spawnle_noargs(self): program, __ = self.create_args() self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, {}) self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, '', {}) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnv') def test_spawnv_noargs(self): program, __ = self.create_args() @@ -3719,7 +3719,7 @@ def test_spawnv_noargs(self): self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ('',)) self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ['']) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnve') def test_spawnve_noargs(self): program, __ = self.create_args() @@ -3776,12 +3776,12 @@ def _test_invalid_env(self, spawn): exitcode = spawn(os.P_WAIT, program, args, newenv) self.assertEqual(exitcode, 0) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnve') def test_spawnve_invalid_env(self): self._test_invalid_env(os.spawnve) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_os_func('spawnvpe') def test_spawnvpe_invalid_env(self): self._test_invalid_env(os.spawnvpe) @@ -4898,7 +4898,7 @@ def test_posix_pty_functions(self): self.addCleanup(os.close, son_fd) self.assertEqual(os.ptsname(mother_fd), os.ttyname(son_fd)) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(hasattr(os, 'spawnl'), "need os.spawnl()") @support.requires_subprocess() def test_pipe_spawnl(self): diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index a170fac4a4f3fc..78327bae98cf26 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -465,7 +465,7 @@ def test_mac_ver(self): else: self.assertEqual(res[2], 'PowerPC') - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(sys.platform == 'darwin', "OSX only test") def test_mac_ver_with_fork(self): # Issue7895: platform.mac_ver() crashes when using fork without exec diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index 764bf0dac754d1..d1e2c4582c3d73 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -194,7 +194,7 @@ def test_openpty(self): s2 = _readline(master_fd) self.assertEqual(b'For my pet fish, Eric.\n', normalize_output(s2)) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_fork(self): debug("calling pty.fork()") pid, master_fd = pty.fork() @@ -296,7 +296,7 @@ def test_master_read(self): self.assertEqual(data, b"") - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 def test_spawn_doesnt_hang(self): self.addCleanup(unlink, TESTFN) with open(TESTFN, 'wb') as f: diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index f2b6dc57f0a5ad..460695b131bf37 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -1401,7 +1401,7 @@ def test__all__(self): # tests validity but not completeness of the __all__ list self.assertTrue(set(random.__all__) <= set(dir(random))) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @test.support.requires_fork() def test_after_fork(self): # Test the global Random instance gets reseeded in child diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 4b2e479060bc5a..4e8714c79fcd42 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -44,7 +44,7 @@ def receive(sock, n, timeout=test.support.SHORT_TIMEOUT): raise RuntimeError("timed out on %r" % (sock,)) -@warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 +@warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @test.support.requires_fork() @contextlib.contextmanager def simple_subprocess(testcase): @@ -175,7 +175,7 @@ def test_ThreadingTCPServer(self): socketserver.StreamRequestHandler, self.stream_examine) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_forking def test_ForkingTCPServer(self): with simple_subprocess(self): @@ -195,7 +195,7 @@ def test_ThreadingUnixStreamServer(self): socketserver.StreamRequestHandler, self.stream_examine) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_unix_sockets @requires_forking def test_ForkingUnixStreamServer(self): @@ -214,7 +214,7 @@ def test_ThreadingUDPServer(self): socketserver.DatagramRequestHandler, self.dgram_examine) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_forking def test_ForkingUDPServer(self): with simple_subprocess(self): @@ -234,7 +234,7 @@ def test_ThreadingUnixDatagramServer(self): socketserver.DatagramRequestHandler, self.dgram_examine) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_unix_sockets @requires_forking def test_ForkingUnixDatagramServer(self): @@ -320,13 +320,13 @@ def test_threading_not_handled(self): self.assertIs(cm.exc_type, SystemExit) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_forking def test_forking_handled(self): ForkingErrorTestServer(ValueError) self.check_result(handled=True) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @requires_forking def test_forking_not_handled(self): ForkingErrorTestServer(SystemExit) diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index b44bc9104ff736..f88575140a451b 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -485,7 +485,7 @@ def test_check__all__(self): self.assertRaises(AssertionError, support.check__all__, self, unittest) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @unittest.skipUnless(hasattr(os, 'waitpid') and hasattr(os, 'WNOHANG'), 'need os.waitpid() and os.WNOHANG') @support.requires_fork() diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index 1d560be43700ac..98fd20935cc201 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -354,7 +354,7 @@ def fork_child(self): # everything is fine return 0 - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.requires_fork() def test_fork(self): # check that tracemalloc is still working after fork diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index 225dd70d0d2762..b99940556ea6b6 100755 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -1112,7 +1112,7 @@ def test_uuid8_uniqueness(self): versions = {u.version for u in uuids} self.assertSetEqual(versions, {8}) - @warnings_helper.ignore_warnings(category=DeprecationWarning) # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 @support.requires_fork() def testIssue8621(self): # On at least some versions of OSX self.uuid.uuid4 generates From 8d832acd02df30f659bf99a2802e8ebd483545ea Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Thu, 24 Jul 2025 22:03:16 +0200 Subject: [PATCH 21/29] Linting issue --- Lib/test/support/warnings_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/support/warnings_helper.py b/Lib/test/support/warnings_helper.py index 7647278a316e8e..c802f18b79f7f4 100644 --- a/Lib/test/support/warnings_helper.py +++ b/Lib/test/support/warnings_helper.py @@ -67,7 +67,7 @@ def wrapper(self, *args, **kwargs): return wrapper return decorator - + def ignore_fork_in_thread_deprecation_warnings(test): """Decorator to suppress the deprecation warnings related to running a fork within a thread. """ From a0fc74359f3fe0a50993e4e68b236f17596fbd38 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk <33353578+rani-pinchuk@users.noreply.github.com> Date: Thu, 31 Jul 2025 20:11:07 +0200 Subject: [PATCH 22/29] Update Modules/posixmodule.c Co-authored-by: Petr Viktorin --- Modules/posixmodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index c04fe319d117e5..de1c5d5b60ef35 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8126,8 +8126,9 @@ os_fork1_impl(PyObject *module) /* parent: release the import lock. */ PyOS_AfterFork_Parent(); // After PyOS_AfterFork_Parent() starts the world to avoid deadlock. - if (warn_about_fork_with_threads("fork1") < 0) + if (warn_about_fork_with_threads("fork1") < 0) { return NULL; + } } if (pid == -1) { errno = saved_errno; From 5d1d553da125b1d9c02a673eb6040d81486ce8b2 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk <33353578+rani-pinchuk@users.noreply.github.com> Date: Thu, 31 Jul 2025 20:12:35 +0200 Subject: [PATCH 23/29] Update Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst Co-authored-by: Petr Viktorin --- .../Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst b/Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst index 4e0999e2635ba9..a14aa844c011e9 100644 --- a/Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst +++ b/Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst @@ -1 +1,4 @@ -A DeprecationWarning is now provided for os.fork and os.forkpty when run within a thread with -Werror. +With :option:`-Werror <-W>`, the DeprecationWarning emitted by :py:func:`os.fork` +and :py:func:`os.forkpty` in mutli-threaded processes is now raised as an exception. +Previously it was silently ignored. +Patch by Rani Pinchuk. From 5a80e4a124a9311f29795d5ef39011409fc17aee Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Thu, 31 Jul 2025 20:32:38 +0200 Subject: [PATCH 24/29] Simply ignore_warning functions --- Lib/test/_test_multiprocessing.py | 260 ++++++------- Lib/test/support/warnings_helper.py | 63 ++-- Lib/test/test_asyncio/test_unix_events.py | 8 +- Lib/test/test_builtin.py | 2 +- Lib/test/test_concurrent_futures/executor.py | 28 +- .../test_as_completed.py | 6 +- .../test_concurrent_futures/test_deadlock.py | 10 +- Lib/test/test_concurrent_futures/test_init.py | 4 +- .../test_process_pool.py | 14 +- .../test_concurrent_futures/test_shutdown.py | 24 +- Lib/test/test_concurrent_futures/test_wait.py | 16 +- Lib/test/test_fork1.py | 4 +- Lib/test/test_kqueue.py | 2 +- Lib/test/test_logging.py | 10 +- Lib/test/test_mailbox.py | 2 +- Lib/test/test_os.py | 36 +- Lib/test/test_platform.py | 2 +- Lib/test/test_pty.py | 4 +- Lib/test/test_random.py | 2 +- Lib/test/test_socketserver.py | 14 +- Lib/test/test_support.py | 2 +- Lib/test/test_tracemalloc.py | 2 +- Lib/test/test_uuid.py | 2 +- Misc/mypy/_colorize.py | 347 +++++++++++++++++- Misc/mypy/token.py | 145 +++++++- ...ged, 7314 insertions(+), 3271 deletions(-) | 227 ++++++++++++ 26 files changed, 966 insertions(+), 270 deletions(-) mode change 120000 => 100644 Misc/mypy/_colorize.py mode change 120000 => 100644 Misc/mypy/token.py create mode 100644 changed, 7314 insertions(+), 3271 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 87194cc512a253..3724e147709310 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -325,7 +325,7 @@ def test_current(self): self.assertEqual(current.ident, os.getpid()) self.assertEqual(current.exitcode, None) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_set_executable(self): if self.TYPE == 'threads': self.skipTest(f'test not appropriate for {self.TYPE}') @@ -342,7 +342,7 @@ def test_set_executable(self): p.join() self.assertEqual(p.exitcode, 0) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.requires_resource('cpu') def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could @@ -390,7 +390,7 @@ def _test(cls, q, *args, **kwds): q.put(bytes(current.authkey)) q.put(current.pid) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_parent_process_attributes(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -411,7 +411,7 @@ def _test_send_parent_process(cls, wconn): from multiprocessing.process import parent_process wconn.send([parent_process().pid, parent_process().name]) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_parent_process(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -450,7 +450,7 @@ def _test_report_parent_status(cls, wconn): parent_process().join(timeout=support.SHORT_TIMEOUT) wconn.send("alive" if parent_process().is_alive() else "not alive") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_process(self): q = self.Queue(1) e = self.Event() @@ -491,7 +491,7 @@ def test_process(self): self.assertNotIn(p, self.active_children()) close_queue(q) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(threading._HAVE_THREAD_NATIVE_ID, "needs native_id") def test_process_mainthread_native_id(self): if self.TYPE == 'threads': @@ -532,7 +532,7 @@ def _sleep_no_int_handler(cls, event): def _test_sleep(cls, delay): time.sleep(delay) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def _kill_process(self, meth, target=None): if self.TYPE == 'threads': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -590,7 +590,7 @@ def handler(*args): return p.exitcode - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipIf(os.name == 'nt', "POSIX only") def test_interrupt(self): exitcode = self._kill_process(multiprocessing.Process.interrupt) @@ -599,18 +599,18 @@ def test_interrupt(self): # (KeyboardInterrupt in this case) # in multiprocessing.BaseProcess._bootstrap - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipIf(os.name == 'nt', "POSIX only") def test_interrupt_no_handler(self): exitcode = self._kill_process(multiprocessing.Process.interrupt, target=self._sleep_no_int_handler) self.assertEqual(exitcode, -signal.SIGINT) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_terminate(self): exitcode = self._kill_process(multiprocessing.Process.terminate) self.assertEqual(exitcode, -signal.SIGTERM) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_kill(self): exitcode = self._kill_process(multiprocessing.Process.kill) if os.name != 'nt': @@ -626,7 +626,7 @@ def test_cpu_count(self): self.assertIsInstance(cpus, int) self.assertGreaterEqual(cpus, 1) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_active_children(self): self.assertEqual(type(self.active_children()), list) @@ -655,7 +655,7 @@ def _test_recursion(cls, wconn, id): p.start() p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_recursion(self): rconn, wconn = self.Pipe(duplex=False) self._test_recursion(wconn, []) @@ -680,7 +680,7 @@ def test_recursion(self): def _test_sentinel(cls, event): event.wait(10.0) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_sentinel(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -703,7 +703,7 @@ def _test_close(cls, rc=0, q=None): q.get() sys.exit(rc) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_close(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -736,7 +736,7 @@ def test_close(self): close_queue(q) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.requires_resource('walltime') def test_many_processes(self): if self.TYPE == 'threads': @@ -773,7 +773,7 @@ def test_many_processes(self): for p in procs: self.assertIn(p.exitcode, exitcodes) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_lose_target_ref(self): c = DummyCallable() wr = weakref.ref(c) @@ -836,7 +836,7 @@ def func2(): threading.Thread(target=func1).start() threading.Thread(target=func2, daemon=True).start() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_wait_for_threads(self): # A child process should wait for non-daemonic threads to end # before exiting @@ -861,7 +861,7 @@ def _test_error_on_stdio_flush(self, evt, break_std_streams={}): setattr(sys, stream_name, None) evt.set() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_error_on_stdio_flush_1(self): # Check that Process works with broken standard streams streams = [io.StringIO(), None] @@ -881,7 +881,7 @@ def test_error_on_stdio_flush_1(self): finally: setattr(sys, stream_name, old_stream) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_error_on_stdio_flush_2(self): # Same as test_error_on_stdio_flush_1(), but standard streams are # broken by the child process @@ -1032,7 +1032,7 @@ class _TestSubclassingProcess(BaseTestCase): ALLOWED_TYPES = ('processes',) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_subclassing(self): uppercaser = _UpperCaser() uppercaser.daemon = True @@ -1042,7 +1042,7 @@ def test_subclassing(self): uppercaser.stop() uppercaser.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_stderr_flush(self): # sys.stderr is flushed at process shutdown (issue #13812) if self.TYPE == "threads": @@ -1073,7 +1073,7 @@ def _test_sys_exit(cls, reason, testfn): sys.stderr = open(fd, 'w', encoding="utf-8", closefd=False) sys.exit(reason) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_sys_exit(self): # See Issue 13854 if self.TYPE == 'threads': @@ -1141,7 +1141,7 @@ def _test_put(cls, queue, child_can_start, parent_can_continue): queue.get() parent_can_continue.set() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_put(self): MAXSIZE = 6 queue = self.Queue(maxsize=MAXSIZE) @@ -1211,7 +1211,7 @@ def _test_get(cls, queue, child_can_start, parent_can_continue): queue.put(5) parent_can_continue.set() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_get(self): queue = self.Queue() child_can_start = self.Event() @@ -1273,7 +1273,7 @@ def _test_fork(cls, queue): # process cannot shutdown until the feeder thread has finished # pushing items onto the pipe. - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_fork(self): # Old versions of Queue would fail to create a new feeder # thread for a forked process if the original process had its @@ -1324,7 +1324,7 @@ def _test_task_done(cls, q): time.sleep(DELTA) q.task_done() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_task_done(self): queue = self.JoinableQueue() @@ -1368,7 +1368,7 @@ def test_no_import_lock_contention(self): self.fail("Probable regression on import lock contention;" " see Issue #22853") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_timeout(self): q = multiprocessing.Queue() start = time.monotonic() @@ -1492,7 +1492,7 @@ def _acquire_event(lock, event): event.set() time.sleep(1.0) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_repr_lock(self): if self.TYPE != 'processes': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -1556,7 +1556,7 @@ def _test_lock_locked_2processes(cls, lock, event, res): res.value = lock.locked() event.set() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_lock_locked_2processes(self): if self.TYPE != 'processes': @@ -1583,7 +1583,7 @@ def _acquire_release(lock, timeout, l=None, n=1): for _ in range(n): lock.release() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_repr_rlock(self): if self.TYPE != 'processes': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -1643,7 +1643,7 @@ def test_rlock(self): self.assertFalse(lock.locked()) self.assertRaises((AssertionError, RuntimeError), lock.release) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_rlock_locked_2processes(self): if self.TYPE != 'processes': @@ -1755,7 +1755,7 @@ def check_invariant(self, cond): except NotImplementedError: pass - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_notify(self): cond = self.Condition() sleeping = self.Semaphore(0) @@ -1798,7 +1798,7 @@ def test_notify(self): threading_helper.join_thread(t) join_process(p) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_notify_all(self): cond = self.Condition() sleeping = self.Semaphore(0) @@ -1868,7 +1868,7 @@ def test_notify_all(self): # NOTE: join_process and join_thread are the same threading_helper.join_thread(w) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_notify_n(self): cond = self.Condition() sleeping = self.Semaphore(0) @@ -1942,7 +1942,7 @@ def _test_waitfor_f(cls, cond, state): if not result or state.value != 4: sys.exit(1) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_waitfor(self): # based on test in test/lock_tests.py @@ -1978,7 +1978,7 @@ def _test_waitfor_timeout_f(cls, cond, state, success, sem): if not result and (expected - CLOCK_RES) <= dt: success.value = True - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(HAS_SHAREDCTYPES, 'needs sharedctypes') def test_waitfor_timeout(self): # based on test in test/lock_tests.py @@ -2011,7 +2011,7 @@ def _test_wait_result(cls, c, pid): if pid is not None: os.kill(pid, signal.SIGINT) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_wait_result(self): if isinstance(self, ProcessesMixin) and sys.platform != 'win32': pid = os.getpid() @@ -2040,7 +2040,7 @@ def _test_event(cls, event): time.sleep(TIMEOUT2) event.set() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_event(self): event = self.Event() wait = TimingWrapper(event.wait) @@ -2237,7 +2237,7 @@ def multipass(cls, barrier, results, n): pass assert not barrier.broken - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_barrier(self, passes=1): """ Test that a barrier is passed in lockstep @@ -2245,7 +2245,7 @@ def test_barrier(self, passes=1): results = [self.DummyList(), self.DummyList()] self.run_threads(self.multipass, (self.barrier, results, passes)) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_barrier_10(self): """ Test that a barrier works for 10 consecutive runs @@ -2257,7 +2257,7 @@ def _test_wait_return_f(cls, barrier, queue): res = barrier.wait() queue.put(res) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_wait_return(self): """ test the return value from barrier.wait @@ -2274,7 +2274,7 @@ def _test_action_f(cls, barrier, results): if len(results) != 1: raise RuntimeError - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_action(self): """ Test the 'action' callback @@ -2297,7 +2297,7 @@ def _test_abort_f(cls, barrier, results1, results2): except RuntimeError: barrier.abort() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_abort(self): """ Test that an abort will put the barrier in a broken state @@ -2328,7 +2328,7 @@ def _test_reset_f(cls, barrier, results1, results2, results3): barrier.wait() results3.append(True) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_reset(self): """ Test that a 'reset' on a barrier frees the waiting threads @@ -2364,7 +2364,7 @@ def _test_abort_and_reset_f(cls, barrier, barrier2, barrier.wait() results3.append(True) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_abort_and_reset(self): """ Test that a barrier can be reset after being broken. @@ -2391,7 +2391,7 @@ def _test_timeout_f(cls, barrier, results): except threading.BrokenBarrierError: results.append(True) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_timeout(self): """ Test wait(timeout) @@ -2411,7 +2411,7 @@ def _test_default_timeout_f(cls, barrier, results): except threading.BrokenBarrierError: results.append(True) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_default_timeout(self): """ Test the barrier's default timeout @@ -2433,7 +2433,7 @@ def _test_thousand_f(cls, barrier, passes, conn, lock): with lock: conn.send(i) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_thousand(self): if self.TYPE == 'manager': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -2475,7 +2475,7 @@ def _test(cls, values): for sv, cv in zip(values, cls.codes_values): sv.value = cv[2] - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_value(self, raw=False): if raw: values = [self.RawValue(code, value) @@ -2539,7 +2539,7 @@ def f(cls, seq): for i in range(1, len(seq)): seq[i] += seq[i-1] - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipIf(c_int is None, "requires _ctypes") def test_array(self, raw=False): seq = [680, 626, 934, 821, 150, 233, 548, 982, 714, 831] @@ -2959,7 +2959,7 @@ def test_async(self): self.assertEqual(get(), 49) self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_async_timeout(self): p = self.Pool(3) try: @@ -3057,7 +3057,7 @@ def test_imap_unordered_handle_iterable_exception(self): self.assertIn(value, expected_values) expected_values.remove(value) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_make_pool(self): expected_error = (RemoteError if self.TYPE == 'manager' else ValueError) @@ -3073,7 +3073,7 @@ def test_make_pool(self): p.close() p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_terminate(self): # Simulate slow tasks which take "forever" to complete sleep_time = support.LONG_TIMEOUT @@ -3091,7 +3091,7 @@ def test_terminate(self): p.terminate() p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_empty_iterable(self): # See Issue 12157 p = self.Pool(1) @@ -3104,7 +3104,7 @@ def test_empty_iterable(self): p.close() p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_context(self): if self.TYPE == 'processes': L = list(range(10)) @@ -3119,7 +3119,7 @@ def test_context(self): def _test_traceback(cls): raise RuntimeError(123) # some comment - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_traceback(self): # We want ensure that the traceback from the child process is # contained in the traceback raised in the main process. @@ -3159,11 +3159,11 @@ def test_traceback(self): p.join() @classmethod - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def _test_wrapped_exception(cls): raise RuntimeError('foo') - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_wrapped_exception(self): # Issue #20980: Should not wrap exception when using thread pool with self.Pool(1) as p: @@ -3171,7 +3171,7 @@ def test_wrapped_exception(self): p.apply(self._test_wrapped_exception) p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_map_no_failfast(self): # Issue #23992: the fail-fast behaviour when an exception is raised # during map() would make Pool.join() deadlock, because a worker @@ -3207,7 +3207,7 @@ def test_release_task_refs(self): # they were released too. self.assertEqual(CountedObject.n_instances, 0) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_enter(self): if self.TYPE == 'manager': self.skipTest("test not applicable to manager") @@ -3224,7 +3224,7 @@ def test_enter(self): pass pool.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_resource_warning(self): if self.TYPE == 'manager': self.skipTest("test not applicable to manager") @@ -3250,7 +3250,7 @@ def unpickleable_result(): class _TestPoolWorkerErrors(BaseTestCase): ALLOWED_TYPES = ('processes', ) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_async_error_callback(self): p = multiprocessing.Pool(2) @@ -3266,7 +3266,7 @@ def errback(exc): p.close() p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_unpickleable_result(self): from multiprocessing.pool import MaybeEncodingError p = multiprocessing.Pool(2) @@ -3292,7 +3292,7 @@ def errback(exc): class _TestPoolWorkerLifetime(BaseTestCase): ALLOWED_TYPES = ('processes', ) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_pool_worker_lifetime(self): p = multiprocessing.Pool(3, maxtasksperchild=10) self.assertEqual(3, len(p._pool)) @@ -3322,7 +3322,7 @@ def test_pool_worker_lifetime(self): p.close() p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_pool_worker_lifetime_early_close(self): # Issue #10332: closing a pool whose workers have limited lifetimes # before all the tasks completed would make join() hang. @@ -3396,7 +3396,7 @@ class _TestMyManager(BaseTestCase): ALLOWED_TYPES = ('manager',) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_mymanager(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) manager.start() @@ -3408,7 +3408,7 @@ def test_mymanager(self): # which happens on slow buildbots. self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM)) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_mymanager_context(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) with manager: @@ -3418,7 +3418,7 @@ def test_mymanager_context(self): # which happens on slow buildbots. self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM)) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_mymanager_context_prestarted(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) manager.start() @@ -3489,7 +3489,7 @@ def _putter(cls, address, authkey): # Note that xmlrpclib will deserialize object as a list not a tuple queue.put(tuple(cls.values)) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_remote(self): authkey = os.urandom(32) @@ -3531,7 +3531,7 @@ def _putter(cls, address, authkey): queue = manager.get_queue() queue.put('hello world') - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_rapid_restart(self): authkey = os.urandom(32) manager = QueueManager( @@ -3598,7 +3598,7 @@ def tearDown(self): self.mgr.shutdown() self.mgr.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_queue_get(self): queue = self.mgr.Queue() if gc.isenabled(): @@ -3610,7 +3610,7 @@ def test_queue_get(self): wr = weakref.ref(e) self.assertEqual(wr(), None) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_dispatch(self): if gc.isenabled(): gc.disable() @@ -3637,7 +3637,7 @@ def _echo(cls, conn): conn.send_bytes(msg) conn.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_connection(self): conn, child_conn = self.Pipe() @@ -3730,7 +3730,7 @@ def test_duplex_false(self): self.assertRaises(OSError, writer.recv) self.assertRaises(OSError, writer.poll) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_spawn_close(self): # We test that a pipe connection can be closed by parent # process immediately after child is spawned. On Windows this @@ -3807,7 +3807,7 @@ def _writefd(cls, conn, data, create_dummy_fds=False): os.write(fd, data) os.close(fd) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") def test_fd_transfer(self): if self.TYPE != 'processes': @@ -3827,7 +3827,7 @@ def test_fd_transfer(self): with open(os_helper.TESTFN, "rb") as f: self.assertEqual(f.read(), b"foo") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") @unittest.skipIf(sys.platform == "win32", "test semantics don't make sense on Windows") @@ -3865,7 +3865,7 @@ def test_large_fd_transfer(self): def _send_data_without_fd(self, conn): os.write(conn.fileno(), b"\0") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") @unittest.skipIf(sys.platform == "win32", "doesn't make sense on Windows") def test_missing_fd_transfer(self): @@ -3965,7 +3965,7 @@ def _test(cls, address): conn.send('hello') conn.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_listener_client(self): for family in self.connection.families: l = self.connection.Listener(family=family) @@ -3977,7 +3977,7 @@ def test_listener_client(self): p.join() l.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_issue14725(self): l = self.connection.Listener() p = self.Process(target=self._test, args=(l.address,)) @@ -4023,7 +4023,7 @@ def _child_strings(cls, conn, strings): conn.send_bytes(s) conn.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_strings(self): strings = (b'hello', b'', b'a', b'b', b'', b'bye', b'', b'lop') a, b = self.Pipe() @@ -4047,7 +4047,7 @@ def _child_boundaries(cls, r): # read from it. r.poll(5) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_boundaries(self): r, w = self.Pipe(False) p = self.Process(target=self._child_boundaries, args=(r,)) @@ -4066,7 +4066,7 @@ def _child_dont_merge(cls, b): b.send_bytes(b'b') b.send_bytes(b'cd') - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_dont_merge(self): a, b = self.Pipe() self.assertEqual(a.poll(0.0), False) @@ -4135,7 +4135,7 @@ def _remote(cls, conn): conn.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_pickling(self): families = self.connection.families @@ -4194,7 +4194,7 @@ def child_access(cls, conn): conn.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_access(self): # On Windows, if we do not specify a destination pid when # using DupHandle then we need to be careful to use the @@ -4358,7 +4358,7 @@ def _double(cls, x, y, z, foo, arr, string): for i in range(len(arr)): arr[i] *= 2 - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_sharedctypes(self, lock=False): x = Value('i', 7, lock=lock) y = Value(c_double, 1.0/3.0, lock=lock) @@ -4620,7 +4620,7 @@ def test_shared_memory_pickle_unpickle_dead_object(self): with self.assertRaises(FileNotFoundError): pickle.loads(pickled_sms) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_shared_memory_across_processes(self): # bpo-40135: don't define shared memory block's name in case of # the failure when we run multiprocessing tests in parallel. @@ -4649,7 +4649,7 @@ def test_shared_memory_across_processes(self): sms.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipIf(os.name != "posix", "not feasible in non-posix platforms") def test_shared_memory_SharedMemoryServer_ignores_sigint(self): # bpo-36368: protect SharedMemoryManager server process from @@ -4695,7 +4695,7 @@ def test_shared_memory_SharedMemoryManager_reuses_resource_tracker(self): # properly released sl. self.assertFalse(err) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_shared_memory_SharedMemoryManager_basics(self): smm1 = multiprocessing.managers.SharedMemoryManager() with self.assertRaises(ValueError): @@ -5035,7 +5035,7 @@ class Foo(object): conn.close() os._exit(0) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_finalize(self): conn, child_conn = self.Pipe() @@ -5163,7 +5163,7 @@ def _test_level(cls, conn): logger = multiprocessing.get_logger() conn.send(logger.getEffectiveLevel()) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_level(self): LEVEL1 = 32 LEVEL2 = 37 @@ -5248,7 +5248,7 @@ def _killer(cls, pid): time.sleep(0.1) os.kill(pid, signal.SIGUSR1) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1') def test_poll_eintr(self): got_signal = [False] @@ -5387,7 +5387,7 @@ def tearDown(self): self.mgr.shutdown() self.mgr.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_manager_initializer(self): m = multiprocessing.managers.SyncManager() self.assertRaises(TypeError, m.start, 1) @@ -5396,7 +5396,7 @@ def test_manager_initializer(self): m.shutdown() m.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_pool_initializer(self): self.assertRaises(TypeError, multiprocessing.Pool, initializer=1) p = multiprocessing.Pool(1, initializer, (self.ns,)) @@ -5454,19 +5454,19 @@ def flush(self): class TestStdinBadfiledescriptor(unittest.TestCase): - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_queue_in_process(self): proc = multiprocessing.Process(target=_test_process) proc.start() proc.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_pool_in_process(self): p = multiprocessing.Process(target=pool_in_process) p.start() p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_flushing(self): sio = io.StringIO() flike = _file_like(sio) @@ -5486,7 +5486,7 @@ def _child_test_wait(cls, w, slow): w.send((i, os.getpid())) w.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_wait(self, slow=False): from multiprocessing.connection import wait readers = [] @@ -5527,7 +5527,7 @@ def _child_test_wait_socket(cls, address, slow): s.sendall(('%s\n' % i).encode('ascii')) s.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_wait_socket(self, slow=False): from multiprocessing.connection import wait l = socket.create_server((socket_helper.HOST, 0)) @@ -5592,7 +5592,7 @@ def signal_and_sleep(cls, sem, period): sem.release() time.sleep(period) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.requires_resource('walltime') def test_wait_integer(self): from multiprocessing.connection import wait @@ -5637,7 +5637,7 @@ def test_wait_integer(self): p.terminate() p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_neg_timeout(self): from multiprocessing.connection import wait a, b = multiprocessing.Pipe() @@ -5715,7 +5715,7 @@ def _test_timeout(cls, child, address): conn.send(456) conn.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_timeout(self): old_timeout = socket.getdefaulttimeout() try: @@ -5773,7 +5773,7 @@ def child(cls, n, conn): conn.send(len(util._afterfork_registry)) conn.close() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_lock(self): r, w = multiprocessing.Pipe(False) l = util.ForkAwareThreadLock() @@ -5825,7 +5825,7 @@ def _test_closefds(cls, conn, fd): s.close() conn.send(None) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_closefd(self): if not HAS_REDUCTION: raise unittest.SkipTest('requires fd pickling') @@ -5871,7 +5871,7 @@ def handler(signum, frame): conn.send(x) conn.send_bytes(b'x' * cls.CONN_MAX_SIZE) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1') def test_ignore(self): conn, child_conn = multiprocessing.Pipe() @@ -5905,7 +5905,7 @@ def handler(signum, frame): a = l.accept() a.send('welcome') - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1') def test_ignore_listener(self): conn, child_conn = multiprocessing.Pipe() @@ -5940,7 +5940,7 @@ def check_context(self, ctx): p.join() self.assertEqual(child_method, ctx.get_start_method()) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_context(self): for method in ('fork', 'spawn', 'forkserver'): try: @@ -5961,7 +5961,7 @@ def test_context_check_module_types(self): with self.assertRaisesRegex(TypeError, 'module_names must be a list of strings'): ctx.set_forkserver_preload([1, 2, 3]) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_set_get(self): multiprocessing.set_forkserver_preload(PRELOAD) count = 0 @@ -6019,7 +6019,7 @@ def test_preload_resources(self): print(err) self.fail("failed spawning forkserver or grandchild") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipIf(sys.platform == "win32", "Only Spawn on windows so no risk of mixing") @only_run_in_spawn_testsuite("avoids redundant testing.") @@ -6053,7 +6053,7 @@ def _put_two_and_nest_once(cls, queue): process.start() process.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_nested_startmethod(self): # gh-108520: Regression test to ensure that child process can send its # arguments to another process @@ -6209,7 +6209,7 @@ def _is_resource_tracker_reused(conn, pid): reused &= _resource_tracker._check_alive() conn.send(reused) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_resource_tracker_reused(self): from multiprocessing.resource_tracker import _resource_tracker _resource_tracker.ensure_running() @@ -6311,7 +6311,7 @@ def test_empty_exceptions(self): with self.assertRaisesRegex(OSError, 'is closed'): q.empty() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_empty(self): queue = multiprocessing.SimpleQueue() child_can_start = multiprocessing.Event() @@ -6476,7 +6476,7 @@ def _test_event(cls, obj): obj.clear() obj.wait(0.001) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_event(self): o = self.manager.Event() o.set() @@ -6489,7 +6489,7 @@ def _test_lock(cls, obj): obj.acquire() obj.locked() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_lock(self, lname="Lock"): o = getattr(self.manager, lname)() self.run_worker(self._test_lock, o) @@ -6502,7 +6502,7 @@ def _test_rlock(cls, obj): obj.release() obj.locked() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_rlock(self, lname="RLock"): o = getattr(self.manager, lname)() self.run_worker(self._test_rlock, o) @@ -6511,7 +6511,7 @@ def test_rlock(self, lname="RLock"): def _test_semaphore(cls, obj): obj.acquire() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_semaphore(self, sname="Semaphore"): o = getattr(self.manager, sname)() self.run_worker(self._test_semaphore, o) @@ -6525,7 +6525,7 @@ def _test_condition(cls, obj): obj.acquire() obj.release() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_condition(self): o = self.manager.Condition() self.run_worker(self._test_condition, o) @@ -6535,7 +6535,7 @@ def _test_barrier(cls, obj): assert obj.parties == 5 obj.reset() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_barrier(self): o = self.manager.Barrier(5) self.run_worker(self._test_barrier, o) @@ -6546,7 +6546,7 @@ def _test_pool(cls, obj): with obj: pass - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_pool(self): o = self.manager.Pool(processes=4) self.run_worker(self._test_pool, o) @@ -6561,7 +6561,7 @@ def _test_queue(cls, obj): assert obj.get() == 6 assert obj.empty() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_queue(self, qname="Queue"): o = getattr(self.manager, qname)(2) o.put(5) @@ -6570,7 +6570,7 @@ def test_queue(self, qname="Queue"): assert o.empty() assert not o.full() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_joinable_queue(self): self.test_queue("JoinableQueue") @@ -6605,7 +6605,7 @@ def _test_list(cls, obj): obj.clear() case.assertEqual(len(obj), 0) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_list(self): o = self.manager.list() o.append(5) @@ -6647,7 +6647,7 @@ def _test_dict(cls, obj): obj.clear() case.assertEqual(len(obj), 0) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_dict(self): o = self.manager.dict() o['foo'] = 5 @@ -6662,7 +6662,7 @@ def _test_value(cls, obj): case.assertEqual(obj.get(), 1) obj.set(2) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_value(self): o = self.manager.Value('i', 1) self.run_worker(self._test_value, o) @@ -6677,7 +6677,7 @@ def _test_array(cls, obj): case.assertEqual(len(obj), 2) case.assertListEqual(list(obj), [0, 1]) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_array(self): o = self.manager.Array('i', [0, 1]) self.run_worker(self._test_array, o) @@ -6688,7 +6688,7 @@ def _test_namespace(cls, obj): case.assertEqual(obj.x, 0) case.assertEqual(obj.y, 1) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_namespace(self): o = self.manager.Namespace() o.x = 0 @@ -6808,7 +6808,7 @@ def _test_set_comparisons(cls, obj): case.assertGreater(obj, {'a'}) case.assertGreaterEqual(obj, {'a', 'b'}) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_set(self): o = self.manager.set() self.run_worker(self._test_set_operator_symbols, o) @@ -6826,7 +6826,7 @@ def test_set_init(self): self.assertSetEqual(o, {"a", "b", "c"}) self.assertRaises(RemoteError, self.manager.set, 1234) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_set_contain_all_method(self): o = self.manager.set() set_methods = { @@ -6880,7 +6880,7 @@ def exit_handler(): f.write("deadbeef") atexit.register(exit_handler) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_atexit(self): # gh-83856 with os_helper.temp_dir() as temp_dir: @@ -7033,7 +7033,7 @@ def f(x): return x*x self.assertEqual("332833500", out.decode('utf-8').strip()) self.assertFalse(err, msg=err.decode('utf-8')) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_forked_thread_not_started(self): # gh-134381: Ensure that a thread that has not been started yet in # the parent process can be started within a forked child process. diff --git a/Lib/test/support/warnings_helper.py b/Lib/test/support/warnings_helper.py index c802f18b79f7f4..aeed570e22d6a6 100644 --- a/Lib/test/support/warnings_helper.py +++ b/Lib/test/support/warnings_helper.py @@ -44,51 +44,32 @@ def check_syntax_warning(testcase, statement, errtext='', testcase.assertEqual(warns, []) -def ignore_warnings(*, category): +@contextlib.contextmanager +def ignore_warnings(*, category, message=''): """Decorator to suppress warnings. - Use of context managers to hide warnings make diffs - more noisy and tools like 'git blame' less useful. + Can also be used as a context manager. This is not preferred, + because it makes diffs more noisy and tools like 'git blame' less useful. + But, it's useful for async functions. """ - def decorator(test): - if inspect.iscoroutinefunction(test): - @functools.wraps(test) - async def async_wrapper(self, *args, **kwargs): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=category) - return await test(self, *args, **kwargs) - return async_wrapper - else: - @functools.wraps(test) - def wrapper(self, *args, **kwargs): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=category) - return test(self, *args, **kwargs) - return wrapper - return decorator - - -def ignore_fork_in_thread_deprecation_warnings(test): - """Decorator to suppress the deprecation warnings related to running a fork within a thread. + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', category=category, message=message) + yield + + +@contextlib.contextmanager +def ignore_fork_in_thread_deprecation_warnings(): + """Suppress deprecation warnings related to forking in multi-threaded code. + + See gh-135427 + + Can be used as decorator (preferred) or context manager. """ - if inspect.iscoroutinefunction(test): - @functools.wraps(test) - async def async_wrapper(self, *args, **kwargs): - with warnings.catch_warnings(): - warnings.filterwarnings('ignore', - message=".*fork.*may lead to deadlocks in the child.*", - category=DeprecationWarning) - return await test(self, *args, **kwargs) - return async_wrapper - else: - @functools.wraps(test) - def wrapper(self, *args, **kwargs): - with warnings.catch_warnings(): - warnings.filterwarnings('ignore', - message=".*fork.*may lead to deadlocks in the child.*", - category=DeprecationWarning) - return test(self, *args, **kwargs) - return wrapper + with ignore_warnings( + message=".*fork.*may lead to deadlocks in the child.*", + category=DeprecationWarning, + ): + yield class WarningsRecorder(object): diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 73f7350555d6ed..452baa5b3c0884 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1182,7 +1182,7 @@ async def runner(): @support.requires_fork() class TestFork(unittest.IsolatedAsyncioTestCase): - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() async def test_fork_not_share_event_loop(self): # The forked process should not share the event loop with the parent loop = asyncio.get_running_loop() @@ -1207,7 +1207,7 @@ async def test_fork_not_share_event_loop(self): self.assertEqual(result, b'NO LOOP') wait_process(pid, exitcode=0) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @hashlib_helper.requires_hashdigest('md5') @support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True) def test_fork_signal_handling(self): @@ -1255,7 +1255,7 @@ async def func(): self.assertFalse(parent_handled.is_set()) self.assertTrue(child_handled.is_set()) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @hashlib_helper.requires_hashdigest('md5') @support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True) def test_fork_asyncio_run(self): @@ -1276,7 +1276,7 @@ async def child_main(): self.assertEqual(result.value, 42) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @hashlib_helper.requires_hashdigest('md5') @support.skip_if_sanitizer("TSAN doesn't support threads after fork", thread=True) def test_fork_asyncio_subprocess(self): diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 8a3a5a584e41a5..85cfe5c90f48af 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -2546,7 +2546,7 @@ def run_child(self, child, terminal_input): finally: signal.signal(signal.SIGHUP, old_sighup) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def _run_child(self, child, terminal_input): r, w = os.pipe() # Pipe test results from child back to parent try: diff --git a/Lib/test/test_concurrent_futures/executor.py b/Lib/test/test_concurrent_futures/executor.py index 62aa568e86a011..a37c4d45f07b17 100644 --- a/Lib/test/test_concurrent_futures/executor.py +++ b/Lib/test/test_concurrent_futures/executor.py @@ -43,12 +43,12 @@ class ExecutorTest: # Executor.shutdown() and context manager usage is tested by # ExecutorShutdownTest. - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_submit(self): future = self.executor.submit(pow, 2, 8) self.assertEqual(256, future.result()) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_submit_keyword(self): future = self.executor.submit(mul, 2, y=8) self.assertEqual(16, future.result()) @@ -59,7 +59,7 @@ def test_submit_keyword(self): with self.assertRaises(TypeError): self.executor.submit(arg=1) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_map(self): self.assertEqual( list(self.executor.map(pow, range(10), range(10))), @@ -69,7 +69,7 @@ def test_map(self): list(self.executor.map(pow, range(10), range(10), chunksize=3)), list(map(pow, range(10), range(10)))) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_map_exception(self): i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) self.assertEqual(i.__next__(), (0, 1)) @@ -77,7 +77,7 @@ def test_map_exception(self): with self.assertRaises(ZeroDivisionError): i.__next__() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.requires_resource('walltime') def test_map_timeout(self): results = [] @@ -113,7 +113,7 @@ def test_map_buffersize_value_validation(self): ): self.executor.map(str, range(4), buffersize=buffersize) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_map_buffersize(self): ints = range(4) for buffersize in (1, 2, len(ints), len(ints) * 2): @@ -121,7 +121,7 @@ def test_map_buffersize(self): res = self.executor.map(str, ints, buffersize=buffersize) self.assertListEqual(list(res), ["0", "1", "2", "3"]) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_map_buffersize_on_multiple_iterables(self): ints = range(4) for buffersize in (1, 2, len(ints), len(ints) * 2): @@ -129,14 +129,14 @@ def test_map_buffersize_on_multiple_iterables(self): res = self.executor.map(add, ints, ints, buffersize=buffersize) self.assertListEqual(list(res), [0, 2, 4, 6]) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_map_buffersize_on_infinite_iterable(self): res = self.executor.map(str, itertools.count(), buffersize=2) self.assertEqual(next(res, None), "0") self.assertEqual(next(res, None), "1") self.assertEqual(next(res, None), "2") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_map_buffersize_on_multiple_infinite_iterables(self): res = self.executor.map( add, @@ -156,7 +156,7 @@ def test_map_buffersize_without_iterable(self): res = self.executor.map(str, buffersize=2) self.assertIsNone(next(res, None)) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_map_buffersize_when_buffer_is_full(self): ints = iter(range(4)) buffersize = 2 @@ -168,7 +168,7 @@ def test_map_buffersize_when_buffer_is_full(self): msg="should have fetched only `buffersize` elements from `ints`.", ) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_shutdown_race_issue12456(self): # Issue #12456: race condition at shutdown where trying to post a # sentinel in the call queue blocks (the queue is full while processes @@ -176,7 +176,7 @@ def test_shutdown_race_issue12456(self): self.executor.map(str, [2] * (self.worker_count + 1)) self.executor.shutdown() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.cpython_only def test_no_stale_references(self): # Issue #16284: check that the executors don't unnecessarily hang onto @@ -221,7 +221,7 @@ def test_max_workers_negative(self): "than 0"): self.executor_type(max_workers=number) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_free_reference(self): # Issue #14406: Result iterator should not keep an internal # reference to result objects. @@ -234,7 +234,7 @@ def test_free_reference(self): if wr() is None: break - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_swallows_falsey_exceptions(self): # see gh-132063: Prevent exceptions that evaluate as falsey # from being ignored. diff --git a/Lib/test/test_concurrent_futures/test_as_completed.py b/Lib/test/test_concurrent_futures/test_as_completed.py index 9f7ecf18bbf0c8..31c7bb3ebd872c 100644 --- a/Lib/test/test_concurrent_futures/test_as_completed.py +++ b/Lib/test/test_concurrent_futures/test_as_completed.py @@ -20,7 +20,7 @@ def mul(x, y): class AsCompletedTests: - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_no_timeout(self): future1 = self.executor.submit(mul, 2, 21) future2 = self.executor.submit(mul, 7, 6) @@ -37,7 +37,7 @@ def test_no_timeout(self): future1, future2]), completed) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_future_times_out(self): """Test ``futures.as_completed`` timing out before completing it's final future.""" @@ -65,7 +65,7 @@ def test_future_times_out(self): # Check that ``future`` wasn't completed. self.assertEqual(completed_futures, already_completed) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_duplicate_futures(self): # Issue 20367. Duplicate futures should not raise exceptions or give # duplicate responses. diff --git a/Lib/test/test_concurrent_futures/test_deadlock.py b/Lib/test/test_concurrent_futures/test_deadlock.py index 756a68a029b601..5cd84f7e43043c 100644 --- a/Lib/test/test_concurrent_futures/test_deadlock.py +++ b/Lib/test/test_concurrent_futures/test_deadlock.py @@ -112,7 +112,7 @@ def _fail_on_deadlock(self, executor): print(f"\nTraceback:\n {tb}", file=sys.__stderr__) self.fail(f"Executor deadlock:\n\n{tb}") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def _check_error(self, error, func, *args, ignore_stderr=False): # test for deadlock caused by crashes or exiting in a pool self.executor.shutdown(wait=True) @@ -201,7 +201,7 @@ def test_exit_during_result_unpickle_in_result_handler(self): # the result_handler thread self._check_error(BrokenProcessPool, _return_instance, ExitAtUnpickle) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.skip_if_sanitizer("UBSan: explicit SIGSEV not allowed", ub=True) def test_shutdown_deadlock(self): # Test that the pool calling shutdown do not cause deadlock @@ -215,7 +215,7 @@ def test_shutdown_deadlock(self): with self.assertRaises(BrokenProcessPool): f.result() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_shutdown_deadlock_pickle(self): # Test that the pool calling shutdown with wait=False does not cause # a deadlock if a task fails at pickle after the shutdown call. @@ -242,7 +242,7 @@ def test_shutdown_deadlock_pickle(self): # dangling threads executor_manager.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.skip_if_sanitizer("UBSan: explicit SIGSEV not allowed", ub=True) def test_crash_big_data(self): # Test that there is a clean exception instead of a deadlock when a @@ -259,7 +259,7 @@ def test_crash_big_data(self): executor.shutdown(wait=True) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_gh105829_should_not_deadlock_if_wakeup_pipe_full(self): # Issue #105829: The _ExecutorManagerThread wakeup pipe could # fill up and block. See: https://github.com/python/cpython/issues/105829 diff --git a/Lib/test/test_concurrent_futures/test_init.py b/Lib/test/test_concurrent_futures/test_init.py index 2937e80a5c8ed0..5ea543bf748982 100644 --- a/Lib/test/test_concurrent_futures/test_init.py +++ b/Lib/test/test_concurrent_futures/test_init.py @@ -49,7 +49,7 @@ def setUp(self): initargs=('initialized',)) super().setUp() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_initializer(self): futures = [self.executor.submit(get_init_status) for _ in range(self.worker_count)] @@ -76,7 +76,7 @@ def setUp(self): self.executor_kwargs = dict(initializer=init_fail) super().setUp() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_initializer(self): with self._assert_logged('ValueError: error in initializer'): try: diff --git a/Lib/test/test_concurrent_futures/test_process_pool.py b/Lib/test/test_concurrent_futures/test_process_pool.py index b47448de40caa7..9685f980119a0e 100644 --- a/Lib/test/test_concurrent_futures/test_process_pool.py +++ b/Lib/test/test_concurrent_futures/test_process_pool.py @@ -49,7 +49,7 @@ def test_max_workers_too_large(self): "max_workers must be <= 61"): futures.ProcessPoolExecutor(max_workers=62) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_killed_child(self): # When a child process is abruptly terminated, the whole pool gets # "broken". @@ -62,7 +62,7 @@ def test_killed_child(self): # Submitting other jobs fails as well. self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_map_chunksize(self): def bad_map(): list(self.executor.map(pow, range(40), range(40), chunksize=-1)) @@ -83,7 +83,7 @@ def bad_map(): def _test_traceback(cls): raise RuntimeError(123) # some comment - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_traceback(self): # We want ensure that the traceback from the child process is # contained in the traceback raised in the main process. @@ -106,7 +106,7 @@ def test_traceback(self): self.assertIn('raise RuntimeError(123) # some comment', f1.getvalue()) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @hashlib_helper.requires_hashdigest('md5') def test_ressources_gced_in_workers(self): # Ensure that argument for a job are correctly gc-ed after the job @@ -127,7 +127,7 @@ def test_ressources_gced_in_workers(self): mgr.shutdown() mgr.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_saturation(self): executor = self.executor mp_context = self.get_context() @@ -213,7 +213,7 @@ def test_max_tasks_early_shutdown(self): for i, future in enumerate(futures): self.assertEqual(future.result(), mul(i, i)) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_python_finalization_error(self): # gh-109047: Catch RuntimeError on thread creation # during Python finalization. @@ -264,7 +264,7 @@ def test_force_shutdown_workers_invalid_op(self): executor._force_shutdown, operation='invalid operation'), - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @parameterize(*FORCE_SHUTDOWN_PARAMS) def test_force_shutdown_workers(self, function_name): manager = self.get_context().Manager() diff --git a/Lib/test/test_concurrent_futures/test_shutdown.py b/Lib/test/test_concurrent_futures/test_shutdown.py index 854af20cd6b1a8..a05b2703aa147d 100644 --- a/Lib/test/test_concurrent_futures/test_shutdown.py +++ b/Lib/test/test_concurrent_futures/test_shutdown.py @@ -78,14 +78,14 @@ def run_last(): self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) self.assertEqual(out.strip(), b"runtime-error") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_hang_issue12364(self): fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] self.executor.shutdown() for f in fs: f.result() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_cancel_futures(self): assert self.worker_count <= 5, "test needs few workers" fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] @@ -131,7 +131,7 @@ def test_hang_gh83386(self): self.assertFalse(err) self.assertEqual(out.strip(), b"apple") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_hang_gh94440(self): """shutdown(wait=True) doesn't hang when a future was submitted and quickly canceled right before shutdown. @@ -175,7 +175,7 @@ def acquire_lock(lock): for t in self.executor._threads: t.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_context_manager_shutdown(self): with futures.ThreadPoolExecutor(max_workers=5) as e: executor = e @@ -185,7 +185,7 @@ def test_context_manager_shutdown(self): for t in executor._threads: t.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_del_shutdown(self): executor = futures.ThreadPoolExecutor(max_workers=5) res = executor.map(abs, range(-5, 5)) @@ -199,7 +199,7 @@ def test_del_shutdown(self): # executor got shutdown. assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_shutdown_no_wait(self): # Ensure that the executor cleans up the threads when calling # shutdown with wait=False @@ -214,7 +214,7 @@ def test_shutdown_no_wait(self): # executor got shutdown. assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_thread_names_assigned(self): executor = futures.ThreadPoolExecutor( max_workers=5, thread_name_prefix='SpecialPool') @@ -227,7 +227,7 @@ def test_thread_names_assigned(self): self.assertRegex(t.name, r'^SpecialPool_[0-4]$') t.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_thread_names_default(self): executor = futures.ThreadPoolExecutor(max_workers=5) executor.map(abs, range(-5, 5)) @@ -261,7 +261,7 @@ def test_cancel_futures_wait_false(self): class ProcessPoolShutdownTest(ExecutorShutdownTest): - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_processes_terminate(self): def acquire_lock(lock): lock.acquire() @@ -285,7 +285,7 @@ def acquire_lock(lock): for p in processes.values(): p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_context_manager_shutdown(self): with futures.ProcessPoolExecutor( max_workers=5, mp_context=self.get_context()) as e: @@ -296,7 +296,7 @@ def test_context_manager_shutdown(self): for p in processes.values(): p.join() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_del_shutdown(self): executor = futures.ProcessPoolExecutor( max_workers=5, mp_context=self.get_context()) @@ -319,7 +319,7 @@ def test_del_shutdown(self): # executor got shutdown. assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_shutdown_no_wait(self): # Ensure that the executor cleans up the processes when calling # shutdown with wait=False diff --git a/Lib/test/test_concurrent_futures/test_wait.py b/Lib/test/test_concurrent_futures/test_wait.py index 9388d3f19bb6ee..b8250cec7ab3e7 100644 --- a/Lib/test/test_concurrent_futures/test_wait.py +++ b/Lib/test/test_concurrent_futures/test_wait.py @@ -22,7 +22,7 @@ def wait_and_raise(e): class WaitTests: - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_20369(self): # See https://bugs.python.org/issue20369 future = self.executor.submit(mul, 1, 2) @@ -31,7 +31,7 @@ def test_20369(self): self.assertEqual({future}, done) self.assertEqual(set(), not_done) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_first_completed(self): event = self.create_event() future1 = self.executor.submit(mul, 21, 2) @@ -48,7 +48,7 @@ def test_first_completed(self): event.set() future2.result() # wait for job to finish - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_first_completed_some_already_completed(self): event = self.create_event() future1 = self.executor.submit(event.wait) @@ -66,7 +66,7 @@ def test_first_completed_some_already_completed(self): event.set() future1.result() # wait for job to finish - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_first_exception(self): event1 = self.create_event() event2 = self.create_event() @@ -96,7 +96,7 @@ def wait_for_future1(): event2.set() future3.result() # wait for job to finish - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_first_exception_some_already_complete(self): event = self.create_event() future1 = self.executor.submit(divmod, 21, 0) @@ -118,7 +118,7 @@ def test_first_exception_some_already_complete(self): event.set() future2.result() # wait for job to finish - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_first_exception_one_already_failed(self): event = self.create_event() future1 = self.executor.submit(event.wait) @@ -134,7 +134,7 @@ def test_first_exception_one_already_failed(self): event.set() future1.result() # wait for job to finish - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_all_completed(self): future1 = self.executor.submit(divmod, 2, 0) future2 = self.executor.submit(mul, 2, 21) @@ -154,7 +154,7 @@ def test_all_completed(self): future2]), finished) self.assertEqual(set(), pending) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_timeout(self): short_timeout = 0.050 diff --git a/Lib/test/test_fork1.py b/Lib/test/test_fork1.py index 0d34ae7aa27028..550faa8a174ec6 100644 --- a/Lib/test/test_fork1.py +++ b/Lib/test/test_fork1.py @@ -20,7 +20,7 @@ class ForkTest(ForkWait): - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_threaded_import_lock_fork(self): """Check fork() in main thread works while a subthread is doing an import""" import_started = threading.Event() @@ -63,7 +63,7 @@ def importer(): except OSError: pass - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_nested_import_lock_fork(self): """Check fork() in main thread works while the main thread is doing an import""" exitcode = 42 diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py index 77431fdac08f23..d2ab45c4a5b1ea 100644 --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -259,7 +259,7 @@ def test_fd_non_inheritable(self): self.addCleanup(kqueue.close) self.assertEqual(os.get_inheritable(kqueue.fileno()), False) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.requires_fork() def test_fork(self): # gh-110395: kqueue objects must be closed after fork diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index dea2d5c8b18cf4..7a08f9ec9de9fb 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -730,7 +730,7 @@ def remove_loop(fname, tries): # based on os.fork existing because that is what users and this test use. # This helps ensure that when fork exists (the important concept) that the # register_at_fork mechanism is also present and used. - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.requires_fork() @threading_helper.requires_working_threading() @skip_if_asan_fork @@ -4046,7 +4046,7 @@ def test_config_queue_handler_invalid_config_does_not_create_multiprocessing_man self._apply_simple_queue_listener_configuration(qspec) manager.assert_not_called() - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @skip_if_tsan_fork @support.requires_subprocess() @unittest.skipUnless(support.Py_DEBUG, "requires a debug build for testing" @@ -4069,7 +4069,7 @@ def test_config_reject_simple_queue_handler_multiprocessing_context(self): with self.assertRaises(ValueError): self._apply_simple_queue_listener_configuration(qspec) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @skip_if_tsan_fork @support.requires_subprocess() @unittest.skipUnless(support.Py_DEBUG, "requires a debug build for testing" @@ -4110,7 +4110,7 @@ def _mpinit_issue121723(qspec, message_to_log): # log a message (this creates a record put in the queue) logging.getLogger().info(message_to_log) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @skip_if_tsan_fork @support.requires_subprocess() def test_multiprocessing_queues(self): @@ -5341,7 +5341,7 @@ def _extract_logrecord_process_name(key, logMultiprocessing, conn=None): else: return results - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @skip_if_tsan_fork def test_multiprocessing(self): support.skip_if_broken_multiprocessing_synchronize() diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 6f3156ac93ceec..288b2c4496faa1 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -1212,7 +1212,7 @@ def test_add_and_close(self): self.assertEqual(contents, f.read()) self._box = self._factory(self._path) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.requires_fork() @unittest.skipUnless(hasattr(socket, 'socketpair'), "Test needs socketpair().") def test_lock_conflict(self): diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 4656373d075058..9827a7f12ea21d 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3518,7 +3518,7 @@ def test_getppid(self): self.assertEqual(error, b'') self.assertEqual(int(stdout), os.getpid()) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def check_waitpid(self, code, exitcode, callback=None): if sys.platform == 'win32': # On Windows, os.spawnv() simply joins arguments with spaces: @@ -3621,35 +3621,35 @@ def create_args(self, *, with_env=False, use_bytes=False): return program, args - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnl') def test_spawnl(self): program, args = self.create_args() exitcode = os.spawnl(os.P_WAIT, program, *args) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnle') def test_spawnle(self): program, args = self.create_args(with_env=True) exitcode = os.spawnle(os.P_WAIT, program, *args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnlp') def test_spawnlp(self): program, args = self.create_args() exitcode = os.spawnlp(os.P_WAIT, program, *args) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnlpe') def test_spawnlpe(self): program, args = self.create_args(with_env=True) exitcode = os.spawnlpe(os.P_WAIT, program, *args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnv') def test_spawnv(self): program, args = self.create_args() @@ -3660,35 +3660,35 @@ def test_spawnv(self): exitcode = os.spawnv(os.P_WAIT, FakePath(program), args) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnve') def test_spawnve(self): program, args = self.create_args(with_env=True) exitcode = os.spawnve(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnvp') def test_spawnvp(self): program, args = self.create_args() exitcode = os.spawnvp(os.P_WAIT, program, args) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnvpe') def test_spawnvpe(self): program, args = self.create_args(with_env=True) exitcode = os.spawnvpe(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnv') def test_nowait(self): program, args = self.create_args() pid = os.spawnv(os.P_NOWAIT, program, args) support.wait_process(pid, exitcode=self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnve') def test_spawnve_bytes(self): # Test bytes handling in parse_arglist and parse_envlist (#28114) @@ -3696,21 +3696,21 @@ def test_spawnve_bytes(self): exitcode = os.spawnve(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnl') def test_spawnl_noargs(self): program, __ = self.create_args() self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program) self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program, '') - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnle') def test_spawnle_noargs(self): program, __ = self.create_args() self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, {}) self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, '', {}) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnv') def test_spawnv_noargs(self): program, __ = self.create_args() @@ -3719,7 +3719,7 @@ def test_spawnv_noargs(self): self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ('',)) self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ['']) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnve') def test_spawnve_noargs(self): program, __ = self.create_args() @@ -3776,12 +3776,12 @@ def _test_invalid_env(self, spawn): exitcode = spawn(os.P_WAIT, program, args, newenv) self.assertEqual(exitcode, 0) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnve') def test_spawnve_invalid_env(self): self._test_invalid_env(os.spawnve) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_os_func('spawnvpe') def test_spawnvpe_invalid_env(self): self._test_invalid_env(os.spawnvpe) @@ -4898,7 +4898,7 @@ def test_posix_pty_functions(self): self.addCleanup(os.close, son_fd) self.assertEqual(os.ptsname(mother_fd), os.ttyname(son_fd)) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(hasattr(os, 'spawnl'), "need os.spawnl()") @support.requires_subprocess() def test_pipe_spawnl(self): diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 78327bae98cf26..2e26134bae8323 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -465,7 +465,7 @@ def test_mac_ver(self): else: self.assertEqual(res[2], 'PowerPC') - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(sys.platform == 'darwin', "OSX only test") def test_mac_ver_with_fork(self): # Issue7895: platform.mac_ver() crashes when using fork without exec diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index d1e2c4582c3d73..fbba7025ac4abf 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -194,7 +194,7 @@ def test_openpty(self): s2 = _readline(master_fd) self.assertEqual(b'For my pet fish, Eric.\n', normalize_output(s2)) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_fork(self): debug("calling pty.fork()") pid, master_fd = pty.fork() @@ -296,7 +296,7 @@ def test_master_read(self): self.assertEqual(data, b"") - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() def test_spawn_doesnt_hang(self): self.addCleanup(unlink, TESTFN) with open(TESTFN, 'wb') as f: diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index 460695b131bf37..1e57b9244b4fd5 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -1401,7 +1401,7 @@ def test__all__(self): # tests validity but not completeness of the __all__ list self.assertTrue(set(random.__all__) <= set(dir(random))) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @test.support.requires_fork() def test_after_fork(self): # Test the global Random instance gets reseeded in child diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 4e8714c79fcd42..893372cbbd0be9 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -44,7 +44,7 @@ def receive(sock, n, timeout=test.support.SHORT_TIMEOUT): raise RuntimeError("timed out on %r" % (sock,)) -@warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 +@warnings_helper.ignore_fork_in_thread_deprecation_warnings() @test.support.requires_fork() @contextlib.contextmanager def simple_subprocess(testcase): @@ -175,7 +175,7 @@ def test_ThreadingTCPServer(self): socketserver.StreamRequestHandler, self.stream_examine) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_forking def test_ForkingTCPServer(self): with simple_subprocess(self): @@ -195,7 +195,7 @@ def test_ThreadingUnixStreamServer(self): socketserver.StreamRequestHandler, self.stream_examine) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_unix_sockets @requires_forking def test_ForkingUnixStreamServer(self): @@ -214,7 +214,7 @@ def test_ThreadingUDPServer(self): socketserver.DatagramRequestHandler, self.dgram_examine) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_forking def test_ForkingUDPServer(self): with simple_subprocess(self): @@ -234,7 +234,7 @@ def test_ThreadingUnixDatagramServer(self): socketserver.DatagramRequestHandler, self.dgram_examine) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_unix_sockets @requires_forking def test_ForkingUnixDatagramServer(self): @@ -320,13 +320,13 @@ def test_threading_not_handled(self): self.assertIs(cm.exc_type, SystemExit) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_forking def test_forking_handled(self): ForkingErrorTestServer(ValueError) self.check_result(handled=True) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @requires_forking def test_forking_not_handled(self): ForkingErrorTestServer(SystemExit) diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index f88575140a451b..12361aa4e518a6 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -485,7 +485,7 @@ def test_check__all__(self): self.assertRaises(AssertionError, support.check__all__, self, unittest) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @unittest.skipUnless(hasattr(os, 'waitpid') and hasattr(os, 'WNOHANG'), 'need os.waitpid() and os.WNOHANG') @support.requires_fork() diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index 98fd20935cc201..9d3ff8a620b6f2 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -354,7 +354,7 @@ def fork_child(self): # everything is fine return 0 - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.requires_fork() def test_fork(self): # check that tracemalloc is still working after fork diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index b99940556ea6b6..edce504fc4ba65 100755 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -1112,7 +1112,7 @@ def test_uuid8_uniqueness(self): versions = {u.version for u in uuids} self.assertSetEqual(versions, {8}) - @warnings_helper.ignore_fork_in_thread_deprecation_warnings # gh-135427 + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @support.requires_fork() def testIssue8621(self): # On at least some versions of OSX self.uuid.uuid4 generates diff --git a/Misc/mypy/_colorize.py b/Misc/mypy/_colorize.py deleted file mode 120000 index 9b7304769ec30b..00000000000000 --- a/Misc/mypy/_colorize.py +++ /dev/null @@ -1 +0,0 @@ -../../Lib/_colorize.py \ No newline at end of file diff --git a/Misc/mypy/_colorize.py b/Misc/mypy/_colorize.py new file mode 100644 index 00000000000000..4a310a402358b6 --- /dev/null +++ b/Misc/mypy/_colorize.py @@ -0,0 +1,346 @@ +import io +import os +import sys + +from collections.abc import Callable, Iterator, Mapping +from dataclasses import dataclass, field, Field + +COLORIZE = True + + +# types +if False: + from typing import IO, Self, ClassVar + _theme: Theme + + +class ANSIColors: + RESET = "\x1b[0m" + + BLACK = "\x1b[30m" + BLUE = "\x1b[34m" + CYAN = "\x1b[36m" + GREEN = "\x1b[32m" + GREY = "\x1b[90m" + MAGENTA = "\x1b[35m" + RED = "\x1b[31m" + WHITE = "\x1b[37m" # more like LIGHT GRAY + YELLOW = "\x1b[33m" + + BOLD = "\x1b[1m" + BOLD_BLACK = "\x1b[1;30m" # DARK GRAY + BOLD_BLUE = "\x1b[1;34m" + BOLD_CYAN = "\x1b[1;36m" + BOLD_GREEN = "\x1b[1;32m" + BOLD_MAGENTA = "\x1b[1;35m" + BOLD_RED = "\x1b[1;31m" + BOLD_WHITE = "\x1b[1;37m" # actual WHITE + BOLD_YELLOW = "\x1b[1;33m" + + # intense = like bold but without being bold + INTENSE_BLACK = "\x1b[90m" + INTENSE_BLUE = "\x1b[94m" + INTENSE_CYAN = "\x1b[96m" + INTENSE_GREEN = "\x1b[92m" + INTENSE_MAGENTA = "\x1b[95m" + INTENSE_RED = "\x1b[91m" + INTENSE_WHITE = "\x1b[97m" + INTENSE_YELLOW = "\x1b[93m" + + BACKGROUND_BLACK = "\x1b[40m" + BACKGROUND_BLUE = "\x1b[44m" + BACKGROUND_CYAN = "\x1b[46m" + BACKGROUND_GREEN = "\x1b[42m" + BACKGROUND_MAGENTA = "\x1b[45m" + BACKGROUND_RED = "\x1b[41m" + BACKGROUND_WHITE = "\x1b[47m" + BACKGROUND_YELLOW = "\x1b[43m" + + INTENSE_BACKGROUND_BLACK = "\x1b[100m" + INTENSE_BACKGROUND_BLUE = "\x1b[104m" + INTENSE_BACKGROUND_CYAN = "\x1b[106m" + INTENSE_BACKGROUND_GREEN = "\x1b[102m" + INTENSE_BACKGROUND_MAGENTA = "\x1b[105m" + INTENSE_BACKGROUND_RED = "\x1b[101m" + INTENSE_BACKGROUND_WHITE = "\x1b[107m" + INTENSE_BACKGROUND_YELLOW = "\x1b[103m" + + +ColorCodes = set() +NoColors = ANSIColors() + +for attr, code in ANSIColors.__dict__.items(): + if not attr.startswith("__"): + ColorCodes.add(code) + setattr(NoColors, attr, "") + + +# +# Experimental theming support (see gh-133346) +# + +# - Create a theme by copying an existing `Theme` with one or more sections +# replaced, using `default_theme.copy_with()`; +# - create a theme section by copying an existing `ThemeSection` with one or +# more colors replaced, using for example `default_theme.syntax.copy_with()`; +# - create a theme from scratch by instantiating a `Theme` data class with +# the required sections (which are also dataclass instances). +# +# Then call `_colorize.set_theme(your_theme)` to set it. +# +# Put your theme configuration in $PYTHONSTARTUP for the interactive shell, +# or sitecustomize.py in your virtual environment or Python installation for +# other uses. Your applications can call `_colorize.set_theme()` too. +# +# Note that thanks to the dataclasses providing default values for all fields, +# creating a new theme or theme section from scratch is possible without +# specifying all keys. +# +# For example, here's a theme that makes punctuation and operators less prominent: +# +# try: +# from _colorize import set_theme, default_theme, Syntax, ANSIColors +# except ImportError: +# pass +# else: +# theme_with_dim_operators = default_theme.copy_with( +# syntax=Syntax(op=ANSIColors.INTENSE_BLACK), +# ) +# set_theme(theme_with_dim_operators) +# del set_theme, default_theme, Syntax, ANSIColors, theme_with_dim_operators +# +# Guarding the import ensures that your .pythonstartup file will still work in +# Python 3.13 and older. Deleting the variables ensures they don't remain in your +# interactive shell's global scope. + +class ThemeSection(Mapping[str, str]): + """A mixin/base class for theme sections. + + It enables dictionary access to a section, as well as implements convenience + methods. + """ + + # The two types below are just that: types to inform the type checker that the + # mixin will work in context of those fields existing + __dataclass_fields__: ClassVar[dict[str, Field[str]]] + _name_to_value: Callable[[str], str] + + def __post_init__(self) -> None: + name_to_value = {} + for color_name in self.__dataclass_fields__: + name_to_value[color_name] = getattr(self, color_name) + super().__setattr__('_name_to_value', name_to_value.__getitem__) + + def copy_with(self, **kwargs: str) -> Self: + color_state: dict[str, str] = {} + for color_name in self.__dataclass_fields__: + color_state[color_name] = getattr(self, color_name) + color_state.update(kwargs) + return type(self)(**color_state) + + @classmethod + def no_colors(cls) -> Self: + color_state: dict[str, str] = {} + for color_name in cls.__dataclass_fields__: + color_state[color_name] = "" + return cls(**color_state) + + def __getitem__(self, key: str) -> str: + return self._name_to_value(key) + + def __len__(self) -> int: + return len(self.__dataclass_fields__) + + def __iter__(self) -> Iterator[str]: + return iter(self.__dataclass_fields__) + + +@dataclass(frozen=True) +class Argparse(ThemeSection): + usage: str = ANSIColors.BOLD_BLUE + prog: str = ANSIColors.BOLD_MAGENTA + prog_extra: str = ANSIColors.MAGENTA + heading: str = ANSIColors.BOLD_BLUE + summary_long_option: str = ANSIColors.CYAN + summary_short_option: str = ANSIColors.GREEN + summary_label: str = ANSIColors.YELLOW + summary_action: str = ANSIColors.GREEN + long_option: str = ANSIColors.BOLD_CYAN + short_option: str = ANSIColors.BOLD_GREEN + label: str = ANSIColors.BOLD_YELLOW + action: str = ANSIColors.BOLD_GREEN + reset: str = ANSIColors.RESET + + +@dataclass(frozen=True) +class Syntax(ThemeSection): + prompt: str = ANSIColors.BOLD_MAGENTA + keyword: str = ANSIColors.BOLD_BLUE + builtin: str = ANSIColors.CYAN + comment: str = ANSIColors.RED + string: str = ANSIColors.GREEN + number: str = ANSIColors.YELLOW + op: str = ANSIColors.RESET + definition: str = ANSIColors.BOLD + soft_keyword: str = ANSIColors.BOLD_BLUE + reset: str = ANSIColors.RESET + + +@dataclass(frozen=True) +class Traceback(ThemeSection): + type: str = ANSIColors.BOLD_MAGENTA + message: str = ANSIColors.MAGENTA + filename: str = ANSIColors.MAGENTA + line_no: str = ANSIColors.MAGENTA + frame: str = ANSIColors.MAGENTA + error_highlight: str = ANSIColors.BOLD_RED + error_range: str = ANSIColors.RED + reset: str = ANSIColors.RESET + + +@dataclass(frozen=True) +class Unittest(ThemeSection): + passed: str = ANSIColors.GREEN + warn: str = ANSIColors.YELLOW + fail: str = ANSIColors.RED + fail_info: str = ANSIColors.BOLD_RED + reset: str = ANSIColors.RESET + + +@dataclass(frozen=True) +class Theme: + """A suite of themes for all sections of Python. + + When adding a new one, remember to also modify `copy_with` and `no_colors` + below. + """ + argparse: Argparse = field(default_factory=Argparse) + syntax: Syntax = field(default_factory=Syntax) + traceback: Traceback = field(default_factory=Traceback) + unittest: Unittest = field(default_factory=Unittest) + + def copy_with( + self, + *, + argparse: Argparse | None = None, + syntax: Syntax | None = None, + traceback: Traceback | None = None, + unittest: Unittest | None = None, + ) -> Self: + """Return a new Theme based on this instance with some sections replaced. + + Themes are immutable to protect against accidental modifications that + could lead to invalid terminal states. + """ + return type(self)( + argparse=argparse or self.argparse, + syntax=syntax or self.syntax, + traceback=traceback or self.traceback, + unittest=unittest or self.unittest, + ) + + @classmethod + def no_colors(cls) -> Self: + """Return a new Theme where colors in all sections are empty strings. + + This allows writing user code as if colors are always used. The color + fields will be ANSI color code strings when colorization is desired + and possible, and empty strings otherwise. + """ + return cls( + argparse=Argparse.no_colors(), + syntax=Syntax.no_colors(), + traceback=Traceback.no_colors(), + unittest=Unittest.no_colors(), + ) + + +def get_colors( + colorize: bool = False, *, file: IO[str] | IO[bytes] | None = None +) -> ANSIColors: + if colorize or can_colorize(file=file): + return ANSIColors() + else: + return NoColors + + +def decolor(text: str) -> str: + """Remove ANSI color codes from a string.""" + for code in ColorCodes: + text = text.replace(code, "") + return text + + +def can_colorize(*, file: IO[str] | IO[bytes] | None = None) -> bool: + if file is None: + file = sys.stdout + + if not sys.flags.ignore_environment: + if os.environ.get("PYTHON_COLORS") == "0": + return False + if os.environ.get("PYTHON_COLORS") == "1": + return True + if os.environ.get("NO_COLOR"): + return False + if not COLORIZE: + return False + if os.environ.get("FORCE_COLOR"): + return True + if os.environ.get("TERM") == "dumb": + return False + + if not hasattr(file, "fileno"): + return False + + if sys.platform == "win32": + try: + import nt + + if not nt._supports_virtual_terminal(): + return False + except (ImportError, AttributeError): + return False + + try: + return os.isatty(file.fileno()) + except io.UnsupportedOperation: + return hasattr(file, "isatty") and file.isatty() + + +default_theme = Theme() +theme_no_color = default_theme.no_colors() + + +def get_theme( + *, + tty_file: IO[str] | IO[bytes] | None = None, + force_color: bool = False, + force_no_color: bool = False, +) -> Theme: + """Returns the currently set theme, potentially in a zero-color variant. + + In cases where colorizing is not possible (see `can_colorize`), the returned + theme contains all empty strings in all color definitions. + See `Theme.no_colors()` for more information. + + It is recommended not to cache the result of this function for extended + periods of time because the user might influence theme selection by + the interactive shell, a debugger, or application-specific code. The + environment (including environment variable state and console configuration + on Windows) can also change in the course of the application life cycle. + """ + if force_color or (not force_no_color and can_colorize(file=tty_file)): + return _theme + return theme_no_color + + +def set_theme(t: Theme) -> None: + global _theme + + if not isinstance(t, Theme): + raise ValueError(f"Expected Theme object, found {t}") + + _theme = t + + +set_theme(default_theme) diff --git a/Misc/mypy/token.py b/Misc/mypy/token.py deleted file mode 120000 index 0a39f726dda1aa..00000000000000 --- a/Misc/mypy/token.py +++ /dev/null @@ -1 +0,0 @@ -../../Lib/token.py \ No newline at end of file diff --git a/Misc/mypy/token.py b/Misc/mypy/token.py new file mode 100644 index 00000000000000..f61723cc09da02 --- /dev/null +++ b/Misc/mypy/token.py @@ -0,0 +1,144 @@ +"""Token constants.""" +# Auto-generated by Tools/build/generate_token.py + +__all__ = ['tok_name', 'ISTERMINAL', 'ISNONTERMINAL', 'ISEOF', + 'EXACT_TOKEN_TYPES'] + +ENDMARKER = 0 +NAME = 1 +NUMBER = 2 +STRING = 3 +NEWLINE = 4 +INDENT = 5 +DEDENT = 6 +LPAR = 7 +RPAR = 8 +LSQB = 9 +RSQB = 10 +COLON = 11 +COMMA = 12 +SEMI = 13 +PLUS = 14 +MINUS = 15 +STAR = 16 +SLASH = 17 +VBAR = 18 +AMPER = 19 +LESS = 20 +GREATER = 21 +EQUAL = 22 +DOT = 23 +PERCENT = 24 +LBRACE = 25 +RBRACE = 26 +EQEQUAL = 27 +NOTEQUAL = 28 +LESSEQUAL = 29 +GREATEREQUAL = 30 +TILDE = 31 +CIRCUMFLEX = 32 +LEFTSHIFT = 33 +RIGHTSHIFT = 34 +DOUBLESTAR = 35 +PLUSEQUAL = 36 +MINEQUAL = 37 +STAREQUAL = 38 +SLASHEQUAL = 39 +PERCENTEQUAL = 40 +AMPEREQUAL = 41 +VBAREQUAL = 42 +CIRCUMFLEXEQUAL = 43 +LEFTSHIFTEQUAL = 44 +RIGHTSHIFTEQUAL = 45 +DOUBLESTAREQUAL = 46 +DOUBLESLASH = 47 +DOUBLESLASHEQUAL = 48 +AT = 49 +ATEQUAL = 50 +RARROW = 51 +ELLIPSIS = 52 +COLONEQUAL = 53 +EXCLAMATION = 54 +OP = 55 +TYPE_IGNORE = 56 +TYPE_COMMENT = 57 +SOFT_KEYWORD = 58 +FSTRING_START = 59 +FSTRING_MIDDLE = 60 +FSTRING_END = 61 +TSTRING_START = 62 +TSTRING_MIDDLE = 63 +TSTRING_END = 64 +COMMENT = 65 +NL = 66 +# These aren't used by the C tokenizer but are needed for tokenize.py +ERRORTOKEN = 67 +ENCODING = 68 +N_TOKENS = 69 +# Special definitions for cooperation with parser +NT_OFFSET = 256 + +tok_name = {value: name + for name, value in globals().items() + if isinstance(value, int) and not name.startswith('_')} +__all__.extend(tok_name.values()) + +EXACT_TOKEN_TYPES = { + '!': EXCLAMATION, + '!=': NOTEQUAL, + '%': PERCENT, + '%=': PERCENTEQUAL, + '&': AMPER, + '&=': AMPEREQUAL, + '(': LPAR, + ')': RPAR, + '*': STAR, + '**': DOUBLESTAR, + '**=': DOUBLESTAREQUAL, + '*=': STAREQUAL, + '+': PLUS, + '+=': PLUSEQUAL, + ',': COMMA, + '-': MINUS, + '-=': MINEQUAL, + '->': RARROW, + '.': DOT, + '...': ELLIPSIS, + '/': SLASH, + '//': DOUBLESLASH, + '//=': DOUBLESLASHEQUAL, + '/=': SLASHEQUAL, + ':': COLON, + ':=': COLONEQUAL, + ';': SEMI, + '<': LESS, + '<<': LEFTSHIFT, + '<<=': LEFTSHIFTEQUAL, + '<=': LESSEQUAL, + '=': EQUAL, + '==': EQEQUAL, + '>': GREATER, + '>=': GREATEREQUAL, + '>>': RIGHTSHIFT, + '>>=': RIGHTSHIFTEQUAL, + '@': AT, + '@=': ATEQUAL, + '[': LSQB, + ']': RSQB, + '^': CIRCUMFLEX, + '^=': CIRCUMFLEXEQUAL, + '{': LBRACE, + '|': VBAR, + '|=': VBAREQUAL, + '}': RBRACE, + '~': TILDE, +} + +def ISTERMINAL(x: int) -> bool: + return x < NT_OFFSET + +def ISNONTERMINAL(x: int) -> bool: + return x >= NT_OFFSET + +def ISEOF(x: int) -> bool: + return x == ENDMARKER diff --git a/changed, 7314 insertions(+), 3271 deletions(-) b/changed, 7314 insertions(+), 3271 deletions(-) new file mode 100644 index 00000000000000..7412e0a5a2b01b --- /dev/null +++ b/changed, 7314 insertions(+), 3271 deletions(-) @@ -0,0 +1,227 @@ + .github/workflows/build.yml | 30 +- + .github/workflows/reusable-san.yml | 124 +++++ + .github/workflows/reusable-tsan.yml | 94 ---- + .github/workflows/reusable-ubsan.yml | 74 --- + Android/android.py | 73 +-- + Doc/Makefile | 1 + + Doc/c-api/arg.rst | 15 - + Doc/c-api/init.rst | 42 +- + Doc/c-api/memory.rst | 4 + + Doc/c-api/perfmaps.rst | 9 +- + Doc/deprecations/pending-removal-in-3.15.rst | 2 +- + Doc/glossary.rst | 7 +- + Doc/howto/logging.rst | 8 +- + Doc/howto/perf_profiling.rst | 56 ++- + Doc/library/annotationlib.rst | 2 +- + Doc/library/argparse.rst | 32 +- + Doc/library/ast.rst | 54 ++- + Doc/library/dis.rst | 42 ++ + Doc/library/enum.rst | 23 +- + Doc/library/fractions.rst | 4 +- + Doc/library/gc.rst | 8 +- + Doc/library/gzip.rst | 20 +- + Doc/library/http.client.rst | 22 +- + Doc/library/ipaddress.rst | 12 +- + Doc/library/multiprocessing.rst | 9 +- + Doc/library/os.path.rst | 36 +- + Doc/library/pathlib.rst | 14 - + Doc/library/stdtypes.rst | 6 +- + Doc/library/string.rst | 25 +- + Doc/library/string.templatelib.rst | 313 ++++++++++++ + Doc/library/sys.rst | 7 +- + Doc/library/tarfile.rst | 46 +- + Doc/library/text.rst | 1 + + Doc/library/types.rst | 10 + + Doc/library/urllib.request.rst | 14 +- + Doc/library/zipfile.rst | 8 - + Doc/reference/compound_stmts.rst | 4 +- + Doc/reference/lexical_analysis.rst | 50 +- + Doc/tutorial/inputoutput.rst | 9 +- + Doc/tutorial/modules.rst | 4 +- + Doc/using/configure.rst | 3 + + Doc/using/windows.rst | 362 ++++++++------ + Doc/whatsnew/3.13.rst | 2 +- + Doc/whatsnew/3.14.rst | 90 +++- + Doc/whatsnew/3.15.rst | 32 +- + Grammar/python.gram | 11 +- + Include/cpython/critical_section.h | 20 + + Include/internal/pycore_critical_section.h | 14 +- + Include/internal/pycore_pylifecycle.h | 1 + + Lib/_ast_unparse.py | 26 +- + Lib/_pyrepl/_minimal_curses.py | 68 --- + Lib/_pyrepl/curses.py | 33 -- + Lib/_pyrepl/terminfo.py | 488 +++++++++++++++++++ + Lib/_pyrepl/trace.py | 27 +- + Lib/_pyrepl/unix_console.py | 16 +- + Lib/_pyrepl/unix_eventqueue.py | 11 +- + Lib/_pyrepl/utils.py | 4 +- + Lib/argparse.py | 6 +- + Lib/concurrent/futures/interpreter.py | 2 + + Lib/dataclasses.py | 17 +- + Lib/enum.py | 2 +- + Lib/gzip.py | 6 +- + Lib/hashlib.py | 32 +- + Lib/hmac.py | 14 + + Lib/html/parser.py | 24 +- + Lib/http/client.py | 40 +- + Lib/multiprocessing/resource_tracker.py | 8 +- + Lib/pathlib/__init__.py | 12 - + Lib/tarfile.py | 4 +- + Lib/test/_test_multiprocessing.py | 250 +++++++++- + Lib/test/datetimetester.py | 28 ++ + Lib/test/pythoninfo.py | 1 + + Lib/test/support/__init__.py | 5 +- + Lib/test/support/hashlib_helper.py | 711 +++++++++++++++++---------- + Lib/test/support/warnings_helper.py | 37 +- + Lib/test/test_argparse.py | 23 +- + Lib/test/test_ast/test_ast.py | 7 - + Lib/test/test_asyncio/test_unix_events.py | 6 +- + Lib/test/test_build_details.py | 13 +- + Lib/test/test_builtin.py | 2 + + Lib/test/test_capi/test_emscripten.py | 25 + + Lib/test/test_capi/test_getargs.py | 117 ----- + Lib/test/test_clinic.py | 1 + + Lib/test/test_concurrent_futures/executor.py | 16 +- + Lib/test/test_concurrent_futures/test_as_completed.py | 4 + + Lib/test/test_concurrent_futures/test_deadlock.py | 6 + + Lib/test/test_concurrent_futures/test_init.py | 3 + + Lib/test/test_concurrent_futures/test_interpreter_pool.py | 15 + + Lib/test/test_concurrent_futures/test_process_pool.py | 9 +- + Lib/test/test_concurrent_futures/test_shutdown.py | 14 +- + Lib/test/test_concurrent_futures/test_wait.py | 11 +- + Lib/test/test_concurrent_futures/util.py | 11 +- + Lib/test/test_dataclasses/__init__.py | 35 ++ + Lib/test/test_fcntl.py | 5 +- + Lib/test/test_fork1.py | 4 +- + Lib/test/test_free_threading/test_syslog.py | 44 ++ + Lib/test/test_generated_cases.py | 2 +- + Lib/test/test_gettext.py | 7 + + Lib/test/test_gzip.py | 2 +- + Lib/test/test_hashlib.py | 26 +- + Lib/test/test_hmac.py | 2 +- + Lib/test/test_htmlparser.py | 124 ++++- + Lib/test/test_httplib.py | 46 ++ + Lib/test/test_import/__init__.py | 4 +- + Lib/test/test_inspect/test_inspect.py | 1 + + Lib/test/test_kqueue.py | 3 + + Lib/test/test_logging.py | 5 + + Lib/test/test_mailbox.py | 3 +- + Lib/test/test_mmap.py | 2 +- + Lib/test/test_os.py | 18 + + Lib/test/test_pathlib/test_pathlib.py | 12 +- + Lib/test/test_perfmaps.py | 12 +- + Lib/test/test_platform.py | 4 +- + Lib/test/test_pty.py | 6 +- + Lib/test/test_pydoc/test_pydoc.py | 4 +- + Lib/test/test_pyrepl/__init__.py | 20 +- + Lib/test/test_pyrepl/test_eventqueue.py | 11 +- + Lib/test/test_pyrepl/test_pyrepl.py | 9 +- + Lib/test/test_pyrepl/test_reader.py | 12 +- + Lib/test/test_pyrepl/test_terminfo.py | 651 +++++++++++++++++++++++++ + Lib/test/test_pyrepl/test_unix_console.py | 40 +- + Lib/test/test_random.py | 3 + + Lib/test/test_remote_pdb.py | 53 +- + Lib/test/test_samply_profiler.py | 244 ++++++++++ + Lib/test/test_socketserver.py | 8 + + Lib/test/test_support.py | 143 ++++-- + Lib/test/test_sysconfig.py | 2 +- + Lib/test/test_traceback.py | 19 + + Lib/test/test_tracemalloc.py | 3 +- + Lib/test/test_tstring.py | 73 +-- + Lib/test/test_types.py | 11 + + Lib/test/test_unparse.py | 4 - + Lib/test/test_urllib.py | 8 + + Lib/test/test_uuid.py | 3 +- + Lib/test/test_venv.py | 4 +- + Lib/test/test_zipfile/test_core.py | 54 --- + Lib/tkinter/scrolledtext.py | 2 +- + Lib/traceback.py | 5 + + Lib/types.py | 5 +- + Lib/urllib/request.py | 10 +- + Lib/xmlrpc/server.py | 2 +- + Lib/zipfile/__init__.py | 13 - + Makefile.pre.in | 56 ++- + Misc/ACKS | 2 + + Misc/NEWS.d/3.11.0a1.rst | 2 +- + Misc/NEWS.d/3.13.0a4.rst | 2 +- + Misc/NEWS.d/3.14.0b1.rst | 6 +- + Misc/NEWS.d/next/Build/2025-07-18-17-15-00.gh-issue-135621.9cyCNb.rst | 2 + + Misc/NEWS.d/next/C_API/2025-06-24-11-10-01.gh-issue-133296.lIEuVJ.rst | 3 + + Misc/NEWS.d/next/C_API/2025-07-22-15-18-08.gh-issue-112068.4WvT-8.rst | 1 + + Misc/NEWS.d/next/Core_and_Builtins/2025-07-08-23-22-08.gh-issue-132661.34ftJl.rst | 5 + + Misc/NEWS.d/next/Core_and_Builtins/2025-07-09-11-15-42.gh-issue-136459.m4Udh8.rst | 3 + + Misc/NEWS.d/next/Core_and_Builtins/2025-07-12-09-59-14.gh-issue-136421.ZD1rNj.rst | 1 + + Misc/NEWS.d/next/Core_and_Builtins/2025-07-18-08-43-35.gh-issue-116738.i0HWtP.rst | 2 + + Misc/NEWS.d/next/Core_and_Builtins/2025-07-19-12-37-05.gh-issue-136801.XU_tF2.rst | 1 + + Misc/NEWS.d/next/Core_and_Builtins/2025-07-19-17-08-09.gh-issue-127598.Mx8S-y.rst | 2 + + Misc/NEWS.d/next/Library/2025-03-19-12-41-42.gh-issue-91349.8eTOCP.rst | 3 + + Misc/NEWS.d/next/Library/2025-05-11-11-39-05.gh-issue-133875.pUar3l.rst | 2 + + Misc/NEWS.d/next/Library/2025-07-05-09-45-04.gh-issue-136286.N67Amr.rst | 2 +- + Misc/NEWS.d/next/Library/2025-07-10-00-47-37.gh-issue-136470.KlUEUG.rst | 2 + + Misc/NEWS.d/next/Library/2025-07-11-10-23-44.gh-issue-136492.BVi5h0.rst | 1 + + Misc/NEWS.d/next/Library/2025-07-19-11-53-19.gh-issue-135427.iJM_X2.rst | 1 + + Misc/NEWS.d/next/Library/2025-07-19-15-40-47.gh-issue-131724.LS59nA.rst | 4 + + Misc/NEWS.d/next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst | 1 + + Misc/NEWS.d/next/Library/2025-07-20-10-21-49.gh-issue-136787._0Rbp_.rst | 4 + + Misc/NEWS.d/next/Library/2025-07-20-16-02-00.gh-issue-136874.cLC3o1.rst | 1 + + Misc/NEWS.d/next/Library/2025-07-20-16-56-55.gh-issue-135228.n_XIao.rst | 4 + + Misc/NEWS.d/next/Library/2025-07-21-16-10-24.gh-issue-124621.wyoWc1.rst | 1 + + Misc/NEWS.d/next/Library/2025-07-21-22-35-50.gh-issue-136170.QUlc78.rst | 3 + + Misc/NEWS.d/next/Security/2025-06-09-20-38-25.gh-issue-118350.KgWCcP.rst | 2 + + Misc/NEWS.d/next/Security/2025-06-25-14-13-39.gh-issue-135661.idjQ0B.rst | 5 - + Misc/NEWS.d/next/Tools-Demos/2025-06-11-12-14-06.gh-issue-135379.25ttXq.rst | 2 +- + Misc/NEWS.d/next/Tools-Demos/2025-07-05-15-10-42.gh-issue-136251.GRM6o8.rst | 1 + + Modules/Setup.bootstrap.in | 2 + + Modules/Setup.stdlib.in | 3 - + Modules/_ctypes/_ctypes.c | 12 +- + Modules/_ctypes/ctypes.h | 2 +- + Modules/_datetimemodule.c | 165 +++---- + Modules/_hashopenssl.c | 233 ++++++--- + Modules/_interpretersmodule.c | 9 +- + Modules/_json.c | 13 +- + Modules/_testcapimodule.c | 10 + + Modules/_testinternalcapi.c | 34 ++ + Modules/_threadmodule.c | 18 +- + Modules/_typesmodule.c | 1 + + Modules/_zstd/_zstdmodule.c | 2 +- + Modules/_zstd/_zstdmodule.h | 2 +- + Modules/_zstd/buffer.h | 2 +- + Modules/_zstd/compressor.c | 2 +- + Modules/_zstd/decompressor.c | 2 +- + Modules/_zstd/zstddict.c | 2 +- + Modules/_zstd/zstddict.h | 2 +- + Modules/clinic/posixmodule.c.h | 80 ++- + Modules/hashlib.h | 9 + + Modules/hmacmodule.c | 2 +- + Modules/mmapmodule.c | 15 +- + Modules/posixmodule.c | 41 +- + Modules/syslogmodule.c | 8 +- + Objects/frameobject.c | 10 + + Objects/templateobject.c | 91 +--- + Objects/typeobject.c | 4 +- + Objects/unicodeobject.c | 15 +- + PCbuild/_freeze_module.vcxproj | 1 + + Parser/action_helpers.c | 17 +- + Parser/parser.c | 2500 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------- + Parser/pegen.h | 1 + + Python/asm_trampoline.S | 13 + + Python/ast_unparse.c | 86 +--- + Python/codegen.c | 10 - + Python/critical_section.c | 18 + + Python/emscripten_syscalls.c | 284 +++++++++++ + Python/getargs.c | 247 ++++------ + Python/instrumentation.c | 4 + + Python/perf_jit_trampoline.c | 35 +- + Python/pylifecycle.c | 5 + + Python/pystate.c | 9 + + Tools/cases_generator/optimizer_generator.py | 6 +- + Tools/wasm/README.md | 10 +- + Tools/wasm/emscripten/__main__.py | 25 +- + Tools/wasm/{ => emscripten}/config.site-wasm32-emscripten | 3 +- + Tools/wasm/emscripten/{web_example => }/wasm_assets.py | 3 +- + Tools/wasm/emscripten/web_example/{python.html => index.html} | 362 ++++++++++++-- + Tools/wasm/emscripten/web_example_pyrepl_jspi/index.html | 34 ++ + Tools/wasm/emscripten/web_example_pyrepl_jspi/src.mjs | 194 ++++++++ + configure | 6 +- + configure.ac | 7 +- + 226 files changed, 7314 insertions(+), 3271 deletions(-) From 52f6f9702b3d8028c28d50f6c56af95f5417ca1d Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Thu, 31 Jul 2025 21:03:21 +0200 Subject: [PATCH 25/29] Linting fix --- Lib/test/support/warnings_helper.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/test/support/warnings_helper.py b/Lib/test/support/warnings_helper.py index aeed570e22d6a6..c046f39fbff511 100644 --- a/Lib/test/support/warnings_helper.py +++ b/Lib/test/support/warnings_helper.py @@ -1,11 +1,9 @@ import contextlib -import functools import importlib import re import sys import warnings -import inspect def import_deprecated(name): From 36147a13de749f8ab93553bdf94fb39ffd9fc30e Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Thu, 31 Jul 2025 21:09:16 +0200 Subject: [PATCH 26/29] Remove Misc/mypy/_colorize.py - should be a symlink --- Misc/mypy/_colorize.py | 346 ----------------------------------------- 1 file changed, 346 deletions(-) delete mode 100644 Misc/mypy/_colorize.py diff --git a/Misc/mypy/_colorize.py b/Misc/mypy/_colorize.py deleted file mode 100644 index 4a310a402358b6..00000000000000 --- a/Misc/mypy/_colorize.py +++ /dev/null @@ -1,346 +0,0 @@ -import io -import os -import sys - -from collections.abc import Callable, Iterator, Mapping -from dataclasses import dataclass, field, Field - -COLORIZE = True - - -# types -if False: - from typing import IO, Self, ClassVar - _theme: Theme - - -class ANSIColors: - RESET = "\x1b[0m" - - BLACK = "\x1b[30m" - BLUE = "\x1b[34m" - CYAN = "\x1b[36m" - GREEN = "\x1b[32m" - GREY = "\x1b[90m" - MAGENTA = "\x1b[35m" - RED = "\x1b[31m" - WHITE = "\x1b[37m" # more like LIGHT GRAY - YELLOW = "\x1b[33m" - - BOLD = "\x1b[1m" - BOLD_BLACK = "\x1b[1;30m" # DARK GRAY - BOLD_BLUE = "\x1b[1;34m" - BOLD_CYAN = "\x1b[1;36m" - BOLD_GREEN = "\x1b[1;32m" - BOLD_MAGENTA = "\x1b[1;35m" - BOLD_RED = "\x1b[1;31m" - BOLD_WHITE = "\x1b[1;37m" # actual WHITE - BOLD_YELLOW = "\x1b[1;33m" - - # intense = like bold but without being bold - INTENSE_BLACK = "\x1b[90m" - INTENSE_BLUE = "\x1b[94m" - INTENSE_CYAN = "\x1b[96m" - INTENSE_GREEN = "\x1b[92m" - INTENSE_MAGENTA = "\x1b[95m" - INTENSE_RED = "\x1b[91m" - INTENSE_WHITE = "\x1b[97m" - INTENSE_YELLOW = "\x1b[93m" - - BACKGROUND_BLACK = "\x1b[40m" - BACKGROUND_BLUE = "\x1b[44m" - BACKGROUND_CYAN = "\x1b[46m" - BACKGROUND_GREEN = "\x1b[42m" - BACKGROUND_MAGENTA = "\x1b[45m" - BACKGROUND_RED = "\x1b[41m" - BACKGROUND_WHITE = "\x1b[47m" - BACKGROUND_YELLOW = "\x1b[43m" - - INTENSE_BACKGROUND_BLACK = "\x1b[100m" - INTENSE_BACKGROUND_BLUE = "\x1b[104m" - INTENSE_BACKGROUND_CYAN = "\x1b[106m" - INTENSE_BACKGROUND_GREEN = "\x1b[102m" - INTENSE_BACKGROUND_MAGENTA = "\x1b[105m" - INTENSE_BACKGROUND_RED = "\x1b[101m" - INTENSE_BACKGROUND_WHITE = "\x1b[107m" - INTENSE_BACKGROUND_YELLOW = "\x1b[103m" - - -ColorCodes = set() -NoColors = ANSIColors() - -for attr, code in ANSIColors.__dict__.items(): - if not attr.startswith("__"): - ColorCodes.add(code) - setattr(NoColors, attr, "") - - -# -# Experimental theming support (see gh-133346) -# - -# - Create a theme by copying an existing `Theme` with one or more sections -# replaced, using `default_theme.copy_with()`; -# - create a theme section by copying an existing `ThemeSection` with one or -# more colors replaced, using for example `default_theme.syntax.copy_with()`; -# - create a theme from scratch by instantiating a `Theme` data class with -# the required sections (which are also dataclass instances). -# -# Then call `_colorize.set_theme(your_theme)` to set it. -# -# Put your theme configuration in $PYTHONSTARTUP for the interactive shell, -# or sitecustomize.py in your virtual environment or Python installation for -# other uses. Your applications can call `_colorize.set_theme()` too. -# -# Note that thanks to the dataclasses providing default values for all fields, -# creating a new theme or theme section from scratch is possible without -# specifying all keys. -# -# For example, here's a theme that makes punctuation and operators less prominent: -# -# try: -# from _colorize import set_theme, default_theme, Syntax, ANSIColors -# except ImportError: -# pass -# else: -# theme_with_dim_operators = default_theme.copy_with( -# syntax=Syntax(op=ANSIColors.INTENSE_BLACK), -# ) -# set_theme(theme_with_dim_operators) -# del set_theme, default_theme, Syntax, ANSIColors, theme_with_dim_operators -# -# Guarding the import ensures that your .pythonstartup file will still work in -# Python 3.13 and older. Deleting the variables ensures they don't remain in your -# interactive shell's global scope. - -class ThemeSection(Mapping[str, str]): - """A mixin/base class for theme sections. - - It enables dictionary access to a section, as well as implements convenience - methods. - """ - - # The two types below are just that: types to inform the type checker that the - # mixin will work in context of those fields existing - __dataclass_fields__: ClassVar[dict[str, Field[str]]] - _name_to_value: Callable[[str], str] - - def __post_init__(self) -> None: - name_to_value = {} - for color_name in self.__dataclass_fields__: - name_to_value[color_name] = getattr(self, color_name) - super().__setattr__('_name_to_value', name_to_value.__getitem__) - - def copy_with(self, **kwargs: str) -> Self: - color_state: dict[str, str] = {} - for color_name in self.__dataclass_fields__: - color_state[color_name] = getattr(self, color_name) - color_state.update(kwargs) - return type(self)(**color_state) - - @classmethod - def no_colors(cls) -> Self: - color_state: dict[str, str] = {} - for color_name in cls.__dataclass_fields__: - color_state[color_name] = "" - return cls(**color_state) - - def __getitem__(self, key: str) -> str: - return self._name_to_value(key) - - def __len__(self) -> int: - return len(self.__dataclass_fields__) - - def __iter__(self) -> Iterator[str]: - return iter(self.__dataclass_fields__) - - -@dataclass(frozen=True) -class Argparse(ThemeSection): - usage: str = ANSIColors.BOLD_BLUE - prog: str = ANSIColors.BOLD_MAGENTA - prog_extra: str = ANSIColors.MAGENTA - heading: str = ANSIColors.BOLD_BLUE - summary_long_option: str = ANSIColors.CYAN - summary_short_option: str = ANSIColors.GREEN - summary_label: str = ANSIColors.YELLOW - summary_action: str = ANSIColors.GREEN - long_option: str = ANSIColors.BOLD_CYAN - short_option: str = ANSIColors.BOLD_GREEN - label: str = ANSIColors.BOLD_YELLOW - action: str = ANSIColors.BOLD_GREEN - reset: str = ANSIColors.RESET - - -@dataclass(frozen=True) -class Syntax(ThemeSection): - prompt: str = ANSIColors.BOLD_MAGENTA - keyword: str = ANSIColors.BOLD_BLUE - builtin: str = ANSIColors.CYAN - comment: str = ANSIColors.RED - string: str = ANSIColors.GREEN - number: str = ANSIColors.YELLOW - op: str = ANSIColors.RESET - definition: str = ANSIColors.BOLD - soft_keyword: str = ANSIColors.BOLD_BLUE - reset: str = ANSIColors.RESET - - -@dataclass(frozen=True) -class Traceback(ThemeSection): - type: str = ANSIColors.BOLD_MAGENTA - message: str = ANSIColors.MAGENTA - filename: str = ANSIColors.MAGENTA - line_no: str = ANSIColors.MAGENTA - frame: str = ANSIColors.MAGENTA - error_highlight: str = ANSIColors.BOLD_RED - error_range: str = ANSIColors.RED - reset: str = ANSIColors.RESET - - -@dataclass(frozen=True) -class Unittest(ThemeSection): - passed: str = ANSIColors.GREEN - warn: str = ANSIColors.YELLOW - fail: str = ANSIColors.RED - fail_info: str = ANSIColors.BOLD_RED - reset: str = ANSIColors.RESET - - -@dataclass(frozen=True) -class Theme: - """A suite of themes for all sections of Python. - - When adding a new one, remember to also modify `copy_with` and `no_colors` - below. - """ - argparse: Argparse = field(default_factory=Argparse) - syntax: Syntax = field(default_factory=Syntax) - traceback: Traceback = field(default_factory=Traceback) - unittest: Unittest = field(default_factory=Unittest) - - def copy_with( - self, - *, - argparse: Argparse | None = None, - syntax: Syntax | None = None, - traceback: Traceback | None = None, - unittest: Unittest | None = None, - ) -> Self: - """Return a new Theme based on this instance with some sections replaced. - - Themes are immutable to protect against accidental modifications that - could lead to invalid terminal states. - """ - return type(self)( - argparse=argparse or self.argparse, - syntax=syntax or self.syntax, - traceback=traceback or self.traceback, - unittest=unittest or self.unittest, - ) - - @classmethod - def no_colors(cls) -> Self: - """Return a new Theme where colors in all sections are empty strings. - - This allows writing user code as if colors are always used. The color - fields will be ANSI color code strings when colorization is desired - and possible, and empty strings otherwise. - """ - return cls( - argparse=Argparse.no_colors(), - syntax=Syntax.no_colors(), - traceback=Traceback.no_colors(), - unittest=Unittest.no_colors(), - ) - - -def get_colors( - colorize: bool = False, *, file: IO[str] | IO[bytes] | None = None -) -> ANSIColors: - if colorize or can_colorize(file=file): - return ANSIColors() - else: - return NoColors - - -def decolor(text: str) -> str: - """Remove ANSI color codes from a string.""" - for code in ColorCodes: - text = text.replace(code, "") - return text - - -def can_colorize(*, file: IO[str] | IO[bytes] | None = None) -> bool: - if file is None: - file = sys.stdout - - if not sys.flags.ignore_environment: - if os.environ.get("PYTHON_COLORS") == "0": - return False - if os.environ.get("PYTHON_COLORS") == "1": - return True - if os.environ.get("NO_COLOR"): - return False - if not COLORIZE: - return False - if os.environ.get("FORCE_COLOR"): - return True - if os.environ.get("TERM") == "dumb": - return False - - if not hasattr(file, "fileno"): - return False - - if sys.platform == "win32": - try: - import nt - - if not nt._supports_virtual_terminal(): - return False - except (ImportError, AttributeError): - return False - - try: - return os.isatty(file.fileno()) - except io.UnsupportedOperation: - return hasattr(file, "isatty") and file.isatty() - - -default_theme = Theme() -theme_no_color = default_theme.no_colors() - - -def get_theme( - *, - tty_file: IO[str] | IO[bytes] | None = None, - force_color: bool = False, - force_no_color: bool = False, -) -> Theme: - """Returns the currently set theme, potentially in a zero-color variant. - - In cases where colorizing is not possible (see `can_colorize`), the returned - theme contains all empty strings in all color definitions. - See `Theme.no_colors()` for more information. - - It is recommended not to cache the result of this function for extended - periods of time because the user might influence theme selection by - the interactive shell, a debugger, or application-specific code. The - environment (including environment variable state and console configuration - on Windows) can also change in the course of the application life cycle. - """ - if force_color or (not force_no_color and can_colorize(file=tty_file)): - return _theme - return theme_no_color - - -def set_theme(t: Theme) -> None: - global _theme - - if not isinstance(t, Theme): - raise ValueError(f"Expected Theme object, found {t}") - - _theme = t - - -set_theme(default_theme) From baab3326dad134568b8514fe9e0ecde09961d757 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Thu, 31 Jul 2025 21:15:57 +0200 Subject: [PATCH 27/29] Remove Misc/mypy/_token.py and Misc/mypy/_pyrelp - should be a symlink --- Misc/mypy/_pyrepl | 1 - Misc/mypy/token.py | 144 --------------------------------------------- 2 files changed, 145 deletions(-) delete mode 120000 Misc/mypy/_pyrepl delete mode 100644 Misc/mypy/token.py diff --git a/Misc/mypy/_pyrepl b/Misc/mypy/_pyrepl deleted file mode 120000 index bd7b69909663b6..00000000000000 --- a/Misc/mypy/_pyrepl +++ /dev/null @@ -1 +0,0 @@ -../../Lib/_pyrepl \ No newline at end of file diff --git a/Misc/mypy/token.py b/Misc/mypy/token.py deleted file mode 100644 index f61723cc09da02..00000000000000 --- a/Misc/mypy/token.py +++ /dev/null @@ -1,144 +0,0 @@ -"""Token constants.""" -# Auto-generated by Tools/build/generate_token.py - -__all__ = ['tok_name', 'ISTERMINAL', 'ISNONTERMINAL', 'ISEOF', - 'EXACT_TOKEN_TYPES'] - -ENDMARKER = 0 -NAME = 1 -NUMBER = 2 -STRING = 3 -NEWLINE = 4 -INDENT = 5 -DEDENT = 6 -LPAR = 7 -RPAR = 8 -LSQB = 9 -RSQB = 10 -COLON = 11 -COMMA = 12 -SEMI = 13 -PLUS = 14 -MINUS = 15 -STAR = 16 -SLASH = 17 -VBAR = 18 -AMPER = 19 -LESS = 20 -GREATER = 21 -EQUAL = 22 -DOT = 23 -PERCENT = 24 -LBRACE = 25 -RBRACE = 26 -EQEQUAL = 27 -NOTEQUAL = 28 -LESSEQUAL = 29 -GREATEREQUAL = 30 -TILDE = 31 -CIRCUMFLEX = 32 -LEFTSHIFT = 33 -RIGHTSHIFT = 34 -DOUBLESTAR = 35 -PLUSEQUAL = 36 -MINEQUAL = 37 -STAREQUAL = 38 -SLASHEQUAL = 39 -PERCENTEQUAL = 40 -AMPEREQUAL = 41 -VBAREQUAL = 42 -CIRCUMFLEXEQUAL = 43 -LEFTSHIFTEQUAL = 44 -RIGHTSHIFTEQUAL = 45 -DOUBLESTAREQUAL = 46 -DOUBLESLASH = 47 -DOUBLESLASHEQUAL = 48 -AT = 49 -ATEQUAL = 50 -RARROW = 51 -ELLIPSIS = 52 -COLONEQUAL = 53 -EXCLAMATION = 54 -OP = 55 -TYPE_IGNORE = 56 -TYPE_COMMENT = 57 -SOFT_KEYWORD = 58 -FSTRING_START = 59 -FSTRING_MIDDLE = 60 -FSTRING_END = 61 -TSTRING_START = 62 -TSTRING_MIDDLE = 63 -TSTRING_END = 64 -COMMENT = 65 -NL = 66 -# These aren't used by the C tokenizer but are needed for tokenize.py -ERRORTOKEN = 67 -ENCODING = 68 -N_TOKENS = 69 -# Special definitions for cooperation with parser -NT_OFFSET = 256 - -tok_name = {value: name - for name, value in globals().items() - if isinstance(value, int) and not name.startswith('_')} -__all__.extend(tok_name.values()) - -EXACT_TOKEN_TYPES = { - '!': EXCLAMATION, - '!=': NOTEQUAL, - '%': PERCENT, - '%=': PERCENTEQUAL, - '&': AMPER, - '&=': AMPEREQUAL, - '(': LPAR, - ')': RPAR, - '*': STAR, - '**': DOUBLESTAR, - '**=': DOUBLESTAREQUAL, - '*=': STAREQUAL, - '+': PLUS, - '+=': PLUSEQUAL, - ',': COMMA, - '-': MINUS, - '-=': MINEQUAL, - '->': RARROW, - '.': DOT, - '...': ELLIPSIS, - '/': SLASH, - '//': DOUBLESLASH, - '//=': DOUBLESLASHEQUAL, - '/=': SLASHEQUAL, - ':': COLON, - ':=': COLONEQUAL, - ';': SEMI, - '<': LESS, - '<<': LEFTSHIFT, - '<<=': LEFTSHIFTEQUAL, - '<=': LESSEQUAL, - '=': EQUAL, - '==': EQEQUAL, - '>': GREATER, - '>=': GREATEREQUAL, - '>>': RIGHTSHIFT, - '>>=': RIGHTSHIFTEQUAL, - '@': AT, - '@=': ATEQUAL, - '[': LSQB, - ']': RSQB, - '^': CIRCUMFLEX, - '^=': CIRCUMFLEXEQUAL, - '{': LBRACE, - '|': VBAR, - '|=': VBAREQUAL, - '}': RBRACE, - '~': TILDE, -} - -def ISTERMINAL(x: int) -> bool: - return x < NT_OFFSET - -def ISNONTERMINAL(x: int) -> bool: - return x >= NT_OFFSET - -def ISEOF(x: int) -> bool: - return x == ENDMARKER From 244869eb35b7be2aa85179b91c9f8ae68da40a41 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Thu, 31 Jul 2025 21:34:07 +0200 Subject: [PATCH 28/29] Ignore the symlinked files --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 7aa6272cf8e382..392b6ec93cc173 100644 --- a/.gitignore +++ b/.gitignore @@ -179,3 +179,8 @@ CLAUDE.local.md #### main branch only stuff below this line, things to backport go above. #### # main branch only: ABI files are not checked/maintained. Doc/data/python*.abi + +# Mypy symlinks (generated by Misc/mypy/make_symlinks.py) +Misc/mypy/_colorize.py +Misc/mypy/_pyrepl +Misc/mypy/token.py \ No newline at end of file From 8b699d84682e29e7783244a8fb6f2863dff00776 Mon Sep 17 00:00:00 2001 From: Rani Pinchuk Date: Thu, 31 Jul 2025 21:34:44 +0200 Subject: [PATCH 29/29] Fix warning for asymc function --- Lib/test/test_asyncio/test_unix_events.py | 46 +++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 452baa5b3c0884..a69a5e32b1b2bd 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1182,30 +1182,30 @@ async def runner(): @support.requires_fork() class TestFork(unittest.IsolatedAsyncioTestCase): - @warnings_helper.ignore_fork_in_thread_deprecation_warnings() async def test_fork_not_share_event_loop(self): - # The forked process should not share the event loop with the parent - loop = asyncio.get_running_loop() - r, w = os.pipe() - self.addCleanup(os.close, r) - self.addCleanup(os.close, w) - pid = os.fork() - if pid == 0: - # child - try: - loop = asyncio.get_event_loop() - os.write(w, b'LOOP:' + str(id(loop)).encode()) - except RuntimeError: - os.write(w, b'NO LOOP') - except BaseException as e: - os.write(w, b'ERROR:' + ascii(e).encode()) - finally: - os._exit(0) - else: - # parent - result = os.read(r, 100) - self.assertEqual(result, b'NO LOOP') - wait_process(pid, exitcode=0) + with warnings_helper.ignore_fork_in_thread_deprecation_warnings(): + # The forked process should not share the event loop with the parent + loop = asyncio.get_running_loop() + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + pid = os.fork() + if pid == 0: + # child + try: + loop = asyncio.get_event_loop() + os.write(w, b'LOOP:' + str(id(loop)).encode()) + except RuntimeError: + os.write(w, b'NO LOOP') + except BaseException as e: + os.write(w, b'ERROR:' + ascii(e).encode()) + finally: + os._exit(0) + else: + # parent + result = os.read(r, 100) + self.assertEqual(result, b'NO LOOP') + wait_process(pid, exitcode=0) @warnings_helper.ignore_fork_in_thread_deprecation_warnings() @hashlib_helper.requires_hashdigest('md5')