Skip to content

bpo-40280: Skip subprocess-based tests on wasm32-emscripten (GH-30615) #30615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Lib/distutils/tests/test_build_clib.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import sys
import sysconfig

from test.support import run_unittest, missing_compiler_executable
from test.support import (
run_unittest, missing_compiler_executable, requires_subprocess
)

from distutils.command.build_clib import build_clib
from distutils.errors import DistutilsSetupError
Expand Down Expand Up @@ -112,6 +114,7 @@ def test_finalize_options(self):
self.assertRaises(DistutilsSetupError, cmd.finalize_options)

@unittest.skipIf(sys.platform == 'win32', "can't test on Windows")
@requires_subprocess()
def test_run(self):
pkg_dir, dist = self.create_dist()
cmd = build_clib(dist)
Expand Down
2 changes: 2 additions & 0 deletions Lib/distutils/tests/test_build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def tearDown(self):
def build_ext(self, *args, **kwargs):
return build_ext(*args, **kwargs)

@support.requires_subprocess()
def test_build_ext(self):
cmd = support.missing_compiler_executable()
if cmd is not None:
Expand Down Expand Up @@ -332,6 +333,7 @@ def test_compiler_option(self):
cmd.run()
self.assertEqual(cmd.compiler, 'unix')

@support.requires_subprocess()
def test_get_outputs(self):
cmd = support.missing_compiler_executable()
if cmd is not None:
Expand Down
4 changes: 3 additions & 1 deletion Lib/distutils/tests/test_build_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from distutils.errors import DistutilsFileError

from distutils.tests import support
from test.support import run_unittest
from test.support import run_unittest, requires_subprocess


class BuildPyTestCase(support.TempdirManager,
Expand Down Expand Up @@ -89,6 +89,7 @@ def test_empty_package_dir(self):
self.fail("failed package_data test when package_dir is ''")

@unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled')
@requires_subprocess()
def test_byte_compile(self):
project_dir, dist = self.create_dist(py_modules=['boiledeggs'])
os.chdir(project_dir)
Expand All @@ -106,6 +107,7 @@ def test_byte_compile(self):
['boiledeggs.%s.pyc' % sys.implementation.cache_tag])

@unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled')
@requires_subprocess()
def test_byte_compile_optimized(self):
project_dir, dist = self.create_dist(py_modules=['boiledeggs'])
os.chdir(project_dir)
Expand Down
5 changes: 4 additions & 1 deletion Lib/distutils/tests/test_config_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import os
import sys
import sysconfig
from test.support import run_unittest, missing_compiler_executable
from test.support import (
run_unittest, missing_compiler_executable, requires_subprocess
)

from distutils.command.config import dump_file, config
from distutils.tests import support
Expand Down Expand Up @@ -42,6 +44,7 @@ def test_dump_file(self):
self.assertEqual(len(self._logs), numlines+1)

@unittest.skipIf(sys.platform == 'win32', "can't test on Windows")
@requires_subprocess()
def test_search_cpp(self):
cmd = missing_compiler_executable(['preprocessor'])
if cmd is not None:
Expand Down
3 changes: 2 additions & 1 deletion Lib/distutils/tests/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import unittest
import site

from test.support import captured_stdout, run_unittest
from test.support import captured_stdout, run_unittest, requires_subprocess

from distutils import sysconfig
from distutils.command.install import install, HAS_USER_SITE
Expand Down Expand Up @@ -208,6 +208,7 @@ def test_record(self):
'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]]
self.assertEqual(found, expected)

@requires_subprocess()
def test_record_extensions(self):
cmd = test_support.missing_compiler_executable()
if cmd is not None:
Expand Down
4 changes: 3 additions & 1 deletion Lib/distutils/tests/test_install_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from distutils.extension import Extension
from distutils.tests import support
from distutils.errors import DistutilsOptionError
from test.support import run_unittest
from test.support import run_unittest, requires_subprocess


