From 67ef72ca3f0e2b88a7cf30237ab266109ae1ff61 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 14 Oct 2026 11:40:07 +0200 Subject: [PATCH 1/2] Skip test_readlink_is_marked_as_supports_fd on older macOS & iOS - Generalize @requires_mac_ver logic to add @requires_ios_ver - Skip test_readlink_is_marked_as_supports_fd on lower Apple OS versions --- Lib/test/support/__init__.py | 48 ++++++++++++++++++++++------------ Lib/test/test_os/test_posix.py | 2 ++ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 5331615b1b1587a..78c50ab58ae601e 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -19,6 +19,7 @@ import types import unittest import warnings +lazy import platform __all__ = [ @@ -229,7 +230,6 @@ def _force_run(path, func, *args): def _is_gui_available(): if hasattr(_is_gui_available, 'result'): return _is_gui_available.result - import platform reason = None if sys.platform.startswith('win') and platform.win32_is_iot(): reason = "gui is not available on Windows IoT Core" @@ -354,7 +354,6 @@ def _requires_unix_version(sysname, min_version): For example, @_requires_unix_version('FreeBSD', (7, 2)) raises SkipTest if the FreeBSD version is less than 7.2. """ - import platform min_version_txt = '.'.join(map(str, min_version)) version_txt = platform.release().split('-', 1)[0] if platform.system() == sysname: @@ -392,19 +391,12 @@ def requires_linux_version(*min_version): """ return _requires_unix_version('Linux', min_version) -def requires_mac_ver(*min_version): - """Decorator raising SkipTest if the OS is Mac OS X and the OS X - version if less than min_version. - - For example, @requires_mac_ver(10, 5) raises SkipTest if the OS X version - is lesser than 10.5. - """ +def _requires_apple_os_version(name, sys_platform, get_version_text, min_version): def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): - if sys.platform == 'darwin': - import platform - version_txt = platform.mac_ver()[0] + if sys.platform == sys_platform: + version_txt = get_version_text() try: version = tuple(map(int, version_txt.split('.'))) except ValueError: @@ -413,14 +405,40 @@ def wrapper(*args, **kw): if version < min_version: min_version_txt = '.'.join(map(str, min_version)) raise unittest.SkipTest( - "Mac OS X %s or higher required, not %s" - % (min_version_txt, version_txt)) + f"{name} {min_version_txt} or higher required, " + + f"not {version_txt}") return func(*args, **kw) wrapper.min_version = min_version return wrapper return decorator +def requires_mac_ver(*min_version): + """Decorator raising SkipTest if the OS is Mac OS X and the OS X + version if less than min_version. + + For example, @requires_mac_ver(10, 5) raises SkipTest if the OS X version + is lesser than 10.5. + """ + return _requires_apple_os_version( + "macOS", "darwin", + get_version_text=lambda: platform.mac_ver()[0], + min_version=min_version) + + +def requires_ios_ver(*min_version): + """Decorator raising SkipTest if the OS is iOS and the OS version + version if less than min_version. + + For example, requires_ios_ver(16, 0) raises SkipTest if the iOS version + is lesser than 16.0. + """ + return _requires_apple_os_version( + "iOS", "ios", + get_version_text=lambda: platform.ios_ver().release, + min_version=min_version) + + def thread_unsafe(reason): """Mark a test as not thread safe. When the test runner is run with --parallel-threads=N, the test will be run in a single thread.""" @@ -2223,7 +2241,6 @@ def setswitchinterval(interval): if is_android and interval < minimum_interval: global _old_android_emulator if _old_android_emulator is None: - import platform av = platform.android_ver() _old_android_emulator = av.is_emulator and av.api_level < 24 if _old_android_emulator: @@ -3480,7 +3497,6 @@ def linked_to_musl(): # On linux, we'll depend on the platform module to do the check, so new # musl platforms should add support in that module if possible. - import platform lib, version = platform.libc_ver() if lib != 'musl': _linked_to_musl = False diff --git a/Lib/test/test_os/test_posix.py b/Lib/test/test_os/test_posix.py index 7b8f8d2ddadd96b..82115c338906fc0 100644 --- a/Lib/test/test_os/test_posix.py +++ b/Lib/test/test_os/test_posix.py @@ -1946,6 +1946,8 @@ def test_readlink_with_fd_throws_not_implemented_error(self): @unittest.skipUnless(sys.platform in ["linux", "android", "darwin", "ios"], "feature not supported on this platform") + @support.requires_mac_ver(13, 0) + @support.requires_ios_ver(16, 0) def test_readlink_is_marked_as_supports_fd(self): self.assertIn(os.readlink, os.supports_fd) From a907babcb46d82dc1de00d69d6e16322e0f723f4 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 14 Oct 2026 12:33:28 +0200 Subject: [PATCH 2/2] Add to __all__ --- Lib/test/support/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 78c50ab58ae601e..3bcb4b111d669c4 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -34,6 +34,7 @@ "is_resource_enabled", "get_resource_value", "requires", "requires_resource", "requires_freebsd_version", "requires_gil_enabled", "requires_linux_version", "requires_mac_ver", + "requires_ios_ver", "check_syntax_error", "requires_gzip", "requires_bz2", "requires_lzma", "requires_zstd", "bigmemtest", "nomemtest", "bigaddrspacetest", "cpython_only", "get_attribute",