From e6646d74569759c7d6fae31b967319f0d409b3a8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 16:18:30 +0100 Subject: [PATCH 01/27] gh-161430: Omit tests expected to be skipped in regrtest --- Lib/test/libregrtest/results.py | 20 ++- Lib/test/libregrtest/skipped.py | 164 ++++++++++++++++++ ...-11-05-16-20-23.gh-issue-161430.M7b8N6.rst | 2 + 3 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 Lib/test/libregrtest/skipped.py create mode 100644 Misc/NEWS.d/next/Tests/2026-11-05-16-20-23.gh-issue-161430.M7b8N6.rst diff --git a/Lib/test/libregrtest/results.py b/Lib/test/libregrtest/results.py index 3475f645729182..014ffab1c45fd4 100644 --- a/Lib/test/libregrtest/results.py +++ b/Lib/test/libregrtest/results.py @@ -5,6 +5,7 @@ from .runtests import RunTests from .result import State, TestResult, TestStats, Location +from .skipped import expected_to_be_skipped from .utils import ( StrPath, TestName, TestTuple, TestList, FilterDict, printlist, count, format_duration) @@ -204,6 +205,16 @@ def write_junit(self, filename: StrPath) -> None: for s in ET.tostringlist(root): f.write(s) + def split_expected_skip(self, tests): + skipped = [] + expected = [] + for name in tests: + if expected_to_be_skipped(name): + expected.append(name) + else: + skipped.append(name) + return (skipped, expected) + def display_result(self, tests: TestTuple, quiet: bool, print_slowest: bool) -> None: ansi = get_colors() green = ansi.GREEN @@ -221,13 +232,20 @@ def display_result(self, tests: TestTuple, quiet: bool, print_slowest: bool) -> all_tests = [] omitted = set(tests) - self.get_executed() + # Filter tests expected to be skipped + skipped, expected_skip = self.split_expected_skip(self.skipped) + if expected_skip: + print() + count_text = count(len(expected_skip), "test") + print(f"{count_text} expected to be skipped (not listed)") + # less important all_tests.append( (sorted(omitted), "test", f"{yellow}{{}} omitted:{reset}") ) if not quiet: all_tests.append( - (self.skipped, "test", f"{yellow}{{}} skipped:{reset}") + (skipped, "test", f"{yellow}{{}} skipped:{reset}") ) all_tests.append( ( diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py new file mode 100644 index 00000000000000..3aef0ccfb92146 --- /dev/null +++ b/Lib/test/libregrtest/skipped.py @@ -0,0 +1,164 @@ +import importlib +import os +import sys +from test import support + + +# List of tests expected to be skipped +EXPECTED_SKIP = [] +if support.MS_WINDOWS: + EXPECTED_SKIP.extend(( + 'test_asyncio.test_unix_events', + 'test_gdb', + 'test_threadsignals', + )) +else: + EXPECTED_SKIP.extend(( + 'test_asyncio.test_windows_events', + 'test_asyncio.test_windows_utils', + 'test_msvcrt', + 'test_os.test_windows', + 'test_winapi', + 'test_winconsoleio', + 'test_winreg', + 'test_winsound', + 'test_wmi', + )) +if not hasattr(os, 'startfile'): + EXPECTED_SKIP.append('test_startfile') +if not hasattr(os, "openpty"): + EXPECTED_SKIP.append('test_openpty') +if not hasattr(os, "wait3"): + EXPECTED_SKIP.append('test_wait3') +if not hasattr(os, "wait4"): + EXPECTED_SKIP.append('test_wait4') +if not support.is_android: + EXPECTED_SKIP.append('test_android') +if not support.is_apple: + EXPECTED_SKIP.append('test_apple') +if not support.Py_GIL_DISABLED: + EXPECTED_SKIP.append('test_free_threading') +if sys.platform in ("win32", 'darwin'): + EXPECTED_SKIP.append('test_multiprocessing_fork') +if sys.platform in ("win32", "cygwin"): + EXPECTED_SKIP.append('test_multiprocessing_forkserver') +if not support.has_socket_support: + EXPECTED_SKIP.extend(( + 'test_asyncio', + 'test_docxmlrpc', + 'test_ftplib', + 'test_httplib', + 'test_httpservers', + 'test_imaplib', + 'test_poplib', + 'test_socket', + 'test_urllib2', + )) +if not support.has_subprocess_support: + EXPECTED_SKIP.extend(( + 'test_argparse', + 'test_cext', + 'test_clinic', + 'test_cmd_line', + 'test_embed', + 'test_faulthandler', + 'test_file_eintr', + 'test_generated_cases', + 'test_getopt', + 'test_optparse', + 'test_perf_profiler', + )) +if support.is_emscripten: + EXPECTED_SKIP.extend(( + 'test_mmap', + )) + + +# Modules needed by a test. +# Used to check if a test is expected to be skipped. +NEED_MODULES = { + 'test__interpchannels': '_interpchannels', + 'test_crossinterp': '_interpreters', + 'test_curses': ('_curses', 'curses', 'curses.ascii', 'curses.textpad'), + 'test_dbm_gnu': 'dbm.gnu', + 'test_dbm_ndbm': 'dbm.ndbm', + 'test_fcntl': 'fcntl', + 'test_grp': 'grp', + 'test_ioctl': ('fcntl', 'termios'), + 'test_lzma': '_lzma', + 'test_pty': 'termios', + 'test_pwd': 'pwd', + 'test_readline': 'readline', + 'test_resource': 'resource', + 'test_syslog': 'syslog', + 'test_termios': 'termios', + 'test_tty': ('termios', 'tty'), + 'test_xxtestfuzz': '_xxtestfuzz', +} +for name in ( + 'test_multiprocessing_fork', + 'test_multiprocessing_forkserver', + 'test_multiprocessing_main_handling', + 'test_multiprocessing_spawn', +): + NEED_MODULES[name] = '_multiprocessing' +for name in ( + 'test_idle', + 'test_tcl', + 'test_tkinter', + 'test_ttk', + 'test_ttk_textonly', + 'test_turtle', +): + NEED_MODULES[name] = '_tkinter' +for name in ( + 'test_smtpnet', + 'test_ssl', +): + NEED_MODULES[name] = '_ssl' + + + +def miss_modules(modules): + if isinstance(modules, str): + modules = (modules,) + try: + for module in modules: + importlib.import_module(module) + except ImportError: + return False + return True + + +def expected_to_be_skipped(test_name): + test_name = test_name.removeprefix('test.') + if test_name in EXPECTED_SKIP: + return True + + package = test_name.split('.')[0] + if package in EXPECTED_SKIP: + return True + + if test_name in ('test_poll', 'test_epoll', + 'test_kqueue', 'test_devpoll'): + import select + name = test_name.removeprefix('test_') + return not hasattr(select, name) + + if test_name in NEED_MODULES: + if miss_modules(NEED_MODULES[test_name]): + return True + if package in NEED_MODULES: + if miss_modules(NEED_MODULES[package]): + return True + + if test_name == 'test_fork1': + return not support.has_fork_support + if test_name == 'test_dtrace': + import sysconfig + return not sysconfig.get_config_var('WITH_DTRACE') + if package == 'test_concurrent_futures' or test_name == 'test_queue': + from test.support import threading_helper + return not threading_helper.can_start_thread + + return False diff --git a/Misc/NEWS.d/next/Tests/2026-11-05-16-20-23.gh-issue-161430.M7b8N6.rst b/Misc/NEWS.d/next/Tests/2026-11-05-16-20-23.gh-issue-161430.M7b8N6.rst new file mode 100644 index 00000000000000..b53d2f01d5ce14 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2026-11-05-16-20-23.gh-issue-161430.M7b8N6.rst @@ -0,0 +1,2 @@ +No longer list tests expected to be skipped in the final report. Patch by +Victor Stinner. From 4787c7f6599ca73c907d4e75f1a216b7a7d43fbd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 17:42:10 +0100 Subject: [PATCH 02/27] Fix NEED_MODULES logic --- Lib/test/libregrtest/skipped.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 3aef0ccfb92146..d2363fa14e13ec 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -126,8 +126,8 @@ def miss_modules(modules): for module in modules: importlib.import_module(module) except ImportError: - return False - return True + return True + return False def expected_to_be_skipped(test_name): @@ -148,7 +148,7 @@ def expected_to_be_skipped(test_name): if test_name in NEED_MODULES: if miss_modules(NEED_MODULES[test_name]): return True - if package in NEED_MODULES: + elif package in NEED_MODULES: if miss_modules(NEED_MODULES[package]): return True From 6f6bd83f5464c2f7ff843cad9c3365fdbcdcbbce Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 17:52:37 +0100 Subject: [PATCH 03/27] Complete ruleset --- Lib/test/libregrtest/skipped.py | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index d2363fa14e13ec..e13b7fb066f46d 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -1,3 +1,7 @@ +""" +Ruleset to check if a test is expected to be skipped. +""" + import importlib import os import sys @@ -51,8 +55,14 @@ 'test_httpservers', 'test_imaplib', 'test_poplib', + 'test_select', + 'test_smtplib', 'test_socket', 'test_urllib2', + 'test_urllib2_localnet', + 'test_wsgiref', + 'test_xml_dom_xmlbuilder', + 'test_xmlrpc', )) if not support.has_subprocess_support: EXPECTED_SKIP.extend(( @@ -67,11 +77,21 @@ 'test_getopt', 'test_optparse', 'test_perf_profiler', + 'test_regrtest', + 'test_repl', + 'test_samply_profiler', + 'test_subprocess', + 'test_tools', )) if support.is_emscripten: EXPECTED_SKIP.extend(( 'test_mmap', + 'test_selectors', )) +if support.is_android or support.is_apple_mobile or support.is_wasm32: + EXPECTED_SKIP.append('test_venv') +if not sys.is_remote_debug_enabled(): + EXPECTED_SKIP.append('test_remote_pdb') # Modules needed by a test. @@ -94,6 +114,7 @@ 'test_termios': 'termios', 'test_tty': ('termios', 'tty'), 'test_xxtestfuzz': '_xxtestfuzz', + 'test_zstd': '_zstd', } for name in ( 'test_multiprocessing_fork', @@ -118,6 +139,16 @@ NEED_MODULES[name] = '_ssl' +NEED_WORKING_THREADING = ( + 'test_concurrent_futures', + 'test_queue', + 'test_thread', + 'test_threadedtempfile', + 'test_threading', + 'test_threading_local', + 'test_webbrowser', +) + def miss_modules(modules): if isinstance(modules, str): @@ -157,7 +188,8 @@ def expected_to_be_skipped(test_name): if test_name == 'test_dtrace': import sysconfig return not sysconfig.get_config_var('WITH_DTRACE') - if package == 'test_concurrent_futures' or test_name == 'test_queue': + if (test_name in NEED_WORKING_THREADING + or package in NEED_WORKING_THREADING): from test.support import threading_helper return not threading_helper.can_start_thread From 2d93e096fe5f29f46af9bc8ec0e839d456d10429 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 18:29:51 +0100 Subject: [PATCH 04/27] Detect WASI using _PYTHON_HOST_PLATFORM env var --- Lib/test/libregrtest/skipped.py | 70 ++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index e13b7fb066f46d..3eea7f5402e771 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -8,16 +8,25 @@ from test import support +# On a WASI CI, the main regrtest process is run on the build Python and test +# worker processes are run on the host Python. Detect WASI using +# _PYTHON_HOST_PLATFORM environment variable. Below, IS_WASI should be checked +# explicitly since test.support constants (such as support.has_socket_support) +# are set by the build Python which is different. +HOST_PLATFORM = os.environ.get('_PYTHON_HOST_PLATFORM', '') +IS_WASI = support.is_wasi or HOST_PLATFORM.startswith('wasi') + + # List of tests expected to be skipped -EXPECTED_SKIP = [] +EXPECTED_SKIP = set() if support.MS_WINDOWS: - EXPECTED_SKIP.extend(( + EXPECTED_SKIP |= { 'test_asyncio.test_unix_events', 'test_gdb', 'test_threadsignals', - )) + } else: - EXPECTED_SKIP.extend(( + EXPECTED_SKIP |= { 'test_asyncio.test_windows_events', 'test_asyncio.test_windows_utils', 'test_msvcrt', @@ -27,27 +36,27 @@ 'test_winreg', 'test_winsound', 'test_wmi', - )) + } if not hasattr(os, 'startfile'): - EXPECTED_SKIP.append('test_startfile') + EXPECTED_SKIP.add('test_startfile') if not hasattr(os, "openpty"): - EXPECTED_SKIP.append('test_openpty') + EXPECTED_SKIP.add('test_openpty') if not hasattr(os, "wait3"): - EXPECTED_SKIP.append('test_wait3') + EXPECTED_SKIP.add('test_wait3') if not hasattr(os, "wait4"): - EXPECTED_SKIP.append('test_wait4') + EXPECTED_SKIP.add('test_wait4') if not support.is_android: - EXPECTED_SKIP.append('test_android') + EXPECTED_SKIP.add('test_android') if not support.is_apple: - EXPECTED_SKIP.append('test_apple') + EXPECTED_SKIP.add('test_apple') if not support.Py_GIL_DISABLED: - EXPECTED_SKIP.append('test_free_threading') + EXPECTED_SKIP.add('test_free_threading') if sys.platform in ("win32", 'darwin'): - EXPECTED_SKIP.append('test_multiprocessing_fork') + EXPECTED_SKIP.add('test_multiprocessing_fork') if sys.platform in ("win32", "cygwin"): - EXPECTED_SKIP.append('test_multiprocessing_forkserver') -if not support.has_socket_support: - EXPECTED_SKIP.extend(( + EXPECTED_SKIP.add('test_multiprocessing_forkserver') +if not support.has_socket_support or IS_WASI: + EXPECTED_SKIP |= { 'test_asyncio', 'test_docxmlrpc', 'test_ftplib', @@ -63,9 +72,9 @@ 'test_wsgiref', 'test_xml_dom_xmlbuilder', 'test_xmlrpc', - )) -if not support.has_subprocess_support: - EXPECTED_SKIP.extend(( + } +if not support.has_subprocess_support or IS_WASI: + EXPECTED_SKIP |= { 'test_argparse', 'test_cext', 'test_clinic', @@ -82,20 +91,31 @@ 'test_samply_profiler', 'test_subprocess', 'test_tools', - )) + } if support.is_emscripten: - EXPECTED_SKIP.extend(( + EXPECTED_SKIP |= { 'test_mmap', 'test_selectors', - )) + } if support.is_android or support.is_apple_mobile or support.is_wasm32: - EXPECTED_SKIP.append('test_venv') + EXPECTED_SKIP.add('test_venv') if not sys.is_remote_debug_enabled(): - EXPECTED_SKIP.append('test_remote_pdb') + EXPECTED_SKIP.add('test_remote_pdb') +if not support.has_fork_support or IS_WASI: + EXPECTED_SKIP |= { + 'test_fork1', + 'test_multiprocessing_forkserver', + 'test_wait3', + 'test_wait4', + } +if IS_WASI: + EXPECTED_SKIP.add('test_multiprocessing_fork') # Modules needed by a test. # Used to check if a test is expected to be skipped. +# NEED_MODULES doesn't work on WASI, since the regrtest summary is run on the +# build Python which is different than the host (WASI) Python. NEED_MODULES = { 'test__interpchannels': '_interpchannels', 'test_crossinterp': '_interpreters', @@ -190,6 +210,8 @@ def expected_to_be_skipped(test_name): return not sysconfig.get_config_var('WITH_DTRACE') if (test_name in NEED_WORKING_THREADING or package in NEED_WORKING_THREADING): + if IS_WASI: + return True from test.support import threading_helper return not threading_helper.can_start_thread From 28431f5db078daa4d29793057b7b5a31d0de94c6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 19:03:49 +0100 Subject: [PATCH 05/27] Ignore more tests on WASI --- Lib/test/libregrtest/skipped.py | 102 ++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 26 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 3eea7f5402e771..bc0523d4f5ee4e 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -17,6 +17,24 @@ IS_WASI = support.is_wasi or HOST_PLATFORM.startswith('wasi') +NEED_MULTIPROCESSING = { + 'test_multiprocessing_fork', + 'test_multiprocessing_forkserver', + 'test_multiprocessing_main_handling', + 'test_multiprocessing_spawn', +} +SELECT_TESTS = { + 'test_devpoll', + 'test_epoll', + 'test_kqueue', + 'test_poll', +} +NEED_SSL = { + 'test_smtpnet', + 'test_ssl', +} + + # List of tests expected to be skipped EXPECTED_SKIP = set() if support.MS_WINDOWS: @@ -57,25 +75,32 @@ EXPECTED_SKIP.add('test_multiprocessing_forkserver') if not support.has_socket_support or IS_WASI: EXPECTED_SKIP |= { + 'test_asyncgen', 'test_asyncio', 'test_docxmlrpc', 'test_ftplib', 'test_httplib', 'test_httpservers', 'test_imaplib', + 'test_mailbox', 'test_poplib', 'test_select', + 'test_selectors', 'test_smtplib', 'test_socket', + 'test_urllib', 'test_urllib2', 'test_urllib2_localnet', + 'test_urllib_response', 'test_wsgiref', 'test_xml_dom_xmlbuilder', 'test_xmlrpc', } + EXPECTED_SKIP |= SELECT_TESTS if not support.has_subprocess_support or IS_WASI: EXPECTED_SKIP |= { 'test_argparse', + 'test_c_stack_unwind', 'test_cext', 'test_clinic', 'test_cmd_line', @@ -97,7 +122,7 @@ 'test_mmap', 'test_selectors', } -if support.is_android or support.is_apple_mobile or support.is_wasm32: +if support.is_android or support.is_apple_mobile or support.is_wasm32 or IS_WASI: EXPECTED_SKIP.add('test_venv') if not sys.is_remote_debug_enabled(): EXPECTED_SKIP.add('test_remote_pdb') @@ -109,7 +134,40 @@ 'test_wait4', } if IS_WASI: - EXPECTED_SKIP.add('test_multiprocessing_fork') + EXPECTED_SKIP |= { + 'test__interpchannels', # need _interpchannels + 'test__interpreters', # need _interpreters + 'test_bz2', # need _bz2 + 'test_crossinterp', # need _interpreters + 'test_ctypes', # need _ctypes + 'test_curses', # need _curses + 'test_dbm_sqlite3', # need _sqlite3 + 'test_external_inspection', # need _remote_debugging + 'test_fcntl', # need fcntl + 'test_gc_stats', # need _remote_debugging + 'test_grp', # need grp + 'test_gzip', # need zlib + 'test_ioctl', # need fcntl + 'test_lzma', # need _lzma + 'test_mmap', # need mmap + 'test_openpty', # need os.openpty() + 'test_perfmaps', # need perf trampoline profiling + 'test_pty', # need termios + 'test_pwd', # need pwd + 'test_pyrepl', # need termios + 'test_remote_pdb', # need remote debugging + 'test_resource', # need resource + 'test_sqlite3', # need _sqlite3 + 'test_stable_abi_ctypes', # need _ctypes + 'test_syslog', # need syslog + 'test_termios', # need termios + 'test_tty', # need termios + 'test_xxlimited', # need xxlimited + 'test_zlib', # need zlib + 'test_zstd', # need _zstd + } + EXPECTED_SKIP |= NEED_MULTIPROCESSING + EXPECTED_SKIP |= NEED_SSL # Modules needed by a test. @@ -136,12 +194,7 @@ 'test_xxtestfuzz': '_xxtestfuzz', 'test_zstd': '_zstd', } -for name in ( - 'test_multiprocessing_fork', - 'test_multiprocessing_forkserver', - 'test_multiprocessing_main_handling', - 'test_multiprocessing_spawn', -): +for name in NEED_MULTIPROCESSING: NEED_MODULES[name] = '_multiprocessing' for name in ( 'test_idle', @@ -152,14 +205,11 @@ 'test_turtle', ): NEED_MODULES[name] = '_tkinter' -for name in ( - 'test_smtpnet', - 'test_ssl', -): +for name in NEED_SSL: NEED_MODULES[name] = '_ssl' -NEED_WORKING_THREADING = ( +NEED_WORKING_THREADING = { 'test_concurrent_futures', 'test_queue', 'test_thread', @@ -167,7 +217,7 @@ 'test_threading', 'test_threading_local', 'test_webbrowser', -) +} def miss_modules(modules): @@ -182,20 +232,15 @@ def miss_modules(modules): def expected_to_be_skipped(test_name): + # Test EXPECTED_SKIP test_name = test_name.removeprefix('test.') if test_name in EXPECTED_SKIP: return True - package = test_name.split('.')[0] if package in EXPECTED_SKIP: return True - if test_name in ('test_poll', 'test_epoll', - 'test_kqueue', 'test_devpoll'): - import select - name = test_name.removeprefix('test_') - return not hasattr(select, name) - + # Test NEED_MODULES if test_name in NEED_MODULES: if miss_modules(NEED_MODULES[test_name]): return True @@ -203,11 +248,7 @@ def expected_to_be_skipped(test_name): if miss_modules(NEED_MODULES[package]): return True - if test_name == 'test_fork1': - return not support.has_fork_support - if test_name == 'test_dtrace': - import sysconfig - return not sysconfig.get_config_var('WITH_DTRACE') + # Custom ruleset if (test_name in NEED_WORKING_THREADING or package in NEED_WORKING_THREADING): if IS_WASI: @@ -215,4 +256,13 @@ def expected_to_be_skipped(test_name): from test.support import threading_helper return not threading_helper.can_start_thread + if test_name in SELECT_TESTS: + import select + name = test_name.removeprefix('test_') + return not hasattr(select, name) + + if test_name == 'test_dtrace': + import sysconfig + return not sysconfig.get_config_var('WITH_DTRACE') + return False From 375693828bf5c933c5b8511c3181ad12f3878ec3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 19:51:15 +0100 Subject: [PATCH 06/27] Filter more tests --- Lib/test/libregrtest/skipped.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index bc0523d4f5ee4e..241823138e29aa 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -33,6 +33,14 @@ 'test_smtpnet', 'test_ssl', } +NEED_TESTMULTIPHASE = { + # Lib/test/test_importlib/util.py requires _testmultiphase + 'test_compileall', + 'test_import', + 'test_pkgutil', + 'test_pyclbr', + 'test_runpy', +} # List of tests expected to be skipped @@ -55,6 +63,12 @@ 'test_winsound', 'test_wmi', } + +if sys.platform in ("win32", 'darwin'): + EXPECTED_SKIP.add('test_multiprocessing_fork') +if sys.platform in ("win32", "cygwin"): + EXPECTED_SKIP.add('test_multiprocessing_forkserver') + if not hasattr(os, 'startfile'): EXPECTED_SKIP.add('test_startfile') if not hasattr(os, "openpty"): @@ -63,17 +77,16 @@ EXPECTED_SKIP.add('test_wait3') if not hasattr(os, "wait4"): EXPECTED_SKIP.add('test_wait4') + if not support.is_android: EXPECTED_SKIP.add('test_android') if not support.is_apple: EXPECTED_SKIP.add('test_apple') if not support.Py_GIL_DISABLED: EXPECTED_SKIP.add('test_free_threading') -if sys.platform in ("win32", 'darwin'): - EXPECTED_SKIP.add('test_multiprocessing_fork') -if sys.platform in ("win32", "cygwin"): - EXPECTED_SKIP.add('test_multiprocessing_forkserver') + if not support.has_socket_support or IS_WASI: + # need socket support EXPECTED_SKIP |= { 'test_asyncgen', 'test_asyncio', @@ -98,6 +111,7 @@ } EXPECTED_SKIP |= SELECT_TESTS if not support.has_subprocess_support or IS_WASI: + # need subprocess support EXPECTED_SKIP |= { 'test_argparse', 'test_c_stack_unwind', @@ -107,6 +121,7 @@ 'test_embed', 'test_faulthandler', 'test_file_eintr', + 'test_gdb', 'test_generated_cases', 'test_getopt', 'test_optparse', @@ -151,7 +166,6 @@ 'test_lzma', # need _lzma 'test_mmap', # need mmap 'test_openpty', # need os.openpty() - 'test_perfmaps', # need perf trampoline profiling 'test_pty', # need termios 'test_pwd', # need pwd 'test_pyrepl', # need termios @@ -168,6 +182,7 @@ } EXPECTED_SKIP |= NEED_MULTIPROCESSING EXPECTED_SKIP |= NEED_SSL + EXPECTED_SKIP |= NEED_TESTMULTIPHASE # Modules needed by a test. @@ -265,4 +280,10 @@ def expected_to_be_skipped(test_name): import sysconfig return not sysconfig.get_config_var('WITH_DTRACE') + if test_name in ('test_perf_profiler', 'test_perfmaps', 'test_samply_profiler'): + # need perf trampoline profiling + import sysconfig + perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") + return (not perf_trampoline or int(perf_trampoline) != 1) + return False From 8aa0d9ee5e6e4260de7d588d480404dbd13ea6a8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 20:00:30 +0100 Subject: [PATCH 07/27] Add support.supports_perf_trampoline_profiling() function --- Lib/test/libregrtest/skipped.py | 4 +--- Lib/test/support/__init__.py | 7 +++++++ Lib/test/test_perf_profiler.py | 9 +-------- Lib/test/test_perfmaps.py | 8 +------- Lib/test/test_samply_profiler.py | 9 +-------- 5 files changed, 11 insertions(+), 26 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 241823138e29aa..e9d05b8d146845 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -282,8 +282,6 @@ def expected_to_be_skipped(test_name): if test_name in ('test_perf_profiler', 'test_perfmaps', 'test_samply_profiler'): # need perf trampoline profiling - import sysconfig - perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") - return (not perf_trampoline or int(perf_trampoline) != 1) + return not support.supports_perf_trampoline_profiling() return False diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index c14c50dae5bedc..df3ae0890c0f12 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3614,3 +3614,10 @@ def inject_memory_error_cm(start=0, stop=0): yield finally: _testcapi.remove_mem_hooks() + + +def supports_perf_trampoline_profiling(): + perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") + if not perf_trampoline: + return False + return int(perf_trampoline) == 1 diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py index 0ebc0792cfc822..8a2c4889d9471c 100644 --- a/Lib/test/test_perf_profiler.py +++ b/Lib/test/test_perf_profiler.py @@ -23,14 +23,7 @@ raise unittest.SkipTest("test crash randomly on ASAN/MSAN build") -def supports_trampoline_profiling(): - perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") - if not perf_trampoline: - return False - return int(perf_trampoline) == 1 - - -if not supports_trampoline_profiling(): +if not support.supports_perf_trampoline_profiling(): raise unittest.SkipTest("perf trampoline profiling not supported") diff --git a/Lib/test/test_perfmaps.py b/Lib/test/test_perfmaps.py index ee4eb50033c470..4a3d9cb361a4ac 100644 --- a/Lib/test/test_perfmaps.py +++ b/Lib/test/test_perfmaps.py @@ -8,13 +8,7 @@ except ImportError: raise unittest.SkipTest("requires _testinternalcapi") -def supports_trampoline_profiling(): - perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") - if not perf_trampoline: - return False - return int(perf_trampoline) == 1 - -if not supports_trampoline_profiling(): +if not support.supports_perf_trampoline_profiling(): raise unittest.SkipTest("perf trampoline profiling not supported") class TestPerfMapWriting(unittest.TestCase): diff --git a/Lib/test/test_samply_profiler.py b/Lib/test/test_samply_profiler.py index b9ac6586f4f7f5..d3a38b68c0b8b2 100644 --- a/Lib/test/test_samply_profiler.py +++ b/Lib/test/test_samply_profiler.py @@ -20,14 +20,7 @@ raise unittest.SkipTest("test crash randomly on ASAN/MSAN build") -def supports_trampoline_profiling(): - perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") - if not perf_trampoline: - return False - return int(perf_trampoline) == 1 - - -if not supports_trampoline_profiling(): +if not support.supports_perf_trampoline_profiling(): raise unittest.SkipTest("perf trampoline profiling not supported") From 379f3031882e564c9a39353068f4bd36f59d0010 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 20:03:20 +0100 Subject: [PATCH 08/27] Filter test_gdb if gdb program is not found --- Lib/test/libregrtest/skipped.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index e9d05b8d146845..28c3bb1b7df02e 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -284,4 +284,8 @@ def expected_to_be_skipped(test_name): # need perf trampoline profiling return not support.supports_perf_trampoline_profiling() + if package == 'test_gdb': + import shutil + return not shutil.which('gdb') + return False From 20876b5a34c9467988d31186a68f5243f7135eb2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 20:08:25 +0100 Subject: [PATCH 09/27] Update for Emscripten --- Lib/test/libregrtest/skipped.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 28c3bb1b7df02e..6c04276c0ba166 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -138,7 +138,10 @@ 'test_selectors', } if support.is_android or support.is_apple_mobile or support.is_wasm32 or IS_WASI: - EXPECTED_SKIP.add('test_venv') + EXPECTED_SKIP |= { + 'test_pty', + 'test_venv', + } if not sys.is_remote_debug_enabled(): EXPECTED_SKIP.add('test_remote_pdb') if not support.has_fork_support or IS_WASI: @@ -166,7 +169,6 @@ 'test_lzma', # need _lzma 'test_mmap', # need mmap 'test_openpty', # need os.openpty() - 'test_pty', # need termios 'test_pwd', # need pwd 'test_pyrepl', # need termios 'test_remote_pdb', # need remote debugging @@ -191,6 +193,7 @@ # build Python which is different than the host (WASI) Python. NEED_MODULES = { 'test__interpchannels': '_interpchannels', + 'test__interpreters': '_interpreters', 'test_crossinterp': '_interpreters', 'test_curses': ('_curses', 'curses', 'curses.ascii', 'curses.textpad'), 'test_dbm_gnu': 'dbm.gnu', From cd46dbdf17c43bc93c69498dc39edfdb9639400a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 20:09:05 +0100 Subject: [PATCH 10/27] Run prek --all-files --- Lib/test/test_perfmaps.py | 1 - Lib/test/test_samply_profiler.py | 1 - 2 files changed, 2 deletions(-) diff --git a/Lib/test/test_perfmaps.py b/Lib/test/test_perfmaps.py index 4a3d9cb361a4ac..6b855380aa3abc 100644 --- a/Lib/test/test_perfmaps.py +++ b/Lib/test/test_perfmaps.py @@ -1,6 +1,5 @@ import os import sys -import sysconfig import unittest try: diff --git a/Lib/test/test_samply_profiler.py b/Lib/test/test_samply_profiler.py index d3a38b68c0b8b2..ae3f047b15194a 100644 --- a/Lib/test/test_samply_profiler.py +++ b/Lib/test/test_samply_profiler.py @@ -1,7 +1,6 @@ import unittest import subprocess import sys -import sysconfig import os import pathlib from test import support From fc3d09a52ceb73c0e2c3335df99ed034cdb83f7f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 20:12:40 +0100 Subject: [PATCH 11/27] Filter test_asdl_parser on iOS --- Lib/test/libregrtest/skipped.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 6c04276c0ba166..e20df0a63bf72c 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -291,4 +291,8 @@ def expected_to_be_skipped(test_name): import shutil return not shutil.which('gdb') + if test_name == 'test_asdl_parser': + # Test only relevant for from-source Python builds + return not sysconfig.is_python_build() + return False From 9367f53a60c371c198d0bdbf80270ac9efc0e96d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 20:52:56 +0100 Subject: [PATCH 12/27] Add missing imports --- Lib/test/libregrtest/skipped.py | 1 + Lib/test/test_perfmaps.py | 1 + 2 files changed, 2 insertions(+) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index e20df0a63bf72c..89f245ee4b4ff7 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -293,6 +293,7 @@ def expected_to_be_skipped(test_name): if test_name == 'test_asdl_parser': # Test only relevant for from-source Python builds + import sysconfig return not sysconfig.is_python_build() return False diff --git a/Lib/test/test_perfmaps.py b/Lib/test/test_perfmaps.py index 6b855380aa3abc..e6e5985233d1a8 100644 --- a/Lib/test/test_perfmaps.py +++ b/Lib/test/test_perfmaps.py @@ -1,6 +1,7 @@ import os import sys import unittest +from test import support try: from _testinternalcapi import perf_map_state_teardown, write_perf_map_entry From fe10387691d1a4dfdcc383f2cb94eb353212676a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 20:57:12 +0100 Subject: [PATCH 13/27] Skip test_interpreters on Free Threading --- Lib/test/libregrtest/skipped.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 89f245ee4b4ff7..3e1371b2d7bd4a 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -69,6 +69,11 @@ if sys.platform in ("win32", "cygwin"): EXPECTED_SKIP.add('test_multiprocessing_forkserver') +if support.Py_GIL_DISABLED: + EXPECTED_SKIP.add('test_interpreters') +else: + EXPECTED_SKIP.add('test_free_threading') + if not hasattr(os, 'startfile'): EXPECTED_SKIP.add('test_startfile') if not hasattr(os, "openpty"): @@ -82,8 +87,6 @@ EXPECTED_SKIP.add('test_android') if not support.is_apple: EXPECTED_SKIP.add('test_apple') -if not support.Py_GIL_DISABLED: - EXPECTED_SKIP.add('test_free_threading') if not support.has_socket_support or IS_WASI: # need socket support From ce8761a8b652c07380d1b9c43fa0330c6de29b2b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 21:00:08 +0100 Subject: [PATCH 14/27] Skip test_free_threading sub-tests on Windows --- Lib/test/libregrtest/skipped.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 3e1371b2d7bd4a..6513f97d33bf99 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -202,6 +202,12 @@ 'test_dbm_gnu': 'dbm.gnu', 'test_dbm_ndbm': 'dbm.ndbm', 'test_fcntl': 'fcntl', + 'test_free_threading.test_dbm_gnu': 'dbm.gnu', + 'test_free_threading.test_grp': 'grp', + 'test_free_threading.test_pwd': 'pwd', + 'test_free_threading.test_readline': 'readline', + 'test_free_threading.test_resource': 'resource', + 'test_free_threading.test_syslog': 'syslog', 'test_grp': 'grp', 'test_ioctl': ('fcntl', 'termios'), 'test_lzma': '_lzma', From 59eb2bac028fb77a1bafe502b9bd8fbb80232c0d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 22:43:23 +0100 Subject: [PATCH 15/27] Skip test_xxlimited if xxlimited is missing --- Lib/test/libregrtest/skipped.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 6513f97d33bf99..b620357bc1afea 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -218,6 +218,7 @@ 'test_syslog': 'syslog', 'test_termios': 'termios', 'test_tty': ('termios', 'tty'), + 'test_xxlimited': 'xxlimited', 'test_xxtestfuzz': '_xxtestfuzz', 'test_zstd': '_zstd', } From 2da05cdcbca83b0029d84f9ddd5cbc767a2a055e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 5 Nov 2026 23:04:24 +0100 Subject: [PATCH 16/27] Add comments --- Lib/test/libregrtest/skipped.py | 56 ++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index b620357bc1afea..492e899735e1bf 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -47,12 +47,16 @@ EXPECTED_SKIP = set() if support.MS_WINDOWS: EXPECTED_SKIP |= { + # UNIX only 'test_asyncio.test_unix_events', + # test_gdb doesn't work on Windows 'test_gdb', + # Can't test signal on Windows 'test_threadsignals', } else: EXPECTED_SKIP |= { + # Tests specific to Windows 'test_asyncio.test_windows_events', 'test_asyncio.test_windows_utils', 'test_msvcrt', @@ -89,7 +93,7 @@ EXPECTED_SKIP.add('test_apple') if not support.has_socket_support or IS_WASI: - # need socket support + # Need socket support EXPECTED_SKIP |= { 'test_asyncgen', 'test_asyncio', @@ -114,7 +118,7 @@ } EXPECTED_SKIP |= SELECT_TESTS if not support.has_subprocess_support or IS_WASI: - # need subprocess support + # Need subprocess support EXPECTED_SKIP |= { 'test_argparse', 'test_c_stack_unwind', @@ -137,14 +141,19 @@ } if support.is_emscripten: EXPECTED_SKIP |= { + # Incompatible with Emscripten's mmap emulation 'test_mmap', + # Cannot create socketpair on Emscripten/WASI 'test_selectors', } if support.is_android or support.is_apple_mobile or support.is_wasm32 or IS_WASI: EXPECTED_SKIP |= { + # pty is not available on these platforms 'test_pty', + # venv is not available on these platforms 'test_venv', } +# On FreeBSD, is_remote_debug_enabled() is always false if not sys.is_remote_debug_enabled(): EXPECTED_SKIP.add('test_remote_pdb') if not support.has_fork_support or IS_WASI: @@ -156,44 +165,52 @@ } if IS_WASI: EXPECTED_SKIP |= { + # configure disables multiple extension modules on WASI 'test__interpchannels', # need _interpchannels 'test__interpreters', # need _interpreters - 'test_bz2', # need _bz2 'test_crossinterp', # need _interpreters - 'test_ctypes', # need _ctypes 'test_curses', # need _curses - 'test_dbm_sqlite3', # need _sqlite3 'test_external_inspection', # need _remote_debugging 'test_fcntl', # need fcntl 'test_gc_stats', # need _remote_debugging 'test_grp', # need grp - 'test_gzip', # need zlib 'test_ioctl', # need fcntl - 'test_lzma', # need _lzma 'test_mmap', # need mmap - 'test_openpty', # need os.openpty() 'test_pwd', # need pwd 'test_pyrepl', # need termios - 'test_remote_pdb', # need remote debugging + 'test_remote_pdb', # need _remote_debugging 'test_resource', # need resource - 'test_sqlite3', # need _sqlite3 - 'test_stable_abi_ctypes', # need _ctypes 'test_syslog', # need syslog 'test_termios', # need termios 'test_tty', # need termios 'test_xxlimited', # need xxlimited + + # Missing functions on WASI + 'test_openpty', # need os.openpty() + + # Missing dependencies on WASI + 'test_bz2', # need _bz2 + 'test_ctypes', # need _ctypes + 'test_dbm_sqlite3', # need _sqlite3 + 'test_gzip', # need zlib + 'test_lzma', # need _lzma + 'test_sqlite3', # need _sqlite3 + 'test_stable_abi_ctypes', # need _ctypes 'test_zlib', # need zlib 'test_zstd', # need _zstd } + # configure disables _multiprocessing and _testmultiphase + # extension modules on WASI + EXPECTED_SKIP |= NEED_TESTMULTIPHASE EXPECTED_SKIP |= NEED_MULTIPROCESSING + # Missing OpenSSL dependency on WASI EXPECTED_SKIP |= NEED_SSL - EXPECTED_SKIP |= NEED_TESTMULTIPHASE # Modules needed by a test. # Used to check if a test is expected to be skipped. -# NEED_MODULES doesn't work on WASI, since the regrtest summary is run on the -# build Python which is different than the host (WASI) Python. +# NEED_MODULES doesn't work on WASI, since the main regrtest process is run +# on the build Python which is different than the host (WASI) Python. NEED_MODULES = { 'test__interpchannels': '_interpchannels', 'test__interpreters': '_interpreters', @@ -279,25 +296,34 @@ def expected_to_be_skipped(test_name): # Custom ruleset if (test_name in NEED_WORKING_THREADING or package in NEED_WORKING_THREADING): + # Detect whether Python can start new threads + # - wasm32-wasi does not have threading. + # - wasm32-emscripten can be compiled with or without pthread + # support (-s USE_PTHREADS / __EMSCRIPTEN_PTHREADS__). if IS_WASI: return True from test.support import threading_helper return not threading_helper.can_start_thread if test_name in SELECT_TESTS: + # For example, test_epoll needs select.epoll() import select name = test_name.removeprefix('test_') return not hasattr(select, name) if test_name == 'test_dtrace': + # Need ./configure --with-dtrace import sysconfig return not sysconfig.get_config_var('WITH_DTRACE') if test_name in ('test_perf_profiler', 'test_perfmaps', 'test_samply_profiler'): - # need perf trampoline profiling + # Need perf trampoline profiling: configure defines the + # PY_HAVE_PERF_TRAMPOLINE macro on Linux (x86-64 and AArch64) + # and on macOS. return not support.supports_perf_trampoline_profiling() if package == 'test_gdb': + # Need gdb program import shutil return not shutil.which('gdb') From e87dc93298c1c27d3c8013b6b22186c23c65477c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 00:05:14 +0100 Subject: [PATCH 17/27] Disable NEED_MODULES * Replace hasattr(os, name) check for sys.platform check. * List disabled extensions on Apple mobile and on Emscripten --- Lib/test/libregrtest/skipped.py | 239 +++++++++++++++++++------------- 1 file changed, 139 insertions(+), 100 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 492e899735e1bf..0dbb212d5f8f81 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -45,53 +45,14 @@ # List of tests expected to be skipped EXPECTED_SKIP = set() -if support.MS_WINDOWS: - EXPECTED_SKIP |= { - # UNIX only - 'test_asyncio.test_unix_events', - # test_gdb doesn't work on Windows - 'test_gdb', - # Can't test signal on Windows - 'test_threadsignals', - } -else: - EXPECTED_SKIP |= { - # Tests specific to Windows - 'test_asyncio.test_windows_events', - 'test_asyncio.test_windows_utils', - 'test_msvcrt', - 'test_os.test_windows', - 'test_winapi', - 'test_winconsoleio', - 'test_winreg', - 'test_winsound', - 'test_wmi', - } - -if sys.platform in ("win32", 'darwin'): - EXPECTED_SKIP.add('test_multiprocessing_fork') -if sys.platform in ("win32", "cygwin"): - EXPECTED_SKIP.add('test_multiprocessing_forkserver') if support.Py_GIL_DISABLED: + # Need GIL build EXPECTED_SKIP.add('test_interpreters') else: + # Need Free Threading build EXPECTED_SKIP.add('test_free_threading') -if not hasattr(os, 'startfile'): - EXPECTED_SKIP.add('test_startfile') -if not hasattr(os, "openpty"): - EXPECTED_SKIP.add('test_openpty') -if not hasattr(os, "wait3"): - EXPECTED_SKIP.add('test_wait3') -if not hasattr(os, "wait4"): - EXPECTED_SKIP.add('test_wait4') - -if not support.is_android: - EXPECTED_SKIP.add('test_android') -if not support.is_apple: - EXPECTED_SKIP.add('test_apple') - if not support.has_socket_support or IS_WASI: # Need socket support EXPECTED_SKIP |= { @@ -139,13 +100,96 @@ 'test_subprocess', 'test_tools', } +if not support.has_fork_support or IS_WASI: + # Need fork + EXPECTED_SKIP |= { + 'test_fork1', + 'test_multiprocessing_forkserver', + 'test_wait3', + 'test_wait4', + } + + +if support.MS_WINDOWS: + # Tests specific to non-Windows platforms + EXPECTED_SKIP |= { + 'test_asyncio.test_unix_events', # UNIX only + 'test_dbm_gnu', # Need dbm.gnu module + 'test_dbm_ndbm', # Need dbm.ndbm module + 'test_fcntl', # Need fcntl module + 'test_free_threading.test_dbm_gnu', # Need dbm.gnu module + 'test_free_threading.test_grp', # Need grp module + 'test_free_threading.test_pwd', # Need pwd module + 'test_free_threading.test_readline', # Need readline module + 'test_free_threading.test_resource', # Need resource module + 'test_free_threading.test_syslog', # Need syslog module + 'test_gdb', # test_gdb doesn't work on Windows + 'test_grp', # Need grp module + 'test_ioctl', # Need fcntl module + 'test_openpty', # Need os.openpty() + 'test_pty', # Need termios module + 'test_pwd', # Need pwd module + 'test_readline', # Need readline module + 'test_resource', # Need resource module + 'test_syslog', # Need syslog module + 'test_termios', # Need termios module + 'test_threadsignals', # Can't test signal on Windows + 'test_tty', # Need termios and tty modules + 'test_wait3', # Need os.wait3() + 'test_wait4', # Need os.wait4() + } +else: + EXPECTED_SKIP |= { + # Tests specific to Windows + 'test_asyncio.test_windows_events', + 'test_asyncio.test_windows_utils', + 'test_msvcrt', + 'test_os.test_windows', + 'test_startfile', # Need os.startfile() + 'test_winapi', + 'test_winconsoleio', + 'test_winreg', + 'test_winsound', + 'test_wmi', + } +if sys.platform in ("win32", 'darwin'): + EXPECTED_SKIP.add('test_multiprocessing_fork') +if sys.platform in ("win32", "cygwin"): + EXPECTED_SKIP.add('test_multiprocessing_forkserver') + +if not support.is_android: + EXPECTED_SKIP.add('test_android') +if not support.is_apple: + EXPECTED_SKIP.add('test_apple') + +if support.is_apple_mobile: + # configure disables multiple extension modules on Apple mobile + EXPECTED_SKIP |= { + 'test_curses', # need _curses + 'test_grp', # need grp + 'test_syslog', # need syslog + } + EXPECTED_SKIP |= NEED_MULTIPROCESSING + if support.is_emscripten: + # configure disables multiple extension modules on Emscripten + EXPECTED_SKIP |= { + 'test__interpchannels', # need _interpchannels + 'test__interpreters', # need _interpreters + 'test_crossinterp', # need _interpreters + 'test_curses', # need _curses + 'test_grp', # need grp + 'test_pwd', # need pwd + 'test_resource', # need resource + 'test_syslog', # need syslog + } EXPECTED_SKIP |= { # Incompatible with Emscripten's mmap emulation 'test_mmap', # Cannot create socketpair on Emscripten/WASI 'test_selectors', } + if support.is_android or support.is_apple_mobile or support.is_wasm32 or IS_WASI: EXPECTED_SKIP |= { # pty is not available on these platforms @@ -153,16 +197,11 @@ # venv is not available on these platforms 'test_venv', } + # On FreeBSD, is_remote_debug_enabled() is always false if not sys.is_remote_debug_enabled(): EXPECTED_SKIP.add('test_remote_pdb') -if not support.has_fork_support or IS_WASI: - EXPECTED_SKIP |= { - 'test_fork1', - 'test_multiprocessing_forkserver', - 'test_wait3', - 'test_wait4', - } + if IS_WASI: EXPECTED_SKIP |= { # configure disables multiple extension modules on WASI @@ -207,51 +246,51 @@ EXPECTED_SKIP |= NEED_SSL -# Modules needed by a test. -# Used to check if a test is expected to be skipped. -# NEED_MODULES doesn't work on WASI, since the main regrtest process is run -# on the build Python which is different than the host (WASI) Python. -NEED_MODULES = { - 'test__interpchannels': '_interpchannels', - 'test__interpreters': '_interpreters', - 'test_crossinterp': '_interpreters', - 'test_curses': ('_curses', 'curses', 'curses.ascii', 'curses.textpad'), - 'test_dbm_gnu': 'dbm.gnu', - 'test_dbm_ndbm': 'dbm.ndbm', - 'test_fcntl': 'fcntl', - 'test_free_threading.test_dbm_gnu': 'dbm.gnu', - 'test_free_threading.test_grp': 'grp', - 'test_free_threading.test_pwd': 'pwd', - 'test_free_threading.test_readline': 'readline', - 'test_free_threading.test_resource': 'resource', - 'test_free_threading.test_syslog': 'syslog', - 'test_grp': 'grp', - 'test_ioctl': ('fcntl', 'termios'), - 'test_lzma': '_lzma', - 'test_pty': 'termios', - 'test_pwd': 'pwd', - 'test_readline': 'readline', - 'test_resource': 'resource', - 'test_syslog': 'syslog', - 'test_termios': 'termios', - 'test_tty': ('termios', 'tty'), - 'test_xxlimited': 'xxlimited', - 'test_xxtestfuzz': '_xxtestfuzz', - 'test_zstd': '_zstd', -} -for name in NEED_MULTIPROCESSING: - NEED_MODULES[name] = '_multiprocessing' -for name in ( - 'test_idle', - 'test_tcl', - 'test_tkinter', - 'test_ttk', - 'test_ttk_textonly', - 'test_turtle', -): - NEED_MODULES[name] = '_tkinter' -for name in NEED_SSL: - NEED_MODULES[name] = '_ssl' +## # Modules needed by a test. +## # Used to check if a test is expected to be skipped. +## # NEED_MODULES doesn't work on WASI, since the main regrtest process is run +## # on the build Python which is different than the host (WASI) Python. +## NEED_MODULES = { +## 'test__interpchannels': '_interpchannels', +## 'test__interpreters': '_interpreters', +## 'test_crossinterp': '_interpreters', +## 'test_curses': ('_curses', 'curses', 'curses.ascii', 'curses.textpad'), +## 'test_dbm_gnu': 'dbm.gnu', +## 'test_dbm_ndbm': 'dbm.ndbm', +## 'test_fcntl': 'fcntl', +## 'test_free_threading.test_dbm_gnu': 'dbm.gnu', +## 'test_free_threading.test_grp': 'grp', +## 'test_free_threading.test_pwd': 'pwd', +## 'test_free_threading.test_readline': 'readline', +## 'test_free_threading.test_resource': 'resource', +## 'test_free_threading.test_syslog': 'syslog', +## 'test_grp': 'grp', +## 'test_ioctl': ('fcntl', 'termios'), +## 'test_lzma': '_lzma', +## 'test_pty': 'termios', +## 'test_pwd': 'pwd', +## 'test_readline': 'readline', +## 'test_resource': 'resource', +## 'test_syslog': 'syslog', +## 'test_termios': 'termios', +## 'test_tty': ('termios', 'tty'), +## 'test_xxlimited': 'xxlimited', +## 'test_xxtestfuzz': '_xxtestfuzz', +## 'test_zstd': '_zstd', +## } +## for name in NEED_MULTIPROCESSING: +## NEED_MODULES[name] = '_multiprocessing' +## for name in ( +## 'test_idle', +## 'test_tcl', +## 'test_tkinter', +## 'test_ttk', +## 'test_ttk_textonly', +## 'test_turtle', +## ): +## NEED_MODULES[name] = '_tkinter' +## for name in NEED_SSL: +## NEED_MODULES[name] = '_ssl' NEED_WORKING_THREADING = { @@ -285,13 +324,13 @@ def expected_to_be_skipped(test_name): if package in EXPECTED_SKIP: return True - # Test NEED_MODULES - if test_name in NEED_MODULES: - if miss_modules(NEED_MODULES[test_name]): - return True - elif package in NEED_MODULES: - if miss_modules(NEED_MODULES[package]): - return True + ## # Test NEED_MODULES + ## if test_name in NEED_MODULES: + ## if miss_modules(NEED_MODULES[test_name]): + ## return True + ## elif package in NEED_MODULES: + ## if miss_modules(NEED_MODULES[package]): + ## return True # Custom ruleset if (test_name in NEED_WORKING_THREADING From bfd2b077cfda0b3654b82c216d7141395ad5c31c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 00:12:32 +0100 Subject: [PATCH 18/27] Avoid sys.is_remote_debug_enabled() --- Lib/test/libregrtest/skipped.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 0dbb212d5f8f81..6a566d3fb3656f 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -108,7 +108,9 @@ 'test_wait3', 'test_wait4', } - +if not(sys.platform in ("linux", "darwin") or support.MS_WINDOWS): + # Need Py_SUPPORTS_REMOTE_DEBUG macro + EXPECTED_SKIP.add('test_remote_pdb') if support.MS_WINDOWS: # Tests specific to non-Windows platforms @@ -198,10 +200,6 @@ 'test_venv', } -# On FreeBSD, is_remote_debug_enabled() is always false -if not sys.is_remote_debug_enabled(): - EXPECTED_SKIP.add('test_remote_pdb') - if IS_WASI: EXPECTED_SKIP |= { # configure disables multiple extension modules on WASI From 3a9eb250445db7ad95bf08acdd852620e4ced56b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 00:13:16 +0100 Subject: [PATCH 19/27] Disable shutil.which('gdb') check --- Lib/test/libregrtest/skipped.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 6a566d3fb3656f..10fd1b7604dbf4 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -359,10 +359,10 @@ def expected_to_be_skipped(test_name): # and on macOS. return not support.supports_perf_trampoline_profiling() - if package == 'test_gdb': - # Need gdb program - import shutil - return not shutil.which('gdb') + ## if package == 'test_gdb': + ## # Need gdb program + ## import shutil + ## return not shutil.which('gdb') if test_name == 'test_asdl_parser': # Test only relevant for from-source Python builds From 9f606c308a3137d3209b6944e355527fc39ced22 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 18:07:53 +0100 Subject: [PATCH 20/27] Remove commented and dead code --- Lib/test/libregrtest/skipped.py | 96 +++++---------------------------- 1 file changed, 12 insertions(+), 84 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 10fd1b7604dbf4..4ddba5323b0b3b 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -1,5 +1,6 @@ """ Ruleset to check if a test is expected to be skipped. +Tests are mostly filtered using sys.platform, except a few exceptions. """ import importlib @@ -41,9 +42,18 @@ 'test_pyclbr', 'test_runpy', } +NEED_WORKING_THREADING = { + 'test_concurrent_futures', + 'test_queue', + 'test_thread', + 'test_threadedtempfile', + 'test_threading', + 'test_threading_local', + 'test_webbrowser', +} -# List of tests expected to be skipped +# List of tests expected to be skipped on sys.platform EXPECTED_SKIP = set() if support.Py_GIL_DISABLED: @@ -238,81 +248,12 @@ } # configure disables _multiprocessing and _testmultiphase # extension modules on WASI - EXPECTED_SKIP |= NEED_TESTMULTIPHASE EXPECTED_SKIP |= NEED_MULTIPROCESSING + EXPECTED_SKIP |= NEED_TESTMULTIPHASE # Missing OpenSSL dependency on WASI EXPECTED_SKIP |= NEED_SSL -## # Modules needed by a test. -## # Used to check if a test is expected to be skipped. -## # NEED_MODULES doesn't work on WASI, since the main regrtest process is run -## # on the build Python which is different than the host (WASI) Python. -## NEED_MODULES = { -## 'test__interpchannels': '_interpchannels', -## 'test__interpreters': '_interpreters', -## 'test_crossinterp': '_interpreters', -## 'test_curses': ('_curses', 'curses', 'curses.ascii', 'curses.textpad'), -## 'test_dbm_gnu': 'dbm.gnu', -## 'test_dbm_ndbm': 'dbm.ndbm', -## 'test_fcntl': 'fcntl', -## 'test_free_threading.test_dbm_gnu': 'dbm.gnu', -## 'test_free_threading.test_grp': 'grp', -## 'test_free_threading.test_pwd': 'pwd', -## 'test_free_threading.test_readline': 'readline', -## 'test_free_threading.test_resource': 'resource', -## 'test_free_threading.test_syslog': 'syslog', -## 'test_grp': 'grp', -## 'test_ioctl': ('fcntl', 'termios'), -## 'test_lzma': '_lzma', -## 'test_pty': 'termios', -## 'test_pwd': 'pwd', -## 'test_readline': 'readline', -## 'test_resource': 'resource', -## 'test_syslog': 'syslog', -## 'test_termios': 'termios', -## 'test_tty': ('termios', 'tty'), -## 'test_xxlimited': 'xxlimited', -## 'test_xxtestfuzz': '_xxtestfuzz', -## 'test_zstd': '_zstd', -## } -## for name in NEED_MULTIPROCESSING: -## NEED_MODULES[name] = '_multiprocessing' -## for name in ( -## 'test_idle', -## 'test_tcl', -## 'test_tkinter', -## 'test_ttk', -## 'test_ttk_textonly', -## 'test_turtle', -## ): -## NEED_MODULES[name] = '_tkinter' -## for name in NEED_SSL: -## NEED_MODULES[name] = '_ssl' - - -NEED_WORKING_THREADING = { - 'test_concurrent_futures', - 'test_queue', - 'test_thread', - 'test_threadedtempfile', - 'test_threading', - 'test_threading_local', - 'test_webbrowser', -} - - -def miss_modules(modules): - if isinstance(modules, str): - modules = (modules,) - try: - for module in modules: - importlib.import_module(module) - except ImportError: - return True - return False - - def expected_to_be_skipped(test_name): # Test EXPECTED_SKIP test_name = test_name.removeprefix('test.') @@ -322,14 +263,6 @@ def expected_to_be_skipped(test_name): if package in EXPECTED_SKIP: return True - ## # Test NEED_MODULES - ## if test_name in NEED_MODULES: - ## if miss_modules(NEED_MODULES[test_name]): - ## return True - ## elif package in NEED_MODULES: - ## if miss_modules(NEED_MODULES[package]): - ## return True - # Custom ruleset if (test_name in NEED_WORKING_THREADING or package in NEED_WORKING_THREADING): @@ -359,11 +292,6 @@ def expected_to_be_skipped(test_name): # and on macOS. return not support.supports_perf_trampoline_profiling() - ## if package == 'test_gdb': - ## # Need gdb program - ## import shutil - ## return not shutil.which('gdb') - if test_name == 'test_asdl_parser': # Test only relevant for from-source Python builds import sysconfig From 17f9ca36917fe8dfef9853203480ed12fd984a3a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 18:20:52 +0100 Subject: [PATCH 21/27] Filter more tests --- Lib/test/libregrtest/skipped.py | 52 ++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 4ddba5323b0b3b..9657c01819be7b 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -6,6 +6,7 @@ import importlib import os import sys +import sysconfig from test import support @@ -51,6 +52,14 @@ 'test_threading_local', 'test_webbrowser', } +NEED_TKINTER = { + 'test_idle', + 'test_tcl', + 'test_tkinter', + 'test_ttk', + 'test_ttk_textonly', + 'test_turtle', +} # List of tests expected to be skipped on sys.platform @@ -92,6 +101,7 @@ # Need subprocess support EXPECTED_SKIP |= { 'test_argparse', + 'test_asyncio.test_subprocess', 'test_c_stack_unwind', 'test_cext', 'test_clinic', @@ -121,6 +131,20 @@ if not(sys.platform in ("linux", "darwin") or support.MS_WINDOWS): # Need Py_SUPPORTS_REMOTE_DEBUG macro EXPECTED_SKIP.add('test_remote_pdb') +if not sysconfig.is_python_build(): + # Skip tests on installed Python. + # Tests only relevant for from-source Python builds + EXPECTED_SKIP |= { + # Parser/asdl.py is not installed + 'test_asdl_parser', + # Tools/clinic/ is not installed + 'test_clinic', + # Tools/cases_generator is not installed + 'test_generated_cases', + } +if not sysconfig.get_config_var('WITH_DTRACE'): + # Need ./configure --with-dtrace + EXPECTED_SKIP.add('test_dtrace') if support.MS_WINDOWS: # Tests specific to non-Windows platforms @@ -171,6 +195,11 @@ if not support.is_android: EXPECTED_SKIP.add('test_android') + # _multiprocessing is not available on Android + EXPECTED_SKIP |= NEED_MULTIPROCESSING + # _tkinter is not available on Android + EXPECTED_SKIP |= NEED_TKINTER + if not support.is_apple: EXPECTED_SKIP.add('test_apple') @@ -181,7 +210,10 @@ 'test_grp', # need grp 'test_syslog', # need syslog } + # configure disables _multiprocessing on Apple mobile EXPECTED_SKIP |= NEED_MULTIPROCESSING + # configure disables _tkinter on Apple mobile + EXPECTED_SKIP |= NEED_TKINTER if support.is_emscripten: # configure disables multiple extension modules on Emscripten @@ -195,12 +227,18 @@ 'test_resource', # need resource 'test_syslog', # need syslog } + # configure disables _multiprocessing on Emscripten + EXPECTED_SKIP |= NEED_MULTIPROCESSING EXPECTED_SKIP |= { # Incompatible with Emscripten's mmap emulation 'test_mmap', # Cannot create socketpair on Emscripten/WASI 'test_selectors', } + # Missing OpenSSL dependency on Emscripten + EXPECTED_SKIP |= NEED_SSL + # Missing Tcl/Tk dependency on Emscripten + EXPECTED_SKIP |= NEED_TKINTER if support.is_android or support.is_apple_mobile or support.is_wasm32 or IS_WASI: EXPECTED_SKIP |= { @@ -252,6 +290,10 @@ EXPECTED_SKIP |= NEED_TESTMULTIPHASE # Missing OpenSSL dependency on WASI EXPECTED_SKIP |= NEED_SSL + # Missing Tcl/Tk dependency on WASI + EXPECTED_SKIP |= NEED_TKINTER + # Missing libreadline/libedit dependency on Emscripten + EXPECTED_SKIP.add('readline') def expected_to_be_skipped(test_name): @@ -281,20 +323,10 @@ def expected_to_be_skipped(test_name): name = test_name.removeprefix('test_') return not hasattr(select, name) - if test_name == 'test_dtrace': - # Need ./configure --with-dtrace - import sysconfig - return not sysconfig.get_config_var('WITH_DTRACE') - if test_name in ('test_perf_profiler', 'test_perfmaps', 'test_samply_profiler'): # Need perf trampoline profiling: configure defines the # PY_HAVE_PERF_TRAMPOLINE macro on Linux (x86-64 and AArch64) # and on macOS. return not support.supports_perf_trampoline_profiling() - if test_name == 'test_asdl_parser': - # Test only relevant for from-source Python builds - import sysconfig - return not sysconfig.is_python_build() - return False From 09c49f26935682eac0158ed38b378b0fc9fadb7e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 19:48:22 +0100 Subject: [PATCH 22/27] Update Apple mobile/Emscripten/WASI; fix Android --- Lib/test/libregrtest/skipped.py | 43 ++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 9657c01819be7b..adbdbfe1488059 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -193,8 +193,10 @@ if sys.platform in ("win32", "cygwin"): EXPECTED_SKIP.add('test_multiprocessing_forkserver') -if not support.is_android: +if support.is_android: + # Test specific to Android EXPECTED_SKIP.add('test_android') +else: # _multiprocessing is not available on Android EXPECTED_SKIP |= NEED_MULTIPROCESSING # _tkinter is not available on Android @@ -207,7 +209,10 @@ # configure disables multiple extension modules on Apple mobile EXPECTED_SKIP |= { 'test_curses', # need _curses + 'test_dbm_gnu', # need _gdbm 'test_grp', # need grp + 'test_pwd', # need pwd + 'test_readline', # need readline 'test_syslog', # need syslog } # configure disables _multiprocessing on Apple mobile @@ -222,19 +227,32 @@ 'test__interpreters', # need _interpreters 'test_crossinterp', # need _interpreters 'test_curses', # need _curses + 'test_dbm_gnu', # need _gdbm + 'test_dbm_ndbm', # need _dbm 'test_grp', # need grp 'test_pwd', # need pwd + 'test_readline', # need readline 'test_resource', # need resource 'test_syslog', # need syslog } # configure disables _multiprocessing on Emscripten EXPECTED_SKIP |= NEED_MULTIPROCESSING + + # Missing os.openpty() function on Emscripten + EXPECTED_SKIP.add('test_openpty') + EXPECTED_SKIP |= { # Incompatible with Emscripten's mmap emulation 'test_mmap', # Cannot create socketpair on Emscripten/WASI 'test_selectors', } + + # Missing dependencies on Emscripten + EXPECTED_SKIP |= { + 'test_lzma', # need _lzma + 'test_zstd', # need _zstd + } # Missing OpenSSL dependency on Emscripten EXPECTED_SKIP |= NEED_SSL # Missing Tcl/Tk dependency on Emscripten @@ -249,12 +267,14 @@ } if IS_WASI: + # configure disables multiple extension modules on WASI EXPECTED_SKIP |= { - # configure disables multiple extension modules on WASI 'test__interpchannels', # need _interpchannels 'test__interpreters', # need _interpreters 'test_crossinterp', # need _interpreters 'test_curses', # need _curses + 'test_dbm_gnu', # need _gdbm + 'test_dbm_ndbm', # need _dbm 'test_external_inspection', # need _remote_debugging 'test_fcntl', # need fcntl 'test_gc_stats', # need _remote_debugging @@ -269,31 +289,32 @@ 'test_termios', # need termios 'test_tty', # need termios 'test_xxlimited', # need xxlimited + } + # configure disables _multiprocessing and _testmultiphase + # extension modules on WASI + EXPECTED_SKIP |= NEED_MULTIPROCESSING + EXPECTED_SKIP |= NEED_TESTMULTIPHASE - # Missing functions on WASI - 'test_openpty', # need os.openpty() + # Missing os.openpty() function on WASI + EXPECTED_SKIP.add('test_openpty') - # Missing dependencies on WASI + # Missing dependencies on WASI + EXPECTED_SKIP |= { 'test_bz2', # need _bz2 'test_ctypes', # need _ctypes 'test_dbm_sqlite3', # need _sqlite3 'test_gzip', # need zlib 'test_lzma', # need _lzma + 'test_readline', # need libreadline/libedit 'test_sqlite3', # need _sqlite3 'test_stable_abi_ctypes', # need _ctypes 'test_zlib', # need zlib 'test_zstd', # need _zstd } - # configure disables _multiprocessing and _testmultiphase - # extension modules on WASI - EXPECTED_SKIP |= NEED_MULTIPROCESSING - EXPECTED_SKIP |= NEED_TESTMULTIPHASE # Missing OpenSSL dependency on WASI EXPECTED_SKIP |= NEED_SSL # Missing Tcl/Tk dependency on WASI EXPECTED_SKIP |= NEED_TKINTER - # Missing libreadline/libedit dependency on Emscripten - EXPECTED_SKIP.add('readline') def expected_to_be_skipped(test_name): From 8a438c52c5a86bea17e12969457aebbe89857b8c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 19:54:35 +0100 Subject: [PATCH 23/27] Missing dependencies on Android --- Lib/test/libregrtest/skipped.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index adbdbfe1488059..667aea72540edc 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -64,7 +64,6 @@ # List of tests expected to be skipped on sys.platform EXPECTED_SKIP = set() - if support.Py_GIL_DISABLED: # Need GIL build EXPECTED_SKIP.add('test_interpreters') @@ -146,6 +145,7 @@ # Need ./configure --with-dtrace EXPECTED_SKIP.add('test_dtrace') + if support.MS_WINDOWS: # Tests specific to non-Windows platforms EXPECTED_SKIP |= { @@ -197,14 +197,25 @@ # Test specific to Android EXPECTED_SKIP.add('test_android') else: + # Missing dependencies on Android + EXPECTED_SKIP |= { + 'test_dbm_gnu', # need _gdbm + 'test_dbm_ndbm', # need _dbm + 'test_grp', # need grp + 'test_readline', # need libreadline/libedit + } + # _multiprocessing is not available on Android EXPECTED_SKIP |= NEED_MULTIPROCESSING # _tkinter is not available on Android EXPECTED_SKIP |= NEED_TKINTER + if not support.is_apple: + # Test specific to Apple EXPECTED_SKIP.add('test_apple') + if support.is_apple_mobile: # configure disables multiple extension modules on Apple mobile EXPECTED_SKIP |= { @@ -220,6 +231,7 @@ # configure disables _tkinter on Apple mobile EXPECTED_SKIP |= NEED_TKINTER + if support.is_emscripten: # configure disables multiple extension modules on Emscripten EXPECTED_SKIP |= { @@ -258,6 +270,7 @@ # Missing Tcl/Tk dependency on Emscripten EXPECTED_SKIP |= NEED_TKINTER + if support.is_android or support.is_apple_mobile or support.is_wasm32 or IS_WASI: EXPECTED_SKIP |= { # pty is not available on these platforms @@ -266,6 +279,7 @@ 'test_venv', } + if IS_WASI: # configure disables multiple extension modules on WASI EXPECTED_SKIP |= { From 0b9c802147b2b8c01bfc94bbb36aa888a09eb72e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 19:56:39 +0100 Subject: [PATCH 24/27] Run prek --all-files (remove import importlib) --- Lib/test/libregrtest/skipped.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index 667aea72540edc..dbb120462db8fe 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -3,7 +3,6 @@ Tests are mostly filtered using sys.platform, except a few exceptions. """ -import importlib import os import sys import sysconfig From a72df3ed8d4de370cf606167d088b0b542264120 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 20:34:44 +0100 Subject: [PATCH 25/27] Invert is_android test --- Lib/test/libregrtest/skipped.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index dbb120462db8fe..b6ccc085946416 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -193,9 +193,6 @@ EXPECTED_SKIP.add('test_multiprocessing_forkserver') if support.is_android: - # Test specific to Android - EXPECTED_SKIP.add('test_android') -else: # Missing dependencies on Android EXPECTED_SKIP |= { 'test_dbm_gnu', # need _gdbm @@ -208,6 +205,9 @@ EXPECTED_SKIP |= NEED_MULTIPROCESSING # _tkinter is not available on Android EXPECTED_SKIP |= NEED_TKINTER +else: + # Test specific to Android + EXPECTED_SKIP.add('test_android') if not support.is_apple: From d8f7305535a6263065ef500933c3a4efa6c3f5c4 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 22:09:39 +0100 Subject: [PATCH 26/27] Android: skip test_curses --- Lib/test/libregrtest/skipped.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index b6ccc085946416..e1f5afbf8526a5 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -195,6 +195,7 @@ if support.is_android: # Missing dependencies on Android EXPECTED_SKIP |= { + 'test_curses', # need _curses 'test_dbm_gnu', # need _gdbm 'test_dbm_ndbm', # need _dbm 'test_grp', # need grp From ff5a77be59fb8ec69b07ad79f69e6d59b6fec3f8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Nov 2026 22:41:48 +0100 Subject: [PATCH 27/27] test_gdb is skipped on installed Python --- Lib/test/libregrtest/skipped.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/libregrtest/skipped.py b/Lib/test/libregrtest/skipped.py index e1f5afbf8526a5..708266c49c359e 100644 --- a/Lib/test/libregrtest/skipped.py +++ b/Lib/test/libregrtest/skipped.py @@ -137,6 +137,8 @@ 'test_asdl_parser', # Tools/clinic/ is not installed 'test_clinic', + # python-gdb.py is not installed + 'test_gdb', # Tools/cases_generator is not installed 'test_generated_cases', }