diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_shutdown.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_shutdown.py index 9270af5914..68855dfe2e 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_shutdown.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_shutdown.py @@ -47,7 +47,6 @@ import sys from unittest import skipIf from tests import compile_module_from_string -from tests.util import skip_if_sandboxed GRAALPY = sys.implementation.name == 'graalpy' @@ -77,7 +76,6 @@ def test_sigterm(): assert proc.wait() in [-signal.SIGTERM, 128 + signal.SIGTERM] -@skip_if_sandboxed("Needs native extension support in sandboxed runs") @skipIf(not GRAALPY, "GraalPy-only native weakref shutdown test") def test_native_weakref_shutdown_skips_c_retained_object(): module = compile_module_from_string(textwrap.dedent(""" diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_standalone.py b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_standalone.py index 6b51f714dd..1ed2b27f52 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_standalone.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_standalone.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -38,6 +38,7 @@ # SOFTWARE. import os +import sys import tempfile import unittest @@ -69,6 +70,9 @@ def create_test_env(): env["PIP_CONSTRAINT"] = constraints_file return env +def append_env_flag(env, key, flag): + env[key] = (env.get(key, "") + " " + flag).strip() + @unittest.skipUnless(is_enabled, "ENABLE_STANDALONE_UNITTESTS is not true") def test_native_executable_one_file(): graalpy = util.get_gp() @@ -124,7 +128,10 @@ def test_native_executable_venv_and_one_file(): venv_python = os.path.join(venv_dir, "Scripts", "python.exe") if os.name == "nt" else os.path.join(venv_dir, "bin", "python") cmd = [venv_python, "-m", "pip", "install", "termcolor", "ujson"] - _, return_code = util.run_cmd(cmd, env, logger=log) + pip_env = env.copy() + if sys.platform == "darwin": + append_env_flag(pip_env, "CXXFLAGS", "-std=c++11") + _, return_code = util.run_cmd(cmd, pip_env, logger=log) assert return_code == 0, log target_file = os.path.join(target_dir, "hello") diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_call-classmethod.py b/graalpython/com.oracle.graal.python.test/src/tests/test_call-classmethod.py index 2bf5e689eb..633b298375 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_call-classmethod.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_call-classmethod.py @@ -23,6 +23,9 @@ # OF THE POSSIBILITY OF SUCH DAMAGE. # classmethod calls +from tests.util import needs_capi + + class Strength(object): def __init__(self, strength, name): @@ -171,6 +174,7 @@ class Child(Parent): assert Parent.__subclasses__() == [] +@needs_capi def test_cext_classmethod_descriptor(): from _ctypes import _SimpleCData diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_ctypes.py b/graalpython/com.oracle.graal.python.test/src/tests/test_ctypes.py index ff44710f02..d81c6446dc 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_ctypes.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_ctypes.py @@ -46,7 +46,6 @@ from pathlib import Path from tests.testlib_helper import build_testlib -from tests.util import skip_if_sandboxed class TestCtypesInterop(unittest.TestCase): @@ -75,7 +74,6 @@ def run_in_subprocess(self, code, *args): ) ) - @skip_if_sandboxed("Needs native extension support for ctypes in sandboxed runs") def test_ctypes_load_and_call(self): # Pass the library path as an argument code = textwrap.dedent( @@ -93,7 +91,6 @@ def test_ctypes_load_and_call(self): self.run_in_subprocess(code, str(self.lib_path)) @unittest.skipIf(sys.platform != "win32", "Windows-only test") - @skip_if_sandboxed("Needs native extension support for ctypes in sandboxed runs") def test_os_add_dll_directory_and_unload(self): # Pass the library dir as argument code = textwrap.dedent( diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_entropy_subprocess.py b/graalpython/com.oracle.graal.python.test/src/tests/test_entropy_subprocess.py index 9432922a45..0016e3b083 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_entropy_subprocess.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_entropy_subprocess.py @@ -45,7 +45,7 @@ import threading import unittest -from tests.util import skip_if_sandboxed +from tests.util import needs_capi @unittest.skipUnless(sys.implementation.name == "graalpy" and sys.platform.startswith("linux"), "Linux GraalPy-specific test") @@ -279,7 +279,7 @@ def test_pyexpat_parsercreate_does_not_use_additional_initrandom(self): "xmlparser", ) - @skip_if_sandboxed("Needs native extension support for sqlite3 in sandboxed runs") + @needs_capi def test_sqlite3_import_does_not_use_additional_initrandom(self): self.assert_initrandom_bytes_used( self.HASH_SECRET_BYTES, @@ -287,7 +287,7 @@ def test_sqlite3_import_does_not_use_additional_initrandom(self): "_sqlite3", ) - @skip_if_sandboxed("Needs native extension support for sqlite3 in sandboxed runs") + @needs_capi def test_sqlite3_randomblob_does_not_use_initrandom(self): self.assert_initrandom_bytes_used( self.HASH_SECRET_BYTES, diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_indirect_call.py b/graalpython/com.oracle.graal.python.test/src/tests/test_indirect_call.py index b0ae60ae95..052067ec3d 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_indirect_call.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_indirect_call.py @@ -40,6 +40,7 @@ import os from tests.cpyext import CPyExtTestCase, CPyExtType +from tests.util import has_capi, needs_capi # synchronize with Java implementation of __graalpython__.indirect_call_tester TYPE_INDIRECT_BOUNDARY = 1 @@ -70,15 +71,18 @@ def was_stack_walk(new_value): return False -IndirectCApiCallTester = CPyExtType( - 'IndirectCApiCallTester', - code=''' - static PyObject* IndirectCApiCallTester_call(PyObject* self, PyObject *callable) { - return PyObject_CallNoArgs(callable); - } - ''', - tp_methods='''{"call", (PyCFunction)IndirectCApiCallTester_call, METH_O, ""}''', -) +if has_capi(): + IndirectCApiCallTester = CPyExtType( + 'IndirectCApiCallTester', + code=''' + static PyObject* IndirectCApiCallTester_call(PyObject* self, PyObject *callable) { + return PyObject_CallNoArgs(callable); + } + ''', + tp_methods='''{"call", (PyCFunction)IndirectCApiCallTester_call, METH_O, ""}''', + ) +else: + IndirectCApiCallTester = None # === capturing frame @@ -96,6 +100,7 @@ def fun(x): stack_walks += was_stack_walk(False) assert stack_walks <= ALLOWED_NUM_STACK_WALKS, f"Too many stack walks recorded: {stack_walks}" +@needs_capi def test_capi_get_frame(): check_get_frame_no_deopt(IndirectCApiCallTester().call) @@ -174,6 +179,7 @@ def check_ex(msg): stack_walks += was_stack_walk(False) assert stack_walks <= ALLOWED_NUM_STACK_WALKS, f"Too many stack walks recorded: {stack_walks}" +@needs_capi def test_capi_get_ex(): check_get_ex_no_deopt(IndirectCApiCallTester().call) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_sqlite3.py b/graalpython/com.oracle.graal.python.test/src/tests/test_sqlite3.py index 21ae70d3bb..c4614bce56 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_sqlite3.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_sqlite3.py @@ -37,10 +37,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from tests.util import skip_if_sandboxed +from tests.util import needs_capi -@skip_if_sandboxed("Needs native extension support for sqlite3 in sandboxed runs") +@needs_capi def test_basic_functionality(): """ This is a basic test to ensure that the module can be imported. @@ -55,7 +55,7 @@ def test_basic_functionality(): conn.close() -@skip_if_sandboxed("Needs native extension support for sqlite3 in sandboxed runs") +@needs_capi def test_fts5_works(): # we explicitly enable those features below, but on CPython they might not # be available if using some system libsqlite that doesn't have them diff --git a/graalpython/com.oracle.graal.python.test/src/tests/util.py b/graalpython/com.oracle.graal.python.test/src/tests/util.py index f47e5efbcb..2a3824fb21 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/util.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/util.py @@ -59,6 +59,21 @@ def wrapper(test): return wrapper +def _jdk_major_version(): + version = __graalpython__.get_jdk_version() + return int(version.split(".", 1)[0].split("-", 1)[0]) + + +def has_capi(): + return not (sys.implementation.name == 'graalpy' and _jdk_major_version() < 25) + + +def needs_capi(test): + if not has_capi(): + return unittest.skip("Needs C API support on JDK 25 or newer")(test) + return test + + def skipIfBytecodeDSL(reason=''): def wrapper(test): if IS_BYTECODE_DSL: diff --git a/graalpython/lib-python/3/test/_test_multiprocessing.py b/graalpython/lib-python/3/test/_test_multiprocessing.py index 2903cb25b5..625454b371 100644 --- a/graalpython/lib-python/3/test/_test_multiprocessing.py +++ b/graalpython/lib-python/3/test/_test_multiprocessing.py @@ -3221,7 +3221,8 @@ def test_mymanager(self): # bpo-30356: BaseManager._finalize_manager() sends SIGTERM # to the manager process if it takes longer than 1 second to stop, # which happens on slow buildbots. - self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM)) + # GraalPy change: JVM exits with 143 on SIGTERM + self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM, 128 + signal.SIGTERM)) def test_mymanager_context(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) @@ -3230,7 +3231,8 @@ def test_mymanager_context(self): # bpo-30356: BaseManager._finalize_manager() sends SIGTERM # to the manager process if it takes longer than 1 second to stop, # which happens on slow buildbots. - self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM)) + # GraalPy change: JVM exits with 143 on SIGTERM + self.assertIn(manager._process.exitcode, (0, -signal.SIGTERM, 128 + signal.SIGTERM)) def test_mymanager_context_prestarted(self): manager = MyManager(shutdown_timeout=SHUTDOWN_TIMEOUT) diff --git a/mx.graalpython/mx_graalpython.py b/mx.graalpython/mx_graalpython.py index 8392bc9d86..d7d862f354 100644 --- a/mx.graalpython/mx_graalpython.py +++ b/mx.graalpython/mx_graalpython.py @@ -1399,8 +1399,8 @@ def run_sandboxed_tests(python_binary, report, args=None, **kwargs): # C API doesn't work on JDK 21 exclude += [ "cpyext", + "test_ctypes", "test_ctypes_callbacks", - "test_indirect_call", ] env = dict(kwargs.pop("env", os.environ.copy()) or {}) propagated_args = [