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.
This commit is contained in:
Russell Keith-Magee 2024-02-05 08:04:57 +08:00 committed by GitHub
parent 15f6f048a6
commit 391659b3da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 224 additions and 150 deletions

View file

@ -43,7 +43,7 @@
"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 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'):
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 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'):
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

View file

@ -22,8 +22,8 @@
# 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 @@
'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())

View file

@ -1815,6 +1815,7 @@ def check_killed(self, returncode):
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 @@ def test_subprocess_exec(self):
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 @@ def test_subprocess_interactive(self):
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 @@ def test_subprocess_shell(self):
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 @@ def test_subprocess_exitcode(self):
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 @@ def test_subprocess_close_after_finish(self):
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 @@ def test_subprocess_kill(self):
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 @@ def test_subprocess_terminate(self):
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 @@ def test_subprocess_send_signal(self):
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 @@ def test_subprocess_stderr(self):
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 @@ def test_subprocess_stderr_redirect_to_stdout(self):
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 @@ def test_subprocess_close_client_stream(self):
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 @@ def test_subprocess_wait_no_same_group(self):
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 @@ async def connect(**kwds):
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):

View file

@ -10,7 +10,6 @@
import unittest
from unittest import mock
import warnings
from test.support import socket_helper
try:
import ssl
except ImportError:
@ -18,6 +17,7 @@
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 @@ async def client(addr):
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

View file

@ -47,6 +47,7 @@ def _start(self, *args, **kwargs):
self._proc.pid = -1
@support.requires_subprocess()
class SubprocessTransportTests(test_utils.TestCase):
def setUp(self):
super().setUp()
@ -110,6 +111,7 @@ def test_subprocess_repr(self):
transport.close()
@support.requires_subprocess()
class SubprocessMixin:
def test_stdin_stdout(self):

View file

@ -1874,7 +1874,7 @@ async def runner():
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):

View file

@ -14,8 +14,7 @@
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 @@ def test_pep_409_verbiage(self):
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

View file

@ -160,6 +160,7 @@ def setUp(self):
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()"]

View file

@ -6,7 +6,9 @@
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 @@ def get_lockdata():
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 @@ def test_flock(self):
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 @@ def test_lockf_exclusive(self):
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

View file

@ -18,6 +18,7 @@
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 @@ def retr():
@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 @@ def setUp(self, encoding=DEFAULT_ENCODING):
@skipUnless(ssl, "SSL not available")
@requires_subprocess()
class TestTLS_FTPClass(TestCase):
"""Specific TLS_FTP class tests."""

View file

@ -7,9 +7,9 @@
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 @@ def test_abspath_issue3426(self):
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

View file

@ -30,8 +30,9 @@
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 @@ def close_conn():
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 @@ def test_undecodable_filename(self):
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 @@ def test_html_escape_filename(self):
@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.

View file

@ -39,11 +39,9 @@
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 @@ def test_raw_bytes_io(self):
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)

View file

@ -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 @@ def test_recursion_limit(self):
#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

View file

@ -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 @@ def tearDown(self):
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')

View file

@ -3848,6 +3848,7 @@ def test_does_not_crash(self):
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 @@ def test_posix_pty_functions(self):
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

View file

@ -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

View file

@ -472,7 +472,8 @@ def test_macos(self):
'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

View file

@ -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 @@ def check_stat(uid, gid):
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 @@ def test_sched_priority(self):
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 @@ def test_dup2(self):
@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)

View file

@ -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 signal
import socket
import io # readline
import unittest
import warnings
TEST_STRING_1 = b"I wish to buy a fish license.\n"

View file

@ -6,8 +6,7 @@
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 @@ def test_above_fd_setsize(self):
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

View file

@ -2148,6 +2148,7 @@ def check_chown(path, uid=None, gid=None):
check_chown(dirname, uid, gid)
@support.requires_subprocess()
class TestWhich(BaseTest, unittest.TestCase):
def setUp(self):
@ -3181,6 +3182,7 @@ def test_bad_environ(self):
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):

View file

@ -13,9 +13,10 @@
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 @@ def test_itimer_real(self):
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 @@ def handler(signum, frame):
# 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()

View file

@ -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 @@ def testGetServBy(self):
# 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 @@ def testFDPassCMSG_LEN(self):
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 @@ def testFDPassSeparate(self):
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 @@ def _testFDPassSeparate(self):
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 @@ def testFDPassSeparateMinSpace(self):
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 @@ def sendAncillaryIfPossible(self, msg, ancdata):
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.

View file

@ -31,7 +31,7 @@
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 @@ def test_open_with_path_like_object(self):
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 @@ def test_open_uri_readonly(self):
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):

View file

@ -2,8 +2,7 @@
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 @@ def test_flags_consistent(self):
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:

View file

@ -7,7 +7,7 @@
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 @@ def compare_events(self, line_offset, events, expected_events):
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"""

View file

@ -5,7 +5,7 @@
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 @@
'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 @@ def test_open(self):
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 @@ def test_normalize(self):
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():

View file

@ -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 @@ def test_http_body_fileobj(self):
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

View file

@ -19,8 +19,8 @@
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 @@
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):

View file

@ -0,0 +1 @@
Added test exclusions required to run the test suite on iOS.