class InstallLibTestCase(support.TempdirManager,
Expand All @@ -35,6 +35,7 @@ def test_finalize_options(self):
self.assertEqual(cmd.optimize, 2)

@unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled')
@requires_subprocess()
def test_byte_compile(self):
project_dir, dist = self.create_dist()
os.chdir(project_dir)
Expand Down Expand Up @@ -90,6 +91,7 @@ def test_get_inputs(self):
inputs = cmd.get_inputs()
self.assertEqual(len(inputs), 2, inputs)

@requires_subprocess()
def test_dont_write_bytecode(self):
# makes sure byte_compile is not used
dist = self.create_dist()[1]
Expand Down
4 changes: 3 additions & 1 deletion Lib/distutils/tests/test_spawn.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
import stat
import sys
import unittest.mock
from test.support import run_unittest, unix_shell
from test.support import run_unittest, unix_shell, requires_subprocess
from test.support import os_helper

from distutils.spawn import find_executable
from distutils.spawn import spawn
from distutils.errors import DistutilsExecError
from distutils.tests import support


@requires_subprocess()
class SpawnTestCase(support.TempdirManager,
support.LoggingSilencer,
unittest.TestCase):
Expand Down
3 changes: 2 additions & 1 deletion Lib/distutils/tests/test_sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from distutils import sysconfig
from distutils.ccompiler import get_default_compiler
from distutils.tests import support
from test.support import run_unittest, swap_item
from test.support import run_unittest, swap_item, requires_subprocess
from test.support.os_helper import TESTFN
from test.support.warnings_helper import check_warnings

Expand Down Expand Up @@ -247,6 +247,7 @@ def test_SO_in_vars(self):
self.assertIsNotNone(vars['SO'])
self.assertEqual(vars['SO'], vars['EXT_SUFFIX'])

@requires_subprocess()
def test_customize_compiler_before_get_config_vars(self):
# Issue #21923: test that a Distribution compiler
# instance can be called without an explicit call to
Expand Down
3 changes: 3 additions & 0 deletions Lib/lib2to3/tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ def test_load_grammar_from_pickle(self):
shutil.rmtree(tmpdir)

@unittest.skipIf(sys.executable is None, 'sys.executable required')
@unittest.skipIf(
sys.platform == 'emscripten', 'requires working subprocess'
)
def test_load_grammar_from_subprocess(self):
tmpdir = tempfile.mkdtemp()
tmpsubdir = os.path.join(tmpdir, 'subdir')
Expand Down
17 changes: 13 additions & 4 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@
"bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
"requires_IEEE_754", "requires_zlib",
"has_fork_support", "requires_fork",
"has_subprocess_support", "requires_subprocess",
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
"check__all__", "skip_if_buggy_ucrt_strfptime",
"check_disallow_instantiation",
# sys
"is_jython", "is_android", "is_emscripten",
"is_jython", "is_android", "is_emscripten", "is_wasi",
"check_impl_detail", "unix_shell", "setswitchinterval",
# network
"open_urlresource",
Expand Down Expand Up @@ -467,15 +468,23 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'):
else:
unix_shell = None

# wasm32-emscripten is POSIX-like but does not provide a
# working fork() or subprocess API.
# wasm32-emscripten and -wasi are POSIX-like but do not
# have subprocess or fork support.
is_emscripten = sys.platform == "emscripten"
is_wasi = sys.platform == "wasi"

has_fork_support = hasattr(os, "fork") and not is_emscripten
has_fork_support = hasattr(os, "fork") and not is_emscripten and not is_wasi

def requires_fork():
return unittest.skipUnless(has_fork_support, "requires working os.fork()")

has_subprocess_support = not is_emscripten and not is_wasi

def requires_subprocess():
"""Used for subprocess, os.spawn calls"""
return unittest.skipUnless(has_subprocess_support, "requires subprocess support")


# Define the URL of a dedicated HTTP server for the network tests.
# The URL must use clear-text HTTP: no redirection to encrypted HTTPS.
TEST_HTTP_URL = "http://www.pythontest.net"
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/support/script_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ def interpreter_requires_environment():
if 'PYTHONHOME' in os.environ:
__cached_interp_requires_environment = True
return True
# cannot run subprocess, assume we don't need it
if not support.has_subprocess_support:
__cached_interp_requires_environment = False
return False

# Try running an interpreter with -E to see if it works or not.
try:
Expand Down Expand Up @@ -87,6 +91,7 @@ def fail(self, cmd_line):


# Executing the interpreter in a subprocess
@support.requires_subprocess()
def run_python_until_end(*args, **env_vars):
env_required = interpreter_requires_environment()
cwd = env_vars.pop('__cwd', None)
Expand Down Expand Up @@ -139,6 +144,7 @@ def run_python_until_end(*args, **env_vars):
return _PythonRunResult(rc, out, err), cmd_line


@support.requires_subprocess()
def _assert_python(expected_success, /, *args, **env_vars):
res, cmd_line = run_python_until_end(*args, **env_vars)
if (res.rc and expected_success) or (not res.rc and not expected_success):
Expand Down Expand Up @@ -171,6 +177,7 @@ def assert_python_failure(*args, **env_vars):
return _assert_python(False, *args, **env_vars)


@support.requires_subprocess()
def spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw):
"""Run a Python subprocess with the given arguments.

Expand Down Expand Up @@ -273,6 +280,7 @@ def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
return zip_name, os.path.join(zip_name, script_name_in_zip)


@support.requires_subprocess()
def run_test_script(script):
# use -u to try to get the full output if the test hangs or crash
if support.verbose:
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@


class AuditTest(unittest.TestCase):

@support.requires_subprocess()
def do_test(self, *args):
with subprocess.Popen(
[sys.executable, "-Xutf8", AUDIT_TESTS_PY, *args],
Expand All @@ -29,6 +31,7 @@ def do_test(self, *args):
if p.returncode:
self.fail("".join(p.stderr))

@support.requires_subprocess()
def run_python(self, *args):
events = []
with subprocess.Popen(
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_capi.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def test_instancemethod(self):
self.assertEqual(testfunction.attribute, "test")
self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")

@support.requires_subprocess()
def test_no_FatalError_infinite_loop(self):
with support.SuppressCrashReport():
p = subprocess.Popen([sys.executable, "-c",
Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_cmd_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
interpreter_requires_environment
)

if not support.has_subprocess_support:
raise unittest.SkipTest("test module requires subprocess")

# Debug build?
Py_DEBUG = hasattr(sys, "gettotalrefcount")
Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import tempfile
import textwrap

if not support.has_subprocess_support:
raise unittest.SkipTest("test module requires subprocess")

MS_WINDOWS = (os.name == 'nt')
MACOS = (sys.platform == 'darwin')
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_faulthandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ def test_is_enabled(self):
finally:
sys.stderr = orig_stderr

@support.requires_subprocess()
def test_disabled_by_default(self):
# By default, the module should be disabled
code = "import faulthandler; print(faulthandler.is_enabled())"
Expand All @@ -420,6 +421,7 @@ def test_disabled_by_default(self):
output = subprocess.check_output(args)
self.assertEqual(output.rstrip(), b"False")

@support.requires_subprocess()
def test_sys_xoptions(self):
# Test python -X faulthandler
code = "import faulthandler; print(faulthandler.is_enabled())"
Expand All @@ -432,6 +434,7 @@ def test_sys_xoptions(self):
output = subprocess.check_output(args, env=env)
self.assertEqual(output.rstrip(), b"True")

@support.requires_subprocess()
def test_env_var(self):
# empty env var
code = "import faulthandler; print(faulthandler.is_enabled())"
Expand Down
5 changes: 4 additions & 1 deletion Lib/test/test_file_eintr.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
import sys
import time
import unittest
from test import support

if not support.has_subprocess_support:
raise unittest.SkipTest("test module requires subprocess")

# Test import all of the things we're about to try testing up front.
import _io
import _pyio


@unittest.skipUnless(os.name == 'posix', 'tests requires a posix system.')
class TestFileIOSignalInterrupt:
def setUp(self):
Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_gc.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import unittest
import unittest.mock
from test.support import (verbose, refcount_test,
cpython_only)
cpython_only, requires_subprocess)
from test.support.import_helper import import_module
from test.support.os_helper import temp_dir, TESTFN, unlink
from test.support.script_helper import assert_python_ok, make_script
Expand Down Expand Up @@ -661,6 +661,7 @@ def do_work():
gc.collect() # this blows up (bad C pointer) when it fails

@cpython_only
@requires_subprocess()
def test_garbage_at_shutdown(self):
import subprocess
code = """if 1:
Expand Down
4 changes: 3 additions & 1 deletion Lib/test/test_gzip.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from subprocess import PIPE, Popen
from test.support import import_helper
from test.support import os_helper
from test.support import _4G, bigmemtest
from test.support import _4G, bigmemtest, requires_subprocess
from test.support.script_helper import assert_python_ok, assert_python_failure

gzip = import_helper.import_module('gzip')
Expand Down Expand Up @@ -760,6 +760,7 @@ def wrapper(*args, **kwargs):
class TestCommandLine(unittest.TestCase):
data = b'This is a simple test with gzip'

@requires_subprocess()
def test_decompress_stdin_stdout(self):
with io.BytesIO() as bytes_io:
with gzip.GzipFile(fileobj=bytes_io, mode='wb') as gzip_file:
Expand Down Expand Up @@ -795,6 +796,7 @@ def test_decompress_infile_outfile_error(self):
self.assertEqual(rc, 1)
self.assertEqual(out, b'')

@requires_subprocess()
@create_and_remove_directory(TEMPDIR)
def test_compress_stdin_outfile(self):
args = sys.executable, '-m', 'gzip'
Expand Down
Loading