summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2024-02-05 00:04:57 (GMT)
committerGitHub <noreply@github.com>2024-02-05 00:04:57 (GMT)
commit391659b3da570bfa28fed5fbdb6f2d9c26ab3dd0 (patch)
tree19d4bd5693a55e06e3ab4a88826e284a1e9717ae
parent15f6f048a6ecdf0f6f4fc076d013be3d110f8ed6 (diff)
downloadcpython-391659b3da570bfa28fed5fbdb6f2d9c26ab3dd0.zip
cpython-391659b3da570bfa28fed5fbdb6f2d9c26ab3dd0.tar.gz
cpython-391659b3da570bfa28fed5fbdb6f2d9c26ab3dd0.tar.bz2
gh-114099: Add test exclusions to support running the test suite on iOS (#114889)
Add test annotations required to run the test suite on iOS (PEP 730). The majority of the change involve annotating tests that use subprocess, but are skipped on Emscripten/WASI for other reasons, and including iOS/tvOS/watchOS under the same umbrella as macOS/darwin checks. `is_apple` and `is_apple_mobile` test helpers have been added to identify *any* Apple platform, and "any Apple platform except macOS", respectively.
-rw-r--r--Lib/test/support/__init__.py26
-rw-r--r--Lib/test/support/os_helper.py8
-rw-r--r--Lib/test/test_asyncio/test_events.py14
-rw-r--r--Lib/test/test_asyncio/test_streams.py3
-rw-r--r--Lib/test/test_asyncio/test_subprocess.py2
-rw-r--r--Lib/test/test_asyncio/test_unix_events.py2
-rw-r--r--Lib/test/test_cmd_line_script.py16
-rw-r--r--Lib/test/test_code_module.py1
-rw-r--r--Lib/test/test_fcntl.py12
-rw-r--r--Lib/test/test_ftplib.py3
-rw-r--r--Lib/test/test_genericpath.py22
-rw-r--r--Lib/test/test_httpservers.py18
-rw-r--r--Lib/test/test_io.py16
-rw-r--r--Lib/test/test_marshal.py4
-rw-r--r--Lib/test/test_mmap.py4
-rw-r--r--Lib/test/test_os.py4
-rw-r--r--Lib/test/test_pdb.py102
-rw-r--r--Lib/test/test_platform.py3
-rw-r--r--Lib/test/test_posix.py15
-rw-r--r--Lib/test/test_pty.py18
-rw-r--r--Lib/test/test_selectors.py5
-rw-r--r--Lib/test/test_shutil.py2
-rw-r--r--Lib/test/test_signal.py9
-rw-r--r--Lib/test/test_socket.py24
-rw-r--r--Lib/test/test_sqlite3/test_dbapi.py6
-rw-r--r--Lib/test/test_stat.py5
-rw-r--r--Lib/test/test_sys_settrace.py3
-rw-r--r--Lib/test/test_unicode_file_functions.py14
-rw-r--r--Lib/test/test_urllib2.py2
-rw-r--r--Lib/test/test_venv.py10
-rw-r--r--Misc/NEWS.d/next/Tests/2024-02-02-13-18-55.gh-issue-114099.C_ycWg.rst1
31 files changed, 224 insertions, 150 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index f2e6af0..5b091fb 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -43,7 +43,7 @@ __all__ = [
"requires_limited_api", "requires_specialization",
# sys
"MS_WINDOWS", "is_jython", "is_android", "is_emscripten", "is_wasi",
- "check_impl_detail", "unix_shell", "setswitchinterval",
+ "is_apple_mobile", "check_impl_detail", "unix_shell", "setswitchinterval",
# os
"get_pagesize",
# network
@@ -522,7 +522,7 @@ is_jython = sys.platform.startswith('java')
is_android = hasattr(sys, 'getandroidapilevel')
-if sys.platform not in ('win32', 'vxworks'):
+if sys.platform not in {"win32", "vxworks", "ios", "tvos", "watchos"}:
unix_shell = '/system/bin/sh' if is_android else '/bin/sh'
else:
unix_shell = None
@@ -532,19 +532,35 @@ else:
is_emscripten = sys.platform == "emscripten"
is_wasi = sys.platform == "wasi"
-has_fork_support = hasattr(os, "fork") and not is_emscripten and not is_wasi
+# Apple mobile platforms (iOS/tvOS/watchOS) are POSIX-like but do not
+# have subprocess or fork support.
+is_apple_mobile = sys.platform in {"ios", "tvos", "watchos"}
+is_apple = is_apple_mobile or sys.platform == "darwin"
+
+has_fork_support = hasattr(os, "fork") and not (
+ is_emscripten
+ or is_wasi
+ or is_apple_mobile
+)
def requires_fork():
return unittest.skipUnless(has_fork_support, "requires working os.fork()")
-has_subprocess_support = not is_emscripten and not is_wasi
+has_subprocess_support = not (
+ is_emscripten
+ or is_wasi
+ or is_apple_mobile
+)
def requires_subprocess():
"""Used for subprocess, os.spawn calls, fd inheritance"""
return unittest.skipUnless(has_subprocess_support, "requires subprocess support")
# Emscripten's socket emulation and WASI sockets have limitations.
-has_socket_support = not is_emscripten and not is_wasi
+has_socket_support = not (
+ is_emscripten
+ or is_wasi
+)
def requires_working_socket(*, module=False):
"""Skip tests or modules that require working sockets
diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py
index 20f38fd..22787e3 100644
--- a/Lib/test/support/os_helper.py
+++ b/Lib/test/support/os_helper.py
@@ -22,8 +22,8 @@ TESTFN_ASCII = "{}_{}_tmp".format(TESTFN_ASCII, os.getpid())
# TESTFN_UNICODE is a non-ascii filename
TESTFN_UNICODE = TESTFN_ASCII + "-\xe0\xf2\u0258\u0141\u011f"
-if sys.platform == 'darwin':
- # In Mac OS X's VFS API file names are, by definition, canonically
+if support.is_apple:
+ # On Apple's VFS API file names are, by definition, canonically
# decomposed Unicode, encoded using UTF-8. See QA1173:
# http://developer.apple.com/mac/library/qa/qa2001/qa1173.html
import unicodedata
@@ -48,8 +48,8 @@ if os.name == 'nt':
'encoding (%s). Unicode filename tests may not be effective'
% (TESTFN_UNENCODABLE, sys.getfilesystemencoding()))
TESTFN_UNENCODABLE = None
-# macOS and Emscripten deny unencodable filenames (invalid utf-8)
-elif sys.platform not in {'darwin', 'emscripten', 'wasi'}:
+# Apple and Emscripten deny unencodable filenames (invalid utf-8)
+elif not support.is_apple and sys.platform not in {"emscripten", "wasi"}:
try:
# ascii and utf-8 cannot encode the byte 0xff
b'\xff'.decode(sys.getfilesystemencoding())
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index b25c097..c92c88b 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -1815,6 +1815,7 @@ class SubprocessTestsMixin:
else:
self.assertEqual(-signal.SIGKILL, returncode)
+ @support.requires_subprocess()
def test_subprocess_exec(self):
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
@@ -1836,6 +1837,7 @@ class SubprocessTestsMixin:
self.check_killed(proto.returncode)
self.assertEqual(b'Python The Winner', proto.data[1])
+ @support.requires_subprocess()
def test_subprocess_interactive(self):
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
@@ -1863,6 +1865,7 @@ class SubprocessTestsMixin:
self.loop.run_until_complete(proto.completed)
self.check_killed(proto.returncode)
+ @support.requires_subprocess()
def test_subprocess_shell(self):
connect = self.loop.subprocess_shell(
functools.partial(MySubprocessProtocol, self.loop),
@@ -1879,6 +1882,7 @@ class SubprocessTestsMixin:
self.assertEqual(proto.data[2], b'')
transp.close()
+ @support.requires_subprocess()
def test_subprocess_exitcode(self):
connect = self.loop.subprocess_shell(
functools.partial(MySubprocessProtocol, self.loop),
@@ -1890,6 +1894,7 @@ class SubprocessTestsMixin:
self.assertEqual(7, proto.returncode)
transp.close()
+ @support.requires_subprocess()
def test_subprocess_close_after_finish(self):
connect = self.loop.subprocess_shell(
functools.partial(MySubprocessProtocol, self.loop),
@@ -1904,6 +1909,7 @@ class SubprocessTestsMixin:
self.assertEqual(7, proto.returncode)
self.assertIsNone(transp.close())
+ @support.requires_subprocess()
def test_subprocess_kill(self):
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
@@ -1920,6 +1926,7 @@ class SubprocessTestsMixin:
self.check_killed(proto.returncode)
transp.close()
+ @support.requires_subprocess()
def test_subprocess_terminate(self):
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
@@ -1937,6 +1944,7 @@ class SubprocessTestsMixin:
transp.close()
@unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP")
+ @support.requires_subprocess()
def test_subprocess_send_signal(self):
# bpo-31034: Make sure that we get the default signal handler (killing
# the process). The parent process may have decided to ignore SIGHUP,
@@ -1961,6 +1969,7 @@ class SubprocessTestsMixin:
finally:
signal.signal(signal.SIGHUP, old_handler)
+ @support.requires_subprocess()
def test_subprocess_stderr(self):
prog = os.path.join(os.path.dirname(__file__), 'echo2.py')
@@ -1982,6 +1991,7 @@ class SubprocessTestsMixin:
self.assertTrue(proto.data[2].startswith(b'ERR:test'), proto.data[2])
self.assertEqual(0, proto.returncode)
+ @support.requires_subprocess()
def test_subprocess_stderr_redirect_to_stdout(self):
prog = os.path.join(os.path.dirname(__file__), 'echo2.py')
@@ -2007,6 +2017,7 @@ class SubprocessTestsMixin:
transp.close()
self.assertEqual(0, proto.returncode)
+ @support.requires_subprocess()
def test_subprocess_close_client_stream(self):
prog = os.path.join(os.path.dirname(__file__), 'echo3.py')
@@ -2041,6 +2052,7 @@ class SubprocessTestsMixin:
self.loop.run_until_complete(proto.completed)
self.check_killed(proto.returncode)
+ @support.requires_subprocess()
def test_subprocess_wait_no_same_group(self):
# start the new process in a new session
connect = self.loop.subprocess_shell(
@@ -2053,6 +2065,7 @@ class SubprocessTestsMixin:
self.assertEqual(7, proto.returncode)
transp.close()
+ @support.requires_subprocess()
def test_subprocess_exec_invalid_args(self):
async def connect(**kwds):
await self.loop.subprocess_exec(
@@ -2066,6 +2079,7 @@ class SubprocessTestsMixin:
with self.assertRaises(ValueError):
self.loop.run_until_complete(connect(shell=True))
+ @support.requires_subprocess()
def test_subprocess_shell_invalid_args(self):
async def connect(cmd=None, **kwds):
diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py
index 3c8cc5f..2109905 100644
--- a/Lib/test/test_asyncio/test_streams.py
+++ b/Lib/test/test_asyncio/test_streams.py
@@ -10,7 +10,6 @@ import threading
import unittest
from unittest import mock
import warnings
-from test.support import socket_helper
try:
import ssl
except ImportError:
@@ -18,6 +17,7 @@ except ImportError:
import asyncio
from test.test_asyncio import utils as test_utils
+from test.support import requires_subprocess, socket_helper
def tearDownModule():
@@ -770,6 +770,7 @@ class StreamTests(test_utils.TestCase):
self.assertEqual(msg2, b"hello world 2!\n")
@unittest.skipIf(sys.platform == 'win32', "Don't have pipes")
+ @requires_subprocess()
def test_read_all_from_pipe_reader(self):
# See asyncio issue 168. This test is derived from the example
# subprocess_attach_read_pipe.py, but we configure the
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
index 808b21c..f50a9eb 100644
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -47,6 +47,7 @@ class TestSubprocessTransport(base_subprocess.BaseSubprocessTransport):
self._proc.pid = -1
+@support.requires_subprocess()
class SubprocessTransportTests(test_utils.TestCase):
def setUp(self):
super().setUp()
@@ -110,6 +111,7 @@ class SubprocessTransportTests(test_utils.TestCase):
transport.close()
+@support.requires_subprocess()
class SubprocessMixin:
def test_stdin_stdout(self):
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
index d2c8cba..59ef9f5 100644
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -1874,7 +1874,7 @@ class TestFunctional(unittest.TestCase):
wsock.close()
-@unittest.skipUnless(hasattr(os, 'fork'), 'requires os.fork()')
+@support.requires_fork()
class TestFork(unittest.IsolatedAsyncioTestCase):
async def test_fork_not_share_event_loop(self):
diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py
index 48754d5..3a5a8ab 100644
--- a/Lib/test/test_cmd_line_script.py
+++ b/Lib/test/test_cmd_line_script.py
@@ -14,8 +14,7 @@ import io
import textwrap
from test import support
-from test.support import import_helper
-from test.support import os_helper
+from test.support import import_helper, is_apple, os_helper
from test.support.script_helper import (
make_pkg, make_script, make_zip_pkg, make_zip_script,
assert_python_ok, assert_python_failure, spawn_python, kill_python)
@@ -557,12 +556,17 @@ class CmdLineTest(unittest.TestCase):
self.assertTrue(text[3].startswith('NameError'))
def test_non_ascii(self):
- # Mac OS X denies the creation of a file with an invalid UTF-8 name.
+ # Apple platforms deny the creation of a file with an invalid UTF-8 name.
# Windows allows creating a name with an arbitrary bytes name, but
# Python cannot a undecodable bytes argument to a subprocess.
- # WASI does not permit invalid UTF-8 names.
- if (os_helper.TESTFN_UNDECODABLE
- and sys.platform not in ('win32', 'darwin', 'emscripten', 'wasi')):
+ # Emscripten/WASI does not permit invalid UTF-8 names.
+ if (
+ os_helper.TESTFN_UNDECODABLE
+ and sys.platform not in {
+ "win32", "emscripten", "wasi"
+ }
+ and not is_apple
+ ):
name = os.fsdecode(os_helper.TESTFN_UNDECODABLE)
elif os_helper.TESTFN_NONASCII:
name = os_helper.TESTFN_NONASCII
diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py
index 747c0f9..259778a 100644
--- a/Lib/test/test_code_module.py
+++ b/Lib/test/test_code_module.py
@@ -160,6 +160,7 @@ class TestInteractiveConsoleLocalExit(unittest.TestCase, MockSys):
self.console = code.InteractiveConsole(local_exit=True)
self.mock_sys()
+ @unittest.skipIf(sys.flags.no_site, "exit() isn't defined unless there's a site module")
def test_exit(self):
# default exit message
self.infunc.side_effect = ["exit()"]
diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py
index 203dd6f..6d734d0 100644
--- a/Lib/test/test_fcntl.py
+++ b/Lib/test/test_fcntl.py
@@ -6,7 +6,9 @@ import os
import struct
import sys
import unittest
-from test.support import verbose, cpython_only, get_pagesize
+from test.support import (
+ cpython_only, get_pagesize, is_apple, requires_subprocess, verbose
+)
from test.support.import_helper import import_module
from test.support.os_helper import TESTFN, unlink
@@ -56,8 +58,10 @@ class TestFcntl(unittest.TestCase):
else:
start_len = "qq"
- if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd'))
- or sys.platform == 'darwin'):
+ if (
+ sys.platform.startswith(('netbsd', 'freebsd', 'openbsd'))
+ or is_apple
+ ):
if struct.calcsize('l') == 8:
off_t = 'l'
pid_t = 'i'
@@ -157,6 +161,7 @@ class TestFcntl(unittest.TestCase):
self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH)
@unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError")
+ @requires_subprocess()
def test_lockf_exclusive(self):
self.f = open(TESTFN, 'wb+')
cmd = fcntl.LOCK_EX | fcntl.LOCK_NB
@@ -169,6 +174,7 @@ class TestFcntl(unittest.TestCase):
self.assertEqual(p.exitcode, 0)
@unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError")
+ @requires_subprocess()
def test_lockf_share(self):
self.f = open(TESTFN, 'wb+')
cmd = fcntl.LOCK_SH | fcntl.LOCK_NB
diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py
index 2f191ea..81115e9 100644
--- a/Lib/test/test_ftplib.py
+++ b/Lib/test/test_ftplib.py
@@ -18,6 +18,7 @@ except ImportError:
from unittest import TestCase, skipUnless
from test import support
+from test.support import requires_subprocess
from test.support import threading_helper
from test.support import socket_helper
from test.support import warnings_helper
@@ -900,6 +901,7 @@ class TestIPv6Environment(TestCase):
@skipUnless(ssl, "SSL not available")
+@requires_subprocess()
class TestTLS_FTPClassMixin(TestFTPClass):
"""Repeat TestFTPClass tests starting the TLS layer for both control
and data connections first.
@@ -916,6 +918,7 @@ class TestTLS_FTPClassMixin(TestFTPClass):
@skipUnless(ssl, "SSL not available")
+@requires_subprocess()
class TestTLS_FTPClass(TestCase):
"""Specific TLS_FTP class tests."""
diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py
index 4f311c2..b77cd4c 100644
--- a/Lib/test/test_genericpath.py
+++ b/Lib/test/test_genericpath.py
@@ -7,9 +7,9 @@ import os
import sys
import unittest
import warnings
-from test.support import is_emscripten
-from test.support import os_helper
-from test.support import warnings_helper
+from test.support import (
+ is_apple, is_emscripten, os_helper, warnings_helper
+)
from test.support.script_helper import assert_python_ok
from test.support.os_helper import FakePath
@@ -483,12 +483,16 @@ class CommonTest(GenericTest):
self.assertIsInstance(abspath(path), str)
def test_nonascii_abspath(self):
- if (os_helper.TESTFN_UNDECODABLE
- # macOS and Emscripten deny the creation of a directory with an
- # invalid UTF-8 name. Windows allows creating a directory with an
- # arbitrary bytes name, but fails to enter this directory
- # (when the bytes name is used).
- and sys.platform not in ('win32', 'darwin', 'emscripten', 'wasi')):
+ if (
+ os_helper.TESTFN_UNDECODABLE
+ # Apple platforms and Emscripten/WASI deny the creation of a
+ # directory with an invalid UTF-8 name. Windows allows creating a
+ # directory with an arbitrary bytes name, but fails to enter this
+ # directory (when the bytes name is used).
+ and sys.platform not in {
+ "win32", "emscripten", "wasi"
+ } and not is_apple
+ ):
name = os_helper.TESTFN_UNDECODABLE
elif os_helper.TESTFN_NONASCII:
name = os_helper.TESTFN_NONASCII
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
index 9fa6ecf..d762ec6 100644
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -30,8 +30,9 @@ from io import BytesIO, StringIO
import unittest
from test import support
-from test.support import os_helper
-from test.support import threading_helper
+from test.support import (
+ is_apple, os_helper, requires_subprocess, threading_helper
+)
support.requires_working_socket(module=True)
@@ -410,8 +411,8 @@ class SimpleHTTPServerTestCase(BaseTestCase):
reader.close()
return body
- @unittest.skipIf(sys.platform == 'darwin',
- 'undecodable name cannot always be decoded on macOS')
+ @unittest.skipIf(is_apple,
+ 'undecodable name cannot always be decoded on Apple platforms')
@unittest.skipIf(sys.platform == 'win32',
'undecodable name cannot be decoded on win32')
@unittest.skipUnless(os_helper.TESTFN_UNDECODABLE,
@@ -422,11 +423,11 @@ class SimpleHTTPServerTestCase(BaseTestCase):
with open(os.path.join(self.tempdir, filename), 'wb') as f:
f.write(os_helper.TESTFN_UNDECODABLE)
response = self.request(self.base_url + '/')
- if sys.platform == 'darwin':
- # On Mac OS the HFS+ filesystem replaces bytes that aren't valid
- # UTF-8 into a percent-encoded value.
+ if is_apple:
+ # On Apple platforms the HFS+ filesystem replaces bytes that
+ # aren't valid UTF-8 into a percent-encoded value.
for name in os.listdir(self.tempdir):
- if name != 'test': # Ignore a filename created in setUp().
+ if name != 'test': # Ignore a filename created in setUp().
filename = name
break
body = self.check_status_and_reason(response, HTTPStatus.OK)
@@ -697,6 +698,7 @@ print("</pre>")
@unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
"This test can't be run reliably as root (issue #13308).")
+@requires_subprocess()
class CGIHTTPServerTestCase(BaseTestCase):
class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler):
_test_case_self = None # populated by each setUp() method call.
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 9e28b93..73669ec 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -39,11 +39,9 @@ from itertools import cycle, count
from test import support
from test.support.script_helper import (
assert_python_ok, assert_python_failure, run_python_until_end)
-from test.support import import_helper
-from test.support import os_helper
-from test.support import threading_helper
-from test.support import warnings_helper
-from test.support import skip_if_sanitizer
+from test.support import (
+ import_helper, is_apple, os_helper, skip_if_sanitizer, threading_helper, warnings_helper
+)
from test.support.os_helper import FakePath
import codecs
@@ -606,10 +604,10 @@ class IOTest(unittest.TestCase):
self.read_ops(f, True)
def test_large_file_ops(self):
- # On Windows and Mac OSX this test consumes large resources; It takes
- # a long time to build the >2 GiB file and takes >2 GiB of disk space
- # therefore the resource must be enabled to run this test.
- if sys.platform[:3] == 'win' or sys.platform == 'darwin':
+ # On Windows and Apple platforms this test consumes large resources; It
+ # takes a long time to build the >2 GiB file and takes >2 GiB of disk
+ # space therefore the resource must be enabled to run this test.
+ if sys.platform[:3] == 'win' or is_apple:
support.requires(
'largefile',
'test requires %s bytes and a long time to run' % self.LARGE)
diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py
index 6e17e01..615568e 100644
--- a/Lib/test/test_marshal.py
+++ b/Lib/test/test_marshal.py
@@ -1,5 +1,5 @@
from test import support
-from test.support import os_helper, requires_debug_ranges
+from test.support import is_apple_mobile, os_helper, requires_debug_ranges
from test.support.script_helper import assert_python_ok
import array
import io
@@ -286,7 +286,7 @@ class BugsTestCase(unittest.TestCase):
#if os.name == 'nt' and support.Py_DEBUG:
if os.name == 'nt':
MAX_MARSHAL_STACK_DEPTH = 1000
- elif sys.platform == 'wasi':
+ elif sys.platform == 'wasi' or is_apple_mobile:
MAX_MARSHAL_STACK_DEPTH = 1500
else:
MAX_MARSHAL_STACK_DEPTH = 2000
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index b89621e..ac75975 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -1,5 +1,5 @@
from test.support import (
- requires, _2G, _4G, gc_collect, cpython_only, is_emscripten
+ requires, _2G, _4G, gc_collect, cpython_only, is_emscripten, is_apple,
)
from test.support.import_helper import import_module
from test.support.os_helper import TESTFN, unlink
@@ -1067,7 +1067,7 @@ class LargeMmapTests(unittest.TestCase):
unlink(TESTFN)
def _make_test_file(self, num_zeroes, tail):
- if sys.platform[:3] == 'win' or sys.platform == 'darwin':
+ if sys.platform[:3] == 'win' or is_apple:
requires('largefile',
'test requires %s bytes and a long time to run' % str(0x180000000))
f = open(TESTFN, 'w+b')
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index ed79a2c..86af1a8 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -3848,6 +3848,7 @@ class TermsizeTests(unittest.TestCase):
self.assertGreaterEqual(size.columns, 0)
self.assertGreaterEqual(size.lines, 0)
+ @support.requires_subprocess()
def test_stty_match(self):
"""Check if stty returns the same results
@@ -4577,7 +4578,8 @@ class PseudoterminalTests(unittest.TestCase):
self.addCleanup(os.close, son_fd)
self.assertEqual(os.ptsname(mother_fd), os.ttyname(son_fd))
- @unittest.skipUnless(hasattr(os, 'spawnl'), "need os.openpty()")
+ @unittest.skipUnless(hasattr(os, 'spawnl'), "need os.spawnl()")
+ @support.requires_subprocess()
def test_pipe_spawnl(self):
# gh-77046: On Windows, os.pipe() file descriptors must be created with
# _O_NOINHERIT to make them non-inheritable. UCRT has no public API to
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index b2283cf..2b0795c 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -779,58 +779,62 @@ def test_pdb_where_command():
(Pdb) continue
"""
-def test_pdb_interact_command():
- """Test interact command
- >>> g = 0
- >>> dict_g = {}
+# skip this test if sys.flags.no_site = True;
+# exit() isn't defined unless there's a site module.
+if not sys.flags.no_site:
+ def test_pdb_interact_command():
+ """Test interact command
- >>> def test_function():
- ... x = 1
- ... lst_local = []
- ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+ >>> g = 0
+ >>> dict_g = {}
- >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
- ... 'interact',
- ... 'x',
- ... 'g',
- ... 'x = 2',
- ... 'g = 3',
- ... 'dict_g["a"] = True',
- ... 'lst_local.append(x)',
- ... 'exit()',
- ... 'p x',
- ... 'p g',
- ... 'p dict_g',
- ... 'p lst_local',
- ... 'continue',
- ... ]):
- ... test_function()
- --Return--
- > <doctest test.test_pdb.test_pdb_interact_command[2]>(4)test_function()->None
- -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
- (Pdb) interact
- *pdb interact start*
- ... x
- 1
- ... g
- 0
- ... x = 2
- ... g = 3
- ... dict_g["a"] = True
- ... lst_local.append(x)
- ... exit()
- *exit from pdb interact command*
- (Pdb) p x
- 1
- (Pdb) p g
- 0
- (Pdb) p dict_g
- {'a': True}
- (Pdb) p lst_local
- [2]
- (Pdb) continue
- """
+ >>> def test_function():
+ ... x = 1
+ ... lst_local = []
+ ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+
+ >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+ ... 'interact',
+ ... 'x',
+ ... 'g',
+ ... 'x = 2',
+ ... 'g = 3',
+ ... 'dict_g["a"] = True',
+ ... 'lst_local.append(x)',
+ ... 'exit()',
+ ... 'p x',
+ ... 'p g',
+ ... 'p dict_g',
+ ... 'p lst_local',
+ ... 'continue',
+ ... ]):
+ ... test_function()
+ --Return--
+ > <doctest test.test_pdb.test_pdb_interact_command[2]>(4)test_function()->None
+ -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+ (Pdb) interact
+ *pdb interact start*
+ ... x
+ 1
+ ... g
+ 0
+ ... x = 2
+ ... g = 3
+ ... dict_g["a"] = True
+ ... lst_local.append(x)
+ ... exit()
+ *exit from pdb interact command*
+ (Pdb) p x
+ 1
+ (Pdb) p g
+ 0
+ (Pdb) p dict_g
+ {'a': True}
+ (Pdb) p lst_local
+ [2]
+ (Pdb) continue
+ """
def test_convenience_variables():
"""Test convenience variables
diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py
index 2169733..648e18d 100644
--- a/Lib/test/test_platform.py
+++ b/Lib/test/test_platform.py
@@ -472,7 +472,8 @@ class PlatformTest(unittest.TestCase):
'root:xnu-4570.71.2~1/RELEASE_X86_64'),
'x86_64', 'i386')
arch = ('64bit', '')
- with mock.patch.object(platform, 'uname', return_value=uname), \
+ with mock.patch.object(sys, "platform", "darwin"), \
+ mock.patch.object(platform, 'uname', return_value=uname), \
mock.patch.object(platform, 'architecture', return_value=arch):
for mac_ver, expected_terse, expected in [
# darwin: mac_ver() returns empty strings
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index 9c382ac..72e348f 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -1,7 +1,7 @@
"Test posix functions"
from test import support
-from test.support import import_helper
+from test.support import is_apple
from test.support import os_helper
from test.support import warnings_helper
from test.support.script_helper import assert_python_ok
@@ -781,9 +781,10 @@ class PosixTester(unittest.TestCase):
check_stat(uid, gid)
self.assertRaises(OSError, chown_func, first_param, 0, -1)
check_stat(uid, gid)
- if 0 not in os.getgroups():
- self.assertRaises(OSError, chown_func, first_param, -1, 0)
- check_stat(uid, gid)
+ if hasattr(os, 'getgroups'):
+ if 0 not in os.getgroups():
+ self.assertRaises(OSError, chown_func, first_param, -1, 0)
+ check_stat(uid, gid)
# test illegal types
for t in str, float:
self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
@@ -1256,8 +1257,8 @@ class PosixTester(unittest.TestCase):
self.assertIsInstance(lo, int)
self.assertIsInstance(hi, int)
self.assertGreaterEqual(hi, lo)
- # OSX evidently just returns 15 without checking the argument.
- if sys.platform != "darwin":
+ # Apple plaforms return 15 without checking the argument.
+ if not is_apple:
self.assertRaises(OSError, posix.sched_get_priority_min, -23)
self.assertRaises(OSError, posix.sched_get_priority_max, -23)
@@ -2028,11 +2029,13 @@ class _PosixSpawnMixin:
@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
+@support.requires_subprocess()
class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin):
spawn_func = getattr(posix, 'posix_spawn', None)
@unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp")
+@support.requires_subprocess()
class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
spawn_func = getattr(posix, 'posix_spawnp', None)
diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py
index 51e3a46..3f2bac0 100644
--- a/Lib/test/test_pty.py
+++ b/Lib/test/test_pty.py
@@ -1,12 +1,17 @@
-from test.support import verbose, reap_children
-from test.support.os_helper import TESTFN, unlink
+import sys
+import unittest
+from test.support import (
+ is_apple_mobile, is_emscripten, is_wasi, reap_children, verbose
+)
from test.support.import_helper import import_module
+from test.support.os_helper import TESTFN, unlink
-# Skip these tests if termios or fcntl are not available
+# Skip these tests if termios is not available
import_module('termios')
-# fcntl is a proxy for not being one of the wasm32 platforms even though we
-# don't use this module... a proper check for what crashes those is needed.
-import_module("fcntl")
+
+# Skip tests on WASM platforms, plus iOS/tvOS/watchOS
+if is_apple_mobile or is_emscripten or is_wasi:
+ raise unittest.SkipTest(f"pty tests not required on {sys.platform}")
import errno
import os
@@ -17,7 +22,6 @@ import select
import signal
import socket
import io # readline
-import unittest
import warnings
TEST_STRING_1 = b"I wish to buy a fish license.\n"
diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py
index 677349c..6437755 100644
--- a/Lib/test/test_selectors.py
+++ b/Lib/test/test_selectors.py
@@ -6,8 +6,7 @@ import signal
import socket
import sys
from test import support
-from test.support import os_helper
-from test.support import socket_helper
+from test.support import is_apple, os_helper, socket_helper
from time import sleep
import unittest
import unittest.mock
@@ -526,7 +525,7 @@ class ScalableSelectorMixIn:
try:
fds = s.select()
except OSError as e:
- if e.errno == errno.EINVAL and sys.platform == 'darwin':
+ if e.errno == errno.EINVAL and is_apple:
# unexplainable errors on macOS don't need to fail the test
self.skipTest("Invalid argument error calling poll()")
raise
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 8edd75e..d96dad4 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -2148,6 +2148,7 @@ class TestMisc(BaseTest, unittest.TestCase):
check_chown(dirname, uid, gid)
+@support.requires_subprocess()
class TestWhich(BaseTest, unittest.TestCase):
def setUp(self):
@@ -3181,6 +3182,7 @@ class TestGetTerminalSize(unittest.TestCase):
self.assertGreaterEqual(size.lines, 0)
@unittest.skipUnless(os.isatty(sys.__stdout__.fileno()), "not on tty")
+ @support.requires_subprocess()
@unittest.skipUnless(hasattr(os, 'get_terminal_size'),
'need os.get_terminal_size()')
def test_stty_match(self):
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index 637a0ca..61fb047 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -13,9 +13,10 @@ import threading
import time
import unittest
from test import support
-from test.support import os_helper
+from test.support import (
+ is_apple, is_apple_mobile, os_helper, threading_helper
+)
from test.support.script_helper import assert_python_ok, spawn_python
-from test.support import threading_helper
try:
import _testcapi
except ImportError:
@@ -832,7 +833,7 @@ class ItimerTest(unittest.TestCase):
self.assertEqual(self.hndl_called, True)
# Issue 3864, unknown if this affects earlier versions of freebsd also
- @unittest.skipIf(sys.platform in ('netbsd5',),
+ @unittest.skipIf(sys.platform in ('netbsd5',) or is_apple_mobile,
'itimer not reliable (does not mix well with threading) on some BSDs.')
def test_itimer_virtual(self):
self.itimer = signal.ITIMER_VIRTUAL
@@ -1344,7 +1345,7 @@ class StressTest(unittest.TestCase):
# Python handler
self.assertEqual(len(sigs), N, "Some signals were lost")
- @unittest.skipIf(sys.platform == "darwin", "crashes due to system bug (FB13453490)")
+ @unittest.skipIf(is_apple, "crashes due to system bug (FB13453490)")
@unittest.skipUnless(hasattr(signal, "SIGUSR1"),
"test needs SIGUSR1")
@threading_helper.requires_working_threading()
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 231448c..1796423 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -1,9 +1,8 @@
import unittest
from test import support
-from test.support import os_helper
-from test.support import socket_helper
-from test.support import threading_helper
-from test.support import refleak_helper
+from test.support import (
+ is_apple, os_helper, refleak_helper, socket_helper, threading_helper
+)
import _thread as thread
import array
@@ -1196,8 +1195,11 @@ class GeneralModuleTests(unittest.TestCase):
# Find one service that exists, then check all the related interfaces.
# I've ordered this by protocols that have both a tcp and udp
# protocol, at least for modern Linuxes.
- if (sys.platform.startswith(('freebsd', 'netbsd', 'gnukfreebsd'))
- or sys.platform in ('linux', 'darwin')):
+ if (
+ sys.platform.startswith(('freebsd', 'netbsd', 'gnukfreebsd'))
+ or sys.platform == 'linux'
+ or is_apple
+ ):
# avoid the 'echo' service on this platform, as there is an
# assumption breaking non-standard port/protocol entry
services = ('daytime', 'qotd', 'domain')
@@ -3708,7 +3710,7 @@ class SCMRightsTest(SendrecvmsgServerTimeoutBase):
def _testFDPassCMSG_LEN(self):
self.createAndSendFDs(1)
- @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958")
+ @unittest.skipIf(is_apple, "skipping, see issue #12958")
@unittest.skipIf(AIX, "skipping, see issue #22397")
@requireAttrs(socket, "CMSG_SPACE")
def testFDPassSeparate(self):
@@ -3719,7 +3721,7 @@ class SCMRightsTest(SendrecvmsgServerTimeoutBase):
maxcmsgs=2)
@testFDPassSeparate.client_skip
- @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958")
+ @unittest.skipIf(is_apple, "skipping, see issue #12958")
@unittest.skipIf(AIX, "skipping, see issue #22397")
def _testFDPassSeparate(self):
fd0, fd1 = self.newFDs(2)
@@ -3732,7 +3734,7 @@ class SCMRightsTest(SendrecvmsgServerTimeoutBase):
array.array("i", [fd1]))]),
len(MSG))
- @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958")
+ @unittest.skipIf(is_apple, "skipping, see issue #12958")
@unittest.skipIf(AIX, "skipping, see issue #22397")
@requireAttrs(socket, "CMSG_SPACE")
def testFDPassSeparateMinSpace(self):
@@ -3746,7 +3748,7 @@ class SCMRightsTest(SendrecvmsgServerTimeoutBase):
maxcmsgs=2, ignoreflags=socket.MSG_CTRUNC)
@testFDPassSeparateMinSpace.client_skip
- @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #12958")
+ @unittest.skipIf(is_apple, "skipping, see issue #12958")
@unittest.skipIf(AIX, "skipping, see issue #22397")
def _testFDPassSeparateMinSpace(self):
fd0, fd1 = self.newFDs(2)
@@ -3770,7 +3772,7 @@ class SCMRightsTest(SendrecvmsgServerTimeoutBase):
nbytes = self.sendmsgToServer([msg])
self.assertEqual(nbytes, len(msg))
- @unittest.skipIf(sys.platform == "darwin", "see issue #24725")
+ @unittest.skipIf(is_apple, "skipping, see issue #12958")
def testFDPassEmpty(self):
# Try to pass an empty FD array. Can receive either no array
# or an empty array.
diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py
index f3efe0f..5882724 100644
--- a/Lib/test/test_sqlite3/test_dbapi.py
+++ b/Lib/test/test_sqlite3/test_dbapi.py
@@ -31,7 +31,7 @@ import urllib.parse
from test.support import (
SHORT_TIMEOUT, check_disallow_instantiation, requires_subprocess,
- is_emscripten, is_wasi
+ is_apple, is_emscripten, is_wasi
)
from test.support import gc_collect
from test.support import threading_helper
@@ -667,7 +667,7 @@ class OpenTests(unittest.TestCase):
cx.execute(self._sql)
@unittest.skipIf(sys.platform == "win32", "skipped on Windows")
- @unittest.skipIf(sys.platform == "darwin", "skipped on macOS")
+ @unittest.skipIf(is_apple, "skipped on Apple platforms")
@unittest.skipIf(is_emscripten or is_wasi, "not supported on Emscripten/WASI")
@unittest.skipUnless(TESTFN_UNDECODABLE, "only works if there are undecodable paths")
def test_open_with_undecodable_path(self):
@@ -713,7 +713,7 @@ class OpenTests(unittest.TestCase):
cx.execute(self._sql)
@unittest.skipIf(sys.platform == "win32", "skipped on Windows")
- @unittest.skipIf(sys.platform == "darwin", "skipped on macOS")
+ @unittest.skipIf(is_apple, "skipped on Apple platforms")
@unittest.skipIf(is_emscripten or is_wasi, "not supported on Emscripten/WASI")
@unittest.skipUnless(TESTFN_UNDECODABLE, "only works if there are undecodable paths")
def test_open_undecodable_uri(self):
diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py
index d6b6dd6..49013a4 100644
--- a/Lib/test/test_stat.py
+++ b/Lib/test/test_stat.py
@@ -2,8 +2,7 @@ import unittest
import os
import socket
import sys
-from test.support import os_helper
-from test.support import socket_helper
+from test.support import is_apple, os_helper, socket_helper
from test.support.import_helper import import_fresh_module
from test.support.os_helper import TESTFN
@@ -247,7 +246,7 @@ class TestFilemode:
for flag in self.file_flags:
if flag.startswith("UF"):
self.assertTrue(getattr(self.statmod, flag) & self.statmod.UF_SETTABLE, f"{flag} not in UF_SETTABLE")
- elif sys.platform == 'darwin' and self.statmod is c_stat and flag == 'SF_DATALESS':
+ elif is_apple and self.statmod is c_stat and flag == 'SF_DATALESS':
self.assertTrue(self.statmod.SF_DATALESS & self.statmod.SF_SYNTHETIC, "SF_DATALESS not in SF_SYNTHETIC")
self.assertFalse(self.statmod.SF_DATALESS & self.statmod.SF_SETTABLE, "SF_DATALESS in SF_SETTABLE")
else:
diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py
index ae6e192..125f402 100644
--- a/Lib/test/test_sys_settrace.py
+++ b/Lib/test/test_sys_settrace.py
@@ -7,7 +7,7 @@ import difflib
import gc
from functools import wraps
import asyncio
-from test.support import import_helper
+from test.support import import_helper, requires_subprocess
import contextlib
import os
import tempfile
@@ -1810,6 +1810,7 @@ class TraceOpcodesTestCase(TraceTestCase):
def make_tracer():
return Tracer(trace_opcode_events=True)
+ @requires_subprocess()
def test_trace_opcodes_after_settrace(self):
"""Make sure setting f_trace_opcodes after starting trace works even
if it's the first time f_trace_opcodes is being set. GH-103615"""
diff --git a/Lib/test/test_unicode_file_functions.py b/Lib/test/test_unicode_file_functions.py
index 47619c8..25c16e3 100644
--- a/Lib/test/test_unicode_file_functions.py
+++ b/Lib/test/test_unicode_file_functions.py
@@ -5,7 +5,7 @@ import sys
import unittest
import warnings
from unicodedata import normalize
-from test.support import os_helper
+from test.support import is_apple, os_helper
from test import support
@@ -23,13 +23,13 @@ filenames = [
'10_\u1fee\u1ffd',
]
-# Mac OS X decomposes Unicode names, using Normal Form D.
+# Apple platforms decompose Unicode names, using Normal Form D.
# http://developer.apple.com/mac/library/qa/qa2001/qa1173.html
# "However, most volume formats do not follow the exact specification for
# these normal forms. For example, HFS Plus uses a variant of Normal Form D
# in which U+2000 through U+2FFF, U+F900 through U+FAFF, and U+2F800 through
# U+2FAFF are not decomposed."
-if sys.platform != 'darwin':
+if not is_apple:
filenames.extend([
# Specific code points: NFC(fn), NFD(fn), NFKC(fn) and NFKD(fn) all different
'11_\u0385\u03d3\u03d4',
@@ -119,11 +119,11 @@ class UnicodeFileTests(unittest.TestCase):
os.stat(name)
self._apply_failure(os.listdir, name, self._listdir_failure)
- # Skip the test on darwin, because darwin does normalize the filename to
+ # Skip the test on Apple platforms, because they don't normalize the filename to
# NFD (a variant of Unicode NFD form). Normalize the filename to NFC, NFKC,
# NFKD in Python is useless, because darwin will normalize it later and so
# open(), os.stat(), etc. don't raise any exception.
- @unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X')
+ @unittest.skipIf(is_apple, 'irrelevant test on Apple platforms')
@unittest.skipIf(
support.is_emscripten or support.is_wasi,
"test fails on Emscripten/WASI when host platform is macOS."
@@ -142,10 +142,10 @@ class UnicodeFileTests(unittest.TestCase):
self._apply_failure(os.remove, name)
self._apply_failure(os.listdir, name)
- # Skip the test on darwin, because darwin uses a normalization different
+ # Skip the test on Apple platforms, because they use a normalization different
# than Python NFD normalization: filenames are different even if we use
# Python NFD normalization.
- @unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X')
+ @unittest.skipIf(is_apple, 'irrelevant test on Apple platforms')
def test_listdir(self):
sf0 = set(self.files)
with warnings.catch_warnings():
diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py
index 99c9e24..fa528a6 100644
--- a/Lib/test/test_urllib2.py
+++ b/Lib/test/test_urllib2.py
@@ -1,6 +1,7 @@
import unittest
from test import support
from test.support import os_helper
+from test.support import requires_subprocess
from test.support import warnings_helper
from test import test_urllib
from unittest import mock
@@ -998,6 +999,7 @@ class HandlerTests(unittest.TestCase):
file_obj.close()
+ @requires_subprocess()
def test_http_body_pipe(self):
# A file reading from a pipe.
# A pipe cannot be seek'ed. There is no way to determine the
diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py
index 6dda00e..ba31beb 100644
--- a/Lib/test/test_venv.py
+++ b/Lib/test/test_venv.py
@@ -19,8 +19,8 @@ import sysconfig
import tempfile
from test.support import (captured_stdout, captured_stderr,
skip_if_broken_multiprocessing_synchronize, verbose,
- requires_subprocess, is_emscripten, is_wasi,
- requires_venv_with_pip, TEST_HOME_DIR,
+ requires_subprocess, is_apple_mobile, is_emscripten,
+ is_wasi, requires_venv_with_pip, TEST_HOME_DIR,
requires_resource, copy_python_src_ignore)
from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree)
import unittest
@@ -39,8 +39,10 @@ requireVenvCreate = unittest.skipUnless(
or sys._base_executable != sys.executable,
'cannot run venv.create from within a venv on this platform')
-if is_emscripten or is_wasi:
- raise unittest.SkipTest("venv is not available on Emscripten/WASI.")
+# Skip tests on WASM platforms, plus iOS/tvOS/watchOS
+if is_apple_mobile or is_emscripten or is_wasi:
+ raise unittest.SkipTest(f"venv tests not required on {sys.platform}")
+
@requires_subprocess()
def check_output(cmd, encoding=None):
diff --git a/Misc/NEWS.d/next/Tests/2024-02-02-13-18-55.gh-issue-114099.C_ycWg.rst b/Misc/NEWS.d/next/Tests/2024-02-02-13-18-55.gh-issue-114099.C_ycWg.rst
new file mode 100644
index 0000000..487cd50
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2024-02-02-13-18-55.gh-issue-114099.C_ycWg.rst
@@ -0,0 +1 @@
+Added test exclusions required to run the test suite on iOS.