diff --git a/ci.jsonnet b/ci.jsonnet
index 48bf915fd3..f3fbf47e80 100644
--- a/ci.jsonnet
+++ b/ci.jsonnet
@@ -1 +1 @@
-{ "overlay": "840dea7f9575e2e96e2143685751932513fd0c78" }
+{ "overlay": "ea6007b968048485d43905914816208f870ac88b" }
diff --git a/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c b/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c
index 42699b743a..852906637e 100644
--- a/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c
+++ b/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018, 2024, Oracle and/or its affiliates.
+/* Copyright (c) 2018, 2025, Oracle and/or its affiliates.
* Copyright (C) 1996-2020 Python Software Foundation
*
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -6220,16 +6220,17 @@ _PyUnicode_DecodeRawUnicodeEscapeStateful(const char *s,
Py_XDECREF(exc);
return NULL;
}
-
+#endif // GraalPy change
PyObject *
PyUnicode_DecodeRawUnicodeEscape(const char *s,
Py_ssize_t size,
const char *errors)
{
- return _PyUnicode_DecodeRawUnicodeEscapeStateful(s, size, errors, NULL);
+ return PyUnicode_Decode(s, size, "raw_unicode_escape", errors);
+ // return _PyUnicode_DecodeRawUnicodeEscapeStateful(s, size, errors, NULL);
}
-
+#if 0 // GraalPy change
PyObject *
PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)
{
diff --git a/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java b/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java
index f7838f7d5e..f0a6328d1f 100644
--- a/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java
+++ b/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java
@@ -843,6 +843,8 @@ protected void launch(Builder contextBuilder) {
} catch (PolyglotException e) {
if (e.isExit()) {
rc = e.getExitStatus();
+ } else {
+ throw e;
}
} catch (NoSuchFileException e) {
printFileNotFoundException(e);
diff --git a/graalpython/com.oracle.graal.python.test.integration/pom.xml b/graalpython/com.oracle.graal.python.test.integration/pom.xml
index bad3f27502..6251cedd21 100644
--- a/graalpython/com.oracle.graal.python.test.integration/pom.xml
+++ b/graalpython/com.oracle.graal.python.test.integration/pom.xml
@@ -64,7 +64,7 @@ Additionally, one can change the polyglot artifacts version with
17
17
UTF-8
- 25.0.0
+ 24.2.1
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle b/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle
index c9b31ffe75..2dfdd3f5ce 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle
+++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle
@@ -1,6 +1,6 @@
plugins {
id "application"
- id 'org.graalvm.python' version '25.0.0'
+ id 'org.graalvm.python' version '24.2.1'
id "org.graalvm.buildtools.native" version "0.10.2"
}
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle.kts b/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle.kts
index ee72dfe3de..8ccf16421d 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle.kts
+++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle.kts
@@ -1,6 +1,6 @@
plugins {
application
- id("org.graalvm.python") version "25.0.0"
+ id("org.graalvm.python") version "24.2.1"
id("org.graalvm.buildtools.native") version "0.10.2"
}
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPIPComments.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPIPComments.j
index 098695dccb..08561a0c15 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPIPComments.j
+++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPIPComments.j
@@ -1,6 +1,6 @@
///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:25.0.0}
+//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1}
//PIP
// one blank after PIP
//PIP
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceComment.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceComment.j
index 89f5758c5e..31330e96fd 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceComment.j
+++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceComment.j
@@ -1,6 +1,6 @@
///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:25.0.0}
+//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1}
//PYTHON_RESOURCES_DIRECTORY
public class EmptyPythonResourceComment {
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceCommentWithBlanks.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceCommentWithBlanks.j
index fcb93bdc33..6f71f88213 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceCommentWithBlanks.j
+++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceCommentWithBlanks.j
@@ -1,6 +1,6 @@
///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:25.0.0}
+//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1}
// resource dir with blanks
//PYTHON_RESOURCES_DIRECTORY
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/NoPackagesResourcesDir.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/NoPackagesResourcesDir.j
index c2255aca6c..24a4866b26 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/NoPackagesResourcesDir.j
+++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/NoPackagesResourcesDir.j
@@ -1,6 +1,6 @@
///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:25.0.0}
+//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1}
//PYTHON_RESOURCES_DIRECTORY python-resources
public class NoPackagesResourcesDir {
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/TwoPythonResourceComments.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/TwoPythonResourceComments.j
index 3bd4381f51..ab31f0a738 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/TwoPythonResourceComments.j
+++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/TwoPythonResourceComments.j
@@ -1,6 +1,6 @@
///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:25.0.0}
+//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1}
//PYTHON_RESOURCES_DIRECTORY
//PYTHON_RESOURCES_DIRECTORY
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_gradle_plugin.py b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_gradle_plugin.py
index 2b15001db5..b50be878dc 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_gradle_plugin.py
+++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_gradle_plugin.py
@@ -133,6 +133,8 @@ def check_gradle_generated_app(self, community):
cmd = gradlew_cmd + ["build"]
out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir, logger=log)
util.check_ouput("BUILD SUCCESS", out, logger=log)
+ util.check_ouput("Virtual filesystem is deployed to default resources directory", out, logger=log)
+ util.check_ouput("This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem", out, logger=log)
self.check_filelist(target_dir, log)
cmd = gradlew_cmd + ["nativeCompile"]
@@ -413,7 +415,7 @@ def check_gradle_python_resources_dir_and_external_dir_error(self):
gradle_cmd = util.get_gradle_wrapper(target_dir, self.env)
cmd = gradle_cmd + ["graalPyResources"]
out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir)
- util.check_ouput("Cannot set both 'externalDirectory' and 'resourcesDirectory' at the same time", out)
+ util.check_ouput("Cannot set both 'externalDirectory' and 'resourceDirectory' at the same time", out)
assert return_code != 0, out
@@ -478,6 +480,8 @@ def check_gradle_namespaced_vfs(self):
app1_gradle_cmd = util.get_gradle_wrapper(app1_dir, self.env)
out, return_code = util.run_cmd(app1_gradle_cmd + ['publishToMavenLocal'], self.env, cwd=app1_dir)
+ util.check_ouput("Virtual filesystem is deployed to default resources directory", out, contains=False)
+ util.check_ouput("This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem", out, contains=False)
assert return_code == 0, out
app2_gradle_cmd = util.get_gradle_wrapper(app2_dir, self.env)
@@ -677,11 +681,11 @@ def setUpClass(cls):
cls.build_file_name = "build.gradle.kts"
cls.settings_file_name = "settings.gradle.kts"
- @unittest.skipUnless(util.is_gradle_plugin_test_enabled, "ENABLE_GRADLE_PLUGIN_UNITTESTS is not true")
+ @unittest.skipUnless(util.is_gradle_plugin_long_running_test_enabled, "ENABLE_GRADLE_PLUGIN_LONG_RUNNING_UNITTESTS is not true")
def test_gradle_generated_app(self):
self.check_gradle_generated_app(community=True)
- @unittest.skipUnless(util.is_gradle_plugin_test_enabled, "ENABLE_GRADLE_PLUGIN_UNITTESTS is not true")
+ @unittest.skipUnless(util.is_gradle_plugin_long_running_test_enabled, "ENABLE_GRADLE_PLUGIN_LONG_RUNNING_UNITTESTS is not true")
def test_gradle_generated_app_external_resources(self):
self.check_gradle_generated_app_external_resources()
@@ -701,7 +705,7 @@ def test_gradle_check_home(self):
def test_gradle_empty_packages(self):
self.check_gradle_empty_packages()
- @unittest.skipUnless(util.is_gradle_plugin_test_enabled, "ENABLE_GRADLE_PLUGIN_UNITTESTS is not true")
+ @unittest.skipUnless(util.is_gradle_plugin_long_running_test_enabled, "ENABLE_GRADLE_PLUGIN_LONG_RUNNING_UNITTESTS is not true")
def test_gradle_namespaced_vfs(self):
self.check_gradle_namespaced_vfs()
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_maven_plugin.py b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_maven_plugin.py
index 4b2cdb5c04..5c4f9e34cb 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_maven_plugin.py
+++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/test_maven_plugin.py
@@ -115,6 +115,8 @@ def check_generated_app(self, use_default_vfs_path, use_utils_pkg=False):
cmd = mvnw_cmd + ["package", "-Pnative", "-DmainClass=it.pkg.GraalPy"]
out, return_code = util.run_cmd(cmd, self.env, cwd=target_dir)
util.check_ouput("BUILD SUCCESS", out)
+ util.check_ouput("Virtual filesystem is deployed to default resources directory", out, contains=use_default_vfs_path)
+ util.check_ouput("This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem.", out, contains=use_default_vfs_path)
# check fileslist.txt
fl_path = os.path.join(target_dir, "target", "classes", vfs_prefix, "fileslist.txt")
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py b/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py
index 8533ed3835..6ea5c7e6f6 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py
+++ b/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2018, 2025, 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
@@ -150,7 +150,7 @@ def t(obj):
# ForeignInstantiable
self.assertEqual(t((e for e in [1])), polyglot.ForeignIteratorIterable)
self.assertEqual(t(iter([1])), polyglot.ForeignIteratorIterable)
- self.assertEqual(t(object), polyglot.ForeignExecutableClass)
+ self.assertEqual(t(object), polyglot.ForeignClassExecutable)
self.assertEqual(t(None), polyglot.ForeignNone)
self.assertEqual(t(1), polyglot.ForeignNumber)
self.assertEqual(t("abc"), polyglot.ForeignString)
@@ -471,10 +471,19 @@ def test_java_import_from_jar(self):
os.unlink(tempname)
def test_java_class(self):
- from java.lang import Integer, Number, NumberFormatException
- self.assertEqual(type(Integer).mro(), [polyglot.ForeignClass, polyglot.ForeignInstantiable, polyglot.ForeignAbstractClass, polyglot.ForeignObject, object])
+ from java.lang import Number, NumberFormatException
+ from java.util import ArrayList
+ self.assertEqual(type(ArrayList).mro(), [polyglot.ForeignClass, polyglot.ForeignAbstractClass, polyglot.ForeignInstantiable, polyglot.ForeignObject, object])
self.assertEqual(type(Number).mro(), [polyglot.ForeignAbstractClass, polyglot.ForeignObject, object])
- self.assertEqual(type(NumberFormatException).mro(), [polyglot.ForeignClass, polyglot.ForeignInstantiable, polyglot.ForeignAbstractClass, polyglot.ForeignObject, object])
+ self.assertEqual(type(NumberFormatException).mro(), [polyglot.ForeignClass, polyglot.ForeignAbstractClass, polyglot.ForeignInstantiable, polyglot.ForeignObject, object])
+
+ from java.util import ArrayList
+ l = ArrayList()
+ assert isinstance(l, ArrayList)
+ self.assertEqual(getattr(ArrayList, 'class'), l.getClass())
+
+ with self.assertRaisesRegex(TypeError, "ForeignInstantiable.__call__\(\) got an unexpected keyword argument 'kwarg'"):
+ ArrayList(kwarg=42)
def test_java_exceptions(self):
# TODO: more tests
@@ -1040,7 +1049,9 @@ def test_java_map(self):
h.__init__(a=1, b=2)
assert h == {'a': 1, 'b': 2}
- with self.assertRaisesRegex(TypeError, 'invalid instantiation of foreign object'):
+ # Because it tries to call ForeignDict.__call__, but ForeignDict is not executable/instantiable,
+ # so it resolves to type.__call__, which cannot create a ForeignDict
+ with self.assertRaisesRegex(TypeError, "descriptor requires a 'dict' object but received a 'ForeignDict'"):
type(h).fromkeys(['a', 'b'], 42)
def test_java_iterator(self):
diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt
index 019ffaf499..220ef38651 100644
--- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt
+++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt
@@ -35,7 +35,8 @@ test.test_strptime.StrptimeTests.test_percent @ darwin-arm64,darwin-x86_64,linux
test.test_strptime.StrptimeTests.test_second @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64
test.test_strptime.StrptimeTests.test_strptime_exception_context @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64
test.test_strptime.StrptimeTests.test_time @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64
-test.test_strptime.StrptimeTests.test_timezone @ darwin-arm64,darwin-x86_64,win32-AMD64
+# Seems to be dependent on the actual time/date/timezone of the machine, at least on GraalPy. Needs investigation
+!test.test_strptime.StrptimeTests.test_timezone
test.test_strptime.StrptimeTests.test_unconverteddata @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64
test.test_strptime.StrptimeTests.test_year @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64
test.test_strptime.TimeRETests.test_blankpattern @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java
index 633acb7e4c..6f6254b9d8 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java
@@ -59,6 +59,9 @@
import java.util.ServiceLoader;
import java.util.logging.Level;
+import com.oracle.graal.python.builtins.objects.foreign.ForeignExecutableBuiltins;
+import com.oracle.graal.python.builtins.objects.foreign.ForeignInstantiableBuiltins;
+import com.oracle.graal.python.builtins.objects.foreign.ForeignIterableBuiltins;
import org.graalvm.nativeimage.ImageInfo;
import com.oracle.graal.python.PythonLanguage;
@@ -259,6 +262,7 @@
import com.oracle.graal.python.builtins.objects.exception.UnicodeTranslateErrorBuiltins;
import com.oracle.graal.python.builtins.objects.floats.FloatBuiltins;
import com.oracle.graal.python.builtins.objects.floats.PFloat;
+import com.oracle.graal.python.builtins.objects.foreign.ForeignAbstractClassBuiltins;
import com.oracle.graal.python.builtins.objects.foreign.ForeignBooleanBuiltins;
import com.oracle.graal.python.builtins.objects.foreign.ForeignNumberBuiltins;
import com.oracle.graal.python.builtins.objects.foreign.ForeignObjectBuiltins;
@@ -487,6 +491,10 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed,
new ForeignObjectBuiltins(),
new ForeignNumberBuiltins(),
new ForeignBooleanBuiltins(),
+ new ForeignAbstractClassBuiltins(),
+ new ForeignExecutableBuiltins(),
+ new ForeignInstantiableBuiltins(),
+ new ForeignIterableBuiltins(),
new ListBuiltins(),
new DictBuiltins(),
new DictReprBuiltin(),
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java
index cc3d1de44a..8d586cc758 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java
@@ -302,8 +302,12 @@ public enum PythonBuiltinClassType implements TruffleObject {
// Foreign
ForeignObject("ForeignObject", J_POLYGLOT, Flags.PUBLIC_BASE_WDICT, ForeignObjectBuiltins.SLOTS),
- ForeignNumber("ForeignNumber", J_POLYGLOT, Flags.PUBLIC_BASE_WDICT, FOREIGNNUMBER_M_FLAGS, ForeignNumberBuiltins.SLOTS),
- ForeignBoolean("ForeignBoolean", J_POLYGLOT, Flags.PUBLIC_BASE_WDICT, FOREIGNNUMBER_M_FLAGS, ForeignBooleanBuiltins.SLOTS),
+ ForeignNumber("ForeignNumber", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT, FOREIGNNUMBER_M_FLAGS, ForeignNumberBuiltins.SLOTS),
+ ForeignBoolean("ForeignBoolean", J_POLYGLOT, ForeignNumber, Flags.PUBLIC_BASE_WDICT, FOREIGNNUMBER_M_FLAGS, ForeignBooleanBuiltins.SLOTS),
+ ForeignAbstractClass("ForeignAbstractClass", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT),
+ ForeignExecutable("ForeignExecutable", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT),
+ ForeignInstantiable("ForeignInstantiable", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT),
+ ForeignIterable("ForeignIterable", J_POLYGLOT, ForeignObject, Flags.PUBLIC_BASE_WDICT),
// bz2
BZ2Compressor("BZ2Compressor", "_bz2"),
@@ -627,6 +631,11 @@ private static class Flags {
this(name, module, module, flags);
}
+ PythonBuiltinClassType(String name, String module, PythonBuiltinClassType base, Flags flags) {
+ this(name, module, module, flags);
+ this.base = base;
+ }
+
PythonBuiltinClassType(String name, String module, Flags flags, TpSlots slots) {
this(name, module, module, flags, DEFAULT_M_FLAGS, slots);
}
@@ -639,6 +648,11 @@ private static class Flags {
this(name, module, module, flags, methodsFlags, slots);
}
+ PythonBuiltinClassType(String name, String module, PythonBuiltinClassType base, Flags flags, long methodsFlags, TpSlots slots) {
+ this(name, module, module, flags, methodsFlags, slots);
+ this.base = base;
+ }
+
PythonBuiltinClassType(String name, String publishInModule, String moduleName, Flags flags) {
this(name, publishInModule, moduleName, flags, DEFAULT_M_FLAGS, TpSlots.createEmpty());
}
@@ -837,9 +851,6 @@ public final Shape getInstanceShape(PythonLanguage lang) {
Boolean.base = PInt;
- ForeignNumber.base = ForeignObject;
- ForeignBoolean.base = ForeignNumber;
-
PBaseExceptionGroup.base = PBaseException;
SystemExit.base = PBaseException;
KeyboardInterrupt.base = PBaseException;
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java
index eea71e9ebd..a997a8a2aa 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2025, 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
@@ -228,20 +228,24 @@ static Object doIt(PythonAbstractNativeObject clazz,
@CApiBuiltin(ret = ArgDescriptor.Void, args = {PyTypeObject}, call = Direct)
abstract static class PyType_Modified extends CApiUnaryBuiltinNode {
-
@TruffleBoundary
@Specialization
- static Object doIt(PythonAbstractNativeObject clazz,
+ static Object doIt(PythonAbstractClass object,
@Bind("this") Node inliningTarget) {
- PythonContext context = PythonContext.get(inliningTarget);
- CyclicAssumption nativeClassStableAssumption = context.getNativeClassStableAssumption(clazz, false);
- if (nativeClassStableAssumption != null) {
- nativeClassStableAssumption.invalidate("PyType_Modified(\"" + TypeNodes.GetNameNode.executeUncached(clazz).toJavaStringUncached() + "\") called");
+ if (object instanceof PythonAbstractNativeObject clazz) {
+ PythonContext context = PythonContext.get(inliningTarget);
+ CyclicAssumption nativeClassStableAssumption = context.getNativeClassStableAssumption(clazz, false);
+ if (nativeClassStableAssumption != null) {
+ nativeClassStableAssumption.invalidate("PyType_Modified(\"" + TypeNodes.GetNameNode.executeUncached(clazz).toJavaStringUncached() + "\") called");
+ }
+ MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(clazz);
+ mroStorage.lookupChanged();
+ // Reload slots from native, which also invalidates cached slot lookups
+ clazz.setTpSlots(TpSlots.fromNative(clazz, context));
+ } else {
+ MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(object);
+ mroStorage.lookupChanged();
}
- MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(clazz);
- mroStorage.lookupChanged();
- // Reload slots from native, which also invalidates cached slot lookups
- clazz.setTpSlots(TpSlots.fromNative(clazz, context));
return PNone.NO_VALUE;
}
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java
index 5909dc1427..97ad1090b1 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2025, 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
@@ -504,6 +504,7 @@ public final class CApiFunction {
@CApiBuiltin(name = "PyUnicode_DecodeLatin1", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = CImpl)
@CApiBuiltin(name = "PyUnicode_DecodeLocale", ret = PyObject, args = {ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString}, call = CImpl)
@CApiBuiltin(name = "PyUnicode_DecodeLocaleAndSize", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = CImpl)
+ @CApiBuiltin(name = "PyUnicode_DecodeRawUnicodeEscape", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = CImpl)
@CApiBuiltin(name = "PyUnicode_DecodeUTF16", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, INT_LIST}, call = CImpl)
@CApiBuiltin(name = "PyUnicode_DecodeUTF16Stateful", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, INT_LIST, PY_SSIZE_T_PTR}, call = CImpl)
@CApiBuiltin(name = "PyUnicode_DecodeUTF32", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, INT_LIST}, call = CImpl)
@@ -942,7 +943,6 @@ public final class CApiFunction {
@CApiBuiltin(name = "PyUnicode_BuildEncodingMap", ret = PyObject, args = {PyObject}, call = NotImplemented)
@CApiBuiltin(name = "PyUnicode_CopyCharacters", ret = Py_ssize_t, args = {PyObject, Py_ssize_t, PyObject, Py_ssize_t, Py_ssize_t}, call = NotImplemented)
@CApiBuiltin(name = "PyUnicode_DecodeCharmap", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, PyObject, ConstCharPtrAsTruffleString}, call = NotImplemented)
- @CApiBuiltin(name = "PyUnicode_DecodeRawUnicodeEscape", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = NotImplemented)
@CApiBuiltin(name = "PyUnicode_DecodeUTF7", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = NotImplemented)
@CApiBuiltin(name = "PyUnicode_DecodeUTF7Stateful", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, PY_SSIZE_T_PTR}, call = NotImplemented)
@CApiBuiltin(name = "PyUnicode_DecodeUnicodeEscape", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = NotImplemented)
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java
index 18528ad4a6..3111ccef04 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2025, 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
@@ -1309,7 +1309,7 @@ public MethNoargsRoot(PythonLanguage language, TruffleString name, boolean isSta
@Override
protected Object[] prepareCArguments(VirtualFrame frame) {
- return new Object[]{readSelf(frame), PNone.NONE};
+ return new Object[]{readSelf(frame), PNone.NO_VALUE};
}
@Override
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignAbstractClassBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignAbstractClassBuiltins.java
new file mode 100644
index 0000000000..48cfd68373
--- /dev/null
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignAbstractClassBuiltins.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
+ * Copyright (c) 2014, Regents of the University of California
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.graal.python.builtins.objects.foreign;
+
+import com.oracle.graal.python.builtins.Builtin;
+import com.oracle.graal.python.builtins.CoreFunctions;
+import com.oracle.graal.python.builtins.PythonBuiltinClassType;
+import com.oracle.graal.python.builtins.PythonBuiltins;
+import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
+import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
+import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
+import com.oracle.graal.python.runtime.GilNode;
+import com.oracle.graal.python.runtime.object.PythonObjectFactory;
+import com.oracle.graal.python.util.PythonUtils;
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.GenerateNodeFactory;
+import com.oracle.truffle.api.dsl.NodeFactory;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.interop.InteropLibrary;
+import com.oracle.truffle.api.interop.UnsupportedMessageException;
+import com.oracle.truffle.api.library.CachedLibrary;
+
+import java.util.List;
+
+import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___BASES__;
+import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INSTANCECHECK__;
+
+/*
+ * NOTE: We are not using IndirectCallContext here in this file
+ * because it seems unlikely that these interop messages would call back to Python
+ * and that we would also need precise frame info for that case.
+ * Adding it shouldn't hurt peak, but might be a non-trivial overhead in interpreter.
+ */
+@CoreFunctions(extendClasses = PythonBuiltinClassType.ForeignAbstractClass)
+public final class ForeignAbstractClassBuiltins extends PythonBuiltins {
+ @Override
+ protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFactories() {
+ return ForeignAbstractClassBuiltinsFactory.getFactories();
+ }
+
+ @Builtin(name = J___BASES__, minNumOfPositionalArgs = 1, isGetter = true, isSetter = false)
+ @GenerateNodeFactory
+ abstract static class BasesNode extends PythonUnaryBuiltinNode {
+ @Specialization
+ static Object getBases(Object self,
+ @Cached PythonObjectFactory factory) {
+ return factory.createTuple(PythonUtils.EMPTY_OBJECT_ARRAY);
+ }
+ }
+
+ @Builtin(name = J___INSTANCECHECK__, minNumOfPositionalArgs = 2)
+ @GenerateNodeFactory
+ abstract static class InstancecheckNode extends PythonBinaryBuiltinNode {
+ @Specialization(limit = "3")
+ static Object check(Object self, Object instance,
+ @CachedLibrary("self") InteropLibrary lib,
+ @Cached GilNode gil) {
+ gil.release(true);
+ try {
+ return lib.isMetaInstance(self, instance);
+ } catch (UnsupportedMessageException e) {
+ throw CompilerDirectives.shouldNotReachHere();
+ } finally {
+ gil.acquire();
+ }
+ }
+ }
+
+}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java
new file mode 100644
index 0000000000..ea02d004c7
--- /dev/null
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
+ * Copyright (c) 2014, Regents of the University of California
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.graal.python.builtins.objects.foreign;
+
+import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
+
+import java.util.List;
+
+import com.oracle.graal.python.PythonLanguage;
+import com.oracle.graal.python.builtins.Builtin;
+import com.oracle.graal.python.builtins.CoreFunctions;
+import com.oracle.graal.python.builtins.PythonBuiltinClassType;
+import com.oracle.graal.python.builtins.PythonBuiltins;
+import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
+import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
+import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
+import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
+import com.oracle.graal.python.runtime.GilNode;
+import com.oracle.graal.python.runtime.IndirectCallData;
+import com.oracle.graal.python.runtime.PythonContext;
+import com.oracle.graal.python.runtime.exception.PythonErrorType;
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.dsl.Bind;
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.GenerateNodeFactory;
+import com.oracle.truffle.api.dsl.NodeFactory;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.interop.ArityException;
+import com.oracle.truffle.api.interop.InteropLibrary;
+import com.oracle.truffle.api.interop.UnsupportedMessageException;
+import com.oracle.truffle.api.interop.UnsupportedTypeException;
+import com.oracle.truffle.api.library.CachedLibrary;
+import com.oracle.truffle.api.nodes.Node;
+
+@CoreFunctions(extendClasses = PythonBuiltinClassType.ForeignExecutable)
+public final class ForeignExecutableBuiltins extends PythonBuiltins {
+ @Override
+ protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFactories() {
+ return ForeignExecutableBuiltinsFactory.getFactories();
+ }
+
+ @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true)
+ @GenerateNodeFactory
+ public abstract static class CallNode extends PythonBuiltinNode {
+ @Specialization
+ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments,
+ @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
+ @Cached("createFor(this)") IndirectCallData indirectCallData,
+ @CachedLibrary(limit = "4") InteropLibrary lib,
+ @Cached PForeignToPTypeNode toPTypeNode,
+ @Cached GilNode gil,
+ @Cached PRaiseNode.Lazy raiseNode) {
+ PythonLanguage language = PythonLanguage.get(inliningTarget);
+ PythonContext context = PythonContext.get(inliningTarget);
+ try {
+ Object state = IndirectCallContext.enter(frame, language, context, indirectCallData);
+ gil.release(true);
+ try {
+ return toPTypeNode.executeConvert(lib.execute(callee, arguments));
+ } finally {
+ gil.acquire();
+ IndirectCallContext.exit(frame, language, context, state);
+ }
+ } catch (ArityException | UnsupportedTypeException e) {
+ throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
+ } catch (UnsupportedMessageException e) {
+ throw CompilerDirectives.shouldNotReachHere(e);
+ }
+ }
+ }
+
+}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java
new file mode 100644
index 0000000000..d5b095145e
--- /dev/null
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
+ * Copyright (c) 2014, Regents of the University of California
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.graal.python.builtins.objects.foreign;
+
+import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
+import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__;
+
+import java.util.List;
+
+import com.oracle.graal.python.PythonLanguage;
+import com.oracle.graal.python.builtins.Builtin;
+import com.oracle.graal.python.builtins.CoreFunctions;
+import com.oracle.graal.python.builtins.PythonBuiltinClassType;
+import com.oracle.graal.python.builtins.PythonBuiltins;
+import com.oracle.graal.python.nodes.ErrorMessages;
+import com.oracle.graal.python.nodes.PRaiseNode;
+import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
+import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
+import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
+import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
+import com.oracle.graal.python.runtime.GilNode;
+import com.oracle.graal.python.runtime.IndirectCallData;
+import com.oracle.graal.python.runtime.PythonContext;
+import com.oracle.graal.python.runtime.exception.PythonErrorType;
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.dsl.Bind;
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.GenerateNodeFactory;
+import com.oracle.truffle.api.dsl.NodeFactory;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.interop.ArityException;
+import com.oracle.truffle.api.interop.InteropLibrary;
+import com.oracle.truffle.api.interop.UnsupportedMessageException;
+import com.oracle.truffle.api.interop.UnsupportedTypeException;
+import com.oracle.truffle.api.library.CachedLibrary;
+import com.oracle.truffle.api.nodes.Node;
+
+@CoreFunctions(extendClasses = PythonBuiltinClassType.ForeignInstantiable)
+public final class ForeignInstantiableBuiltins extends PythonBuiltins {
+ @Override
+ protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFactories() {
+ return ForeignInstantiableBuiltinsFactory.getFactories();
+ }
+
+ @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true)
+ @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true)
+ @GenerateNodeFactory
+ public abstract static class CallNode extends PythonBuiltinNode {
+ @Specialization
+ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments,
+ @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
+ @Cached("createFor(this)") IndirectCallData indirectCallData,
+ @CachedLibrary(limit = "4") InteropLibrary lib,
+ @Cached PForeignToPTypeNode toPTypeNode,
+ @Cached GilNode gil,
+ @Cached PRaiseNode.Lazy raiseNode) {
+ PythonLanguage language = PythonLanguage.get(inliningTarget);
+ PythonContext context = PythonContext.get(inliningTarget);
+ try {
+ Object state = IndirectCallContext.enter(frame, language, context, indirectCallData);
+ gil.release(true);
+ try {
+ return toPTypeNode.executeConvert(lib.instantiate(callee, arguments));
+ } finally {
+ gil.acquire();
+ IndirectCallContext.exit(frame, language, context, state);
+ }
+ } catch (ArityException | UnsupportedTypeException e) {
+ throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
+ } catch (UnsupportedMessageException e) {
+ throw CompilerDirectives.shouldNotReachHere(e);
+ }
+ }
+ }
+
+}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignIterableBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignIterableBuiltins.java
new file mode 100644
index 0000000000..647eee6b2f
--- /dev/null
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignIterableBuiltins.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
+ * Copyright (c) 2014, Regents of the University of California
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.graal.python.builtins.objects.foreign;
+
+import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
+
+import java.util.List;
+
+import com.oracle.graal.python.builtins.Builtin;
+import com.oracle.graal.python.builtins.CoreFunctions;
+import com.oracle.graal.python.builtins.PythonBuiltinClassType;
+import com.oracle.graal.python.builtins.PythonBuiltins;
+import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
+import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
+import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
+import com.oracle.graal.python.runtime.GilNode;
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.GenerateNodeFactory;
+import com.oracle.truffle.api.dsl.NodeFactory;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.interop.InteropLibrary;
+import com.oracle.truffle.api.interop.UnsupportedMessageException;
+import com.oracle.truffle.api.library.CachedLibrary;
+
+/*
+ * NOTE: We are not using IndirectCallContext here in this file
+ * because it seems unlikely that these interop messages would call back to Python
+ * and that we would also need precise frame info for that case.
+ * Adding it shouldn't hurt peak, but might be a non-trivial overhead in interpreter.
+ */
+@CoreFunctions(extendClasses = PythonBuiltinClassType.ForeignIterable)
+public final class ForeignIterableBuiltins extends PythonBuiltins {
+ @Override
+ protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFactories() {
+ return ForeignIterableBuiltinsFactory.getFactories();
+ }
+
+ @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
+ @GenerateNodeFactory
+ public abstract static class IterNode extends PythonUnaryBuiltinNode {
+
+ @Specialization(limit = "3")
+ static Object doGeneric(Object object,
+ @CachedLibrary("object") InteropLibrary lib,
+ @Cached PForeignToPTypeNode convertNode,
+ @Cached GilNode gil) {
+ gil.release(true);
+ try {
+ return convertNode.executeConvert(lib.getIterator(object));
+ } catch (UnsupportedMessageException e) {
+ throw CompilerDirectives.shouldNotReachHere(e);
+ } finally {
+ gil.acquire();
+ }
+ }
+ }
+
+}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java
index 617458040f..ea386f7fed 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2024, Oracle and/or its affiliates.
+ * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
* Copyright (c) 2014, Regents of the University of California
*
* All rights reserved.
@@ -29,17 +29,10 @@
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.AttributeError;
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
import static com.oracle.graal.python.builtins.objects.str.StringUtils.simpleTruffleStringFormatUncached;
-import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___BASES__;
-import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___BASES__;
-import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CALL__;
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___DIR__;
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___HASH__;
-import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INSTANCECHECK__;
-import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ITER__;
-import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__;
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___REPR__;
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___STR__;
-import static com.oracle.graal.python.nodes.SpecialMethodNames.T___INSTANCECHECK__;
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
import java.util.List;
@@ -53,7 +46,6 @@
import com.oracle.graal.python.builtins.PythonBuiltins;
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
-import com.oracle.graal.python.builtins.objects.function.PKeyword;
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
import com.oracle.graal.python.builtins.objects.object.ObjectNodes;
import com.oracle.graal.python.builtins.objects.type.TpSlots;
@@ -65,35 +57,27 @@
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
-import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
-import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
import com.oracle.graal.python.nodes.object.GetClassNode;
-import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
import com.oracle.graal.python.nodes.util.CannotCastException;
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
-import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
import com.oracle.graal.python.runtime.GilNode;
-import com.oracle.graal.python.runtime.IndirectCallData;
import com.oracle.graal.python.runtime.PythonContext;
import com.oracle.graal.python.runtime.PythonOptions;
import com.oracle.graal.python.runtime.exception.PException;
import com.oracle.graal.python.runtime.exception.PythonErrorType;
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
-import com.oracle.graal.python.util.PythonUtils;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
-import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateCached;
import com.oracle.truffle.api.dsl.GenerateInline;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.ImportStatic;
-import com.oracle.truffle.api.dsl.NeverDefault;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -108,7 +92,7 @@
import com.oracle.truffle.api.strings.TruffleString;
/*
- * NOTE: We are not using IndirectCallContext here in this file (except for CallNode)
+ * NOTE: We are not using IndirectCallContext here in this file
* because it seems unlikely that these interop messages would call back to Python
* and that we would also need precise frame info for that case.
* Adding it shouldn't hurt peak, but might be a non-trivial overhead in interpreter.
@@ -144,111 +128,6 @@ private static int hashCodeBoundary(Object self) {
}
}
- @Builtin(name = J___ITER__, minNumOfPositionalArgs = 1)
- @GenerateNodeFactory
- public abstract static class IterNode extends PythonUnaryBuiltinNode {
-
- @Specialization(limit = "3")
- static Object doGeneric(Object object,
- @Cached PRaiseNode raiseNode,
- @CachedLibrary("object") InteropLibrary lib,
- @Cached PForeignToPTypeNode convertNode,
- @Cached GilNode gil) {
- gil.release(true);
- try {
- if (lib.hasIterator(object)) {
- return convertNode.executeConvert(lib.getIterator(object));
- }
- } catch (UnsupportedMessageException e) {
- throw CompilerDirectives.shouldNotReachHere(e);
- } finally {
- gil.acquire();
- }
- throw raiseNode.raise(TypeError, ErrorMessages.FOREIGN_OBJ_ISNT_ITERABLE);
- }
- }
-
- @Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
- @GenerateNodeFactory
- abstract static class NewNode extends PythonBuiltinNode {
- @Specialization(guards = {"isForeignObjectNode.execute(inliningTarget, callee)", "!isNoValue(callee)", "keywords.length == 0"}, limit = "1")
- static Object doInteropCall(Object callee, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
- @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
- @SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
- @CachedLibrary(limit = "3") InteropLibrary lib,
- @Cached PForeignToPTypeNode toPTypeNode,
- @Cached GilNode gil,
- @Cached PRaiseNode.Lazy raiseNode) {
- gil.release(true);
- try {
- Object res = lib.instantiate(callee, arguments);
- return toPTypeNode.executeConvert(res);
- } catch (ArityException | UnsupportedTypeException | UnsupportedMessageException e) {
- throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
- } finally {
- gil.acquire();
- }
- }
-
- @Fallback
- @SuppressWarnings("unused")
- static Object doGeneric(Object callee, Object arguments, Object keywords,
- @Cached PRaiseNode raiseNode) {
- throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
- }
- }
-
- @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
- @GenerateNodeFactory
- public abstract static class CallNode extends PythonBuiltinNode {
- public final Object executeWithArgs(VirtualFrame frame, Object callee, Object[] arguments) {
- return execute(frame, callee, arguments, PKeyword.EMPTY_KEYWORDS);
- }
-
- public abstract Object execute(VirtualFrame frame, Object callee, Object[] arguments, PKeyword[] keywords);
-
- @Specialization(guards = {"isForeignObjectNode.execute(inliningTarget, callee)", "!isNoValue(callee)", "keywords.length == 0"}, limit = "1")
- static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
- @SuppressWarnings("unused") @Bind("this") Node inliningTarget,
- @Cached("createFor(this)") IndirectCallData indirectCallData,
- @SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
- @CachedLibrary(limit = "4") InteropLibrary lib,
- @Cached PForeignToPTypeNode toPTypeNode,
- @Cached GilNode gil,
- @Cached PRaiseNode.Lazy raiseNode) {
- PythonLanguage language = PythonLanguage.get(inliningTarget);
- PythonContext context = PythonContext.get(inliningTarget);
- try {
- Object state = IndirectCallContext.enter(frame, language, context, indirectCallData);
- gil.release(true);
- try {
- if (lib.isExecutable(callee)) {
- return toPTypeNode.executeConvert(lib.execute(callee, arguments));
- } else {
- return toPTypeNode.executeConvert(lib.instantiate(callee, arguments));
- }
- } finally {
- gil.acquire();
- IndirectCallContext.exit(frame, language, context, state);
- }
- } catch (ArityException | UnsupportedTypeException | UnsupportedMessageException e) {
- throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
- }
- }
-
- @Fallback
- @SuppressWarnings("unused")
- static Object doGeneric(Object callee, Object arguments, Object keywords,
- @Cached PRaiseNode raiseNode) {
- throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
- }
-
- @NeverDefault
- public static CallNode create() {
- return ForeignObjectBuiltinsFactory.CallNodeFactory.create(null);
- }
- }
-
@Slot(value = SlotKind.tp_getattro, isComplex = true)
@GenerateNodeFactory
abstract static class GetAttributeNode extends GetAttrBuiltinNode {
@@ -497,47 +376,4 @@ protected TruffleString defaultConversion(VirtualFrame frame, InteropLibrary lib
}
}
- @Builtin(name = J___BASES__, minNumOfPositionalArgs = 1, isGetter = true, isSetter = false)
- @GenerateNodeFactory
- @ImportStatic(PGuards.class)
- abstract static class BasesNode extends PythonUnaryBuiltinNode {
- @Specialization(limit = "3")
- static Object getBases(Object self,
- @Bind("this") Node inliningTarget,
- @CachedLibrary("self") InteropLibrary lib,
- @Cached PythonObjectFactory factory,
- @Cached PRaiseNode.Lazy raiseNode) {
- if (lib.isMetaObject(self)) {
- return factory.createTuple(PythonUtils.EMPTY_OBJECT_ARRAY);
- } else {
- throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.FOREIGN_OBJ_HAS_NO_ATTR_S, T___BASES__);
- }
- }
- }
-
- @Builtin(name = J___INSTANCECHECK__, minNumOfPositionalArgs = 2)
- @GenerateNodeFactory
- @ImportStatic(PGuards.class)
- abstract static class InstancecheckNode extends PythonBinaryBuiltinNode {
- @Specialization(limit = "3")
- static Object check(Object self, Object instance,
- @Bind("this") Node inliningTarget,
- @CachedLibrary("self") InteropLibrary lib,
- @Cached GilNode gil,
- @Cached PRaiseNode.Lazy raiseNode) {
- if (lib.isMetaObject(self)) {
- gil.release(true);
- try {
- return lib.isMetaInstance(self, instance);
- } catch (UnsupportedMessageException e) {
- throw CompilerDirectives.shouldNotReachHere();
- } finally {
- gil.acquire();
- }
- } else {
- throw raiseNode.get(inliningTarget).raise(AttributeError, ErrorMessages.FOREIGN_OBJ_HAS_NO_ATTR_S, T___INSTANCECHECK__);
- }
- }
- }
-
}
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java
index 497d8f0470..0685be32b0 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java
@@ -842,7 +842,7 @@ public static TpSlots fromNative(PythonAbstractNativeObject pythonClass, PythonC
existingSlotWrapper = execWrapper;
} else if (executable != null) {
// This can happen for legacy slots where the delegate would be a PFunction
- LOGGER.warning(() -> String.format("Unexpected executable for slot pointer: %s", executable));
+ LOGGER.fine(() -> String.format("Unexpected executable for slot pointer: %s", executable));
}
} catch (UnsupportedMessageException e) {
throw new IllegalStateException(e);
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java
index f15c1e4196..37dbb36db7 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java
@@ -334,7 +334,6 @@ public abstract class ErrorMessages {
public static final TruffleString FAILED_TO_CONVERT_SEQ = tsLiteral("failed to convert sequence");
public static final TruffleString FLOAT_ARG_REQUIRED = tsLiteral("float argument required, not %p");
public static final TruffleString FOREIGN_OBJ_HAS_NO_ATTR_S = tsLiteral("foreign object has no attribute '%s'");
- public static final TruffleString FOREIGN_OBJ_ISNT_ITERABLE = tsLiteral("foreign object is not iterable");
public static final TruffleString FOREIGN_OBJ_ISNT_REVERSE_ITERABLE = tsLiteral("foreign object cannot be iterated in reverse");
public static final TruffleString FORMAT_REQUIRES_MAPPING = tsLiteral("format requires a mapping");
public static final TruffleString FORMAT_STR_CONTAINS_POS_FIELDS = tsLiteral("Format string contains positional fields");
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/TopLevelExceptionHandler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/TopLevelExceptionHandler.java
index f20a4ea9cd..53f1fe05d0 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/TopLevelExceptionHandler.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/exception/TopLevelExceptionHandler.java
@@ -195,12 +195,7 @@ private AbstractTruffleException handlePythonException(AbstractTruffleException
if (PythonOptions.isPExceptionWithJavaStacktrace(getPythonLanguage()) && e instanceof PException pe) {
ExceptionUtils.printJavaStackTrace(pe);
}
- if (!getSourceSection().getSource().isInteractive()) {
- if (getContext().isChildContext()) {
- getContext().getChildContextData().setExitCode(1);
- }
- throw new PythonExitException(this, 1);
- }
+ exit(1);
}
// Before we leave Python, format the message since outside the context
if (e instanceof PException pe) {
@@ -209,6 +204,15 @@ private AbstractTruffleException handlePythonException(AbstractTruffleException
throw e;
}
+ private void exit(int exitCode) {
+ if (!getSourceSection().getSource().isInteractive()) {
+ if (getContext().isChildContext()) {
+ getContext().getChildContextData().setExitCode(1);
+ }
+ throw new PythonExitException(this, exitCode);
+ }
+ }
+
private static boolean isSystemExit(PBaseException pythonException) {
return IsBuiltinClassProfile.profileClassSlowPath(GetPythonObjectClassNode.executeUncached(pythonException), SystemExit);
}
@@ -227,6 +231,7 @@ private void handleJavaException(Throwable e) {
if (PythonOptions.shouldPrintJavaStacktrace(getPythonLanguage(), e)) {
e.printStackTrace();
}
+ exit(1);
}
} catch (UnsupportedMessageException unsupportedMessageException) {
throw CompilerDirectives.shouldNotReachHere();
@@ -250,12 +255,12 @@ private void handleSystemExit(PBaseException pythonException) {
int exitcode = getExitCode(pythonException);
throw new PythonExitException(this, exitcode);
} catch (CannotCastException e) {
- // fall through
- }
- if (handleAlwaysRunExceptHook(theContext, pythonException)) {
- throw new PythonExitException(this, 1);
+ if (handleAlwaysRunExceptHook(theContext, pythonException)) {
+ throw new PythonExitException(this, 1);
+ } else {
+ throw pythonException.getExceptionForReraise(pythonException.getTraceback());
+ }
}
- throw pythonException.getExceptionForReraise(pythonException.getTraceback());
}
@TruffleBoundary
@@ -264,12 +269,12 @@ private Object handleChildContextExit(PBaseException pythonException) throws PEx
try {
return getExitCode(pythonException);
} catch (CannotCastException cce) {
- // fall through
- }
- if (handleAlwaysRunExceptHook(getContext(), pythonException)) {
- return 1;
+ if (handleAlwaysRunExceptHook(getContext(), pythonException)) {
+ return 1;
+ } else {
+ throw pythonException.getExceptionForReraise(pythonException.getTraceback());
+ }
}
- throw pythonException.getExceptionForReraise(pythonException.getTraceback());
}
private static int getExitCode(PBaseException pythonException) throws CannotCastException {
diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java
index b40c4afbcf..b7b041b290 100644
--- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, 2025, 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
@@ -87,21 +87,26 @@ public enum Trait {
// The type field is only set for cases which are already implemented.
// First in MRO
+ // Interop types first as they are the most concrete/specific types
+ NULL("None", PythonBuiltinClassType.PNone),
BOOLEAN("Boolean", PythonBuiltinClassType.ForeignBoolean),
NUMBER("Number", PythonBuiltinClassType.ForeignNumber), // int, float, complex
STRING("String", PythonBuiltinClassType.PString),
+ EXCEPTION("Exception", PythonBuiltinClassType.PBaseException),
+ META_OBJECT("AbstractClass", PythonBuiltinClassType.ForeignAbstractClass),
+
+ // Interop traits
+ EXECUTABLE("Executable", PythonBuiltinClassType.ForeignExecutable),
+ INSTANTIABLE("Instantiable", PythonBuiltinClassType.ForeignInstantiable),
+
+ // Container traits/types must be last, see comment above
// Hash before Array so that foreign dict+list prefers dict.[]
HASH("Dict", PythonBuiltinClassType.PDict),
// Array before Iterable so that foreign list+iterable prefers list.__iter__
ARRAY("List", PythonBuiltinClassType.PList),
- EXCEPTION("Exception", PythonBuiltinClassType.PBaseException),
- EXECUTABLE("Executable"),
- INSTANTIABLE("Instantiable"),
// Iterator before Iterable so that foreign iterator+iterable prefers iterator.__iter__
ITERATOR("Iterator", PythonBuiltinClassType.PIterator),
- ITERABLE("Iterable"),
- META_OBJECT("AbstractClass"), // PythonBuiltinClassType.PythonClass ?
- NULL("None", PythonBuiltinClassType.PNone);
+ ITERABLE("Iterable", PythonBuiltinClassType.ForeignIterable);
// Last in MRO
public static final Trait[] VALUES = Trait.values();
@@ -111,10 +116,6 @@ public enum Trait {
final int bit;
final PythonBuiltinClassType type;
- Trait(String name) {
- this(name, null);
- }
-
Trait(String name, PythonBuiltinClassType type) {
this.name = name;
this.bit = 1 << ordinal();
@@ -217,14 +218,14 @@ private PythonManagedClass resolvePolyglotForeignClass(int traits) {
traitsList.add(classForTraits(trait.bit));
}
- if (trait == Trait.INSTANTIABLE && Trait.META_OBJECT.isSet(traits)) {
- // Deal with it when we are at trait META_OBJECT
- } else if (trait == Trait.META_OBJECT) {
+ if (trait == Trait.META_OBJECT) {
if (Trait.INSTANTIABLE.isSet(traits)) {
nameBuilder.append("Class");
} else {
nameBuilder.append("AbstractClass");
}
+ } else if (trait == Trait.INSTANTIABLE && Trait.META_OBJECT.isSet(traits)) {
+ // Dealt with above
} else {
nameBuilder.append(trait.name);
}
diff --git a/graalpython/graalpy-archetype-polyglot-app/pom.xml b/graalpython/graalpy-archetype-polyglot-app/pom.xml
index d08b5631bb..e525172eb1 100644
--- a/graalpython/graalpy-archetype-polyglot-app/pom.xml
+++ b/graalpython/graalpy-archetype-polyglot-app/pom.xml
@@ -45,7 +45,7 @@ SOFTWARE.
org.graalvm.python
graalpy-archetype-polyglot-app
- 25.0.0
+ 24.2.1
http://www.graalvm.org/python
Maven archetype providing a skeleton GraalPy - Java polyglot application.
maven-archetype
diff --git a/graalpython/graalpy-archetype-polyglot-app/src/main/resources/archetype-resources/pom.xml b/graalpython/graalpy-archetype-polyglot-app/src/main/resources/archetype-resources/pom.xml
index eb03184b9f..e67d93e879 100644
--- a/graalpython/graalpy-archetype-polyglot-app/src/main/resources/archetype-resources/pom.xml
+++ b/graalpython/graalpy-archetype-polyglot-app/src/main/resources/archetype-resources/pom.xml
@@ -10,7 +10,7 @@
#set( $symbol_dollar = '$' )
- 25.0.0
+ 24.2.1
python-community
0.10.4
17
diff --git a/graalpython/graalpy-jbang/examples/hello.java b/graalpython/graalpy-jbang/examples/hello.java
index 2afc0c82b3..11049392fc 100644
--- a/graalpython/graalpy-jbang/examples/hello.java
+++ b/graalpython/graalpy-jbang/examples/hello.java
@@ -40,7 +40,7 @@
*/
///usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 17+
-//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:25.0.0}
+//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1}
// specify python packages and their versions as if used with pip
//PIP termcolor==2.2
diff --git a/graalpython/graalpy-jbang/templates/graalpy-template.java.qute b/graalpython/graalpy-jbang/templates/graalpy-template.java.qute
index 5258d8cb30..9a94477922 100644
--- a/graalpython/graalpy-jbang/templates/graalpy-template.java.qute
+++ b/graalpython/graalpy-jbang/templates/graalpy-template.java.qute
@@ -5,7 +5,7 @@
{/for}
{#if dependencies.isEmpty()}// //DEPS {/if}
{|
-//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:25.0.0}
+//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1}
// specify python packages and their versions as if used with pip
//PIP termcolor==2.2
|}
diff --git a/graalpython/graalpy-jbang/templates/graalpy-template_local_repo.java.qute b/graalpython/graalpy-jbang/templates/graalpy-template_local_repo.java.qute
index 9db2304494..6b41f4e288 100644
--- a/graalpython/graalpy-jbang/templates/graalpy-template_local_repo.java.qute
+++ b/graalpython/graalpy-jbang/templates/graalpy-template_local_repo.java.qute
@@ -8,7 +8,7 @@
//REPOS mc=https://repo1.maven.org/maven2/
//REPOS local=file://{path_to_local_repo}
{|
-//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:25.0.0}
+//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1}
// specify python packages and their versions as if used with pip
//PIP termcolor==2.2
|}
diff --git a/graalpython/graalpy-maven-plugin/pom.xml b/graalpython/graalpy-maven-plugin/pom.xml
index 7a8715415f..5a8fe1acde 100644
--- a/graalpython/graalpy-maven-plugin/pom.xml
+++ b/graalpython/graalpy-maven-plugin/pom.xml
@@ -48,7 +48,7 @@ SOFTWARE.
graalpy-maven-plugin
maven-plugin
- 25.0.0
+ 24.2.1
http://www.graalvm.org/python
graalpy-maven-plugin
Handles python related resources in a maven GraalPy - Java polyglot application.
@@ -57,7 +57,7 @@ SOFTWARE.
17
17
UTF-8
- 25.0.0
+ 24.2.1
diff --git a/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/ManageResourcesMojo.java b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/ManageResourcesMojo.java
index bc2b69ceae..d81b78b861 100644
--- a/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/ManageResourcesMojo.java
+++ b/graalpython/graalpy-maven-plugin/src/main/java/org/graalvm/python/maven/plugin/ManageResourcesMojo.java
@@ -145,7 +145,7 @@ public void execute() throws MojoExecutionException {
}
if (resourceDirectory == null) {
- if (externalDirectory != null) {
+ if (externalDirectory == null) {
getLog().info(String.format("Virtual filesystem is deployed to default resources directory '%s'. " +
"This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem. " +
"Consider adding GRAALPY-VFS/${project.groupId}/${project.artifactId} to your pom.xml, " +
@@ -162,7 +162,7 @@ public void execute() throws MojoExecutionException {
getLog().warn("The GraalPy plugin configuration setting was deprecated and has no effect anymore.\n" +
"For execution in jvm mode, the python language home is always available.\n" +
"When building a native executable using GraalVM Native Image, then the full python language home is by default embedded into the native executable.\n" +
- "For more details, please refer to the documentation of GraalVM Native Image options IncludeLanguageResources and CopyLanguageResources documentation.");
+ "For more details, please refer to the documentation of GraalVM Native Image options IncludeLanguageResources and CopyLanguageResources.");
}
manageVenv();
diff --git a/graalpython/lib-graalpython/patches/jq-1.8.0.patch b/graalpython/lib-graalpython/patches/jq-1.8.0.patch
new file mode 100644
index 0000000000..c62c51759a
--- /dev/null
+++ b/graalpython/lib-graalpython/patches/jq-1.8.0.patch
@@ -0,0 +1,59 @@
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -2,13 +2,10 @@
+ requires = [
+ "setuptools>=43",
+ "wheel",
++ "Cython==3.0.10",
+ ]
+ build-backend = "setuptools.build_meta"
+
+ [tool.cibuildwheel]
+-before-build = [
+- "pip install cython==3.0.10",
+- "cython {project}/jq.pyx",
+-]
+ test-requires = "-r test-requirements.txt"
+ test-command = "pytest {project}/tests"
+diff --git a/setup.py b/setup.py
+index 0b97097..54ed7b3 100644
+--- a/setup.py
++++ b/setup.py
+@@ -94,15 +94,27 @@ else:
+ os.path.join(jq_lib_dir, "modules/oniguruma/src/.libs/libonig.a"),
+ ]
+
++
++try:
++ # Follow recommendation from https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules
++ from Cython.Build import cythonize
++except ImportError:
++ cythonize = lambda o: o
++ ext = ".c"
++else:
++ ext = ".pyx"
++
++
+ jq_extension = Extension(
+ "jq",
+- sources=["jq.c"],
++ sources=[_path_in_dir(f"jq{ext}")],
+ define_macros=[("MS_WIN64" , 1)] if os.name == "nt" and sys.maxsize > 2**32 else None, # https://github.com/cython/cython/issues/2670
+ include_dirs=[os.path.join(jq_lib_dir, "src")],
+ extra_link_args=["-lm"] + (["-Wl,-Bstatic", "-lpthread", "-lshlwapi", "-static-libgcc"] if os.name == 'nt' else []) + link_args_deps,
+ extra_objects=extra_objects,
+ )
+
++
+ setup(
+ name='jq',
+ version='1.8.0',
+@@ -112,7 +124,7 @@ setup(
+ url='https://github.com/mwilliamson/jq.py',
+ python_requires='>=3.6',
+ license='BSD 2-Clause',
+- ext_modules = [jq_extension],
++ ext_modules = cythonize([jq_extension]),
+ cmdclass={"build_ext": jq_build_ext},
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml
index ac1ccb7262..b9d99a732b 100644
--- a/graalpython/lib-graalpython/patches/metadata.toml
+++ b/graalpython/lib-graalpython/patches/metadata.toml
@@ -105,7 +105,7 @@ patch = 'cryptography-42.0.5.patch'
license = 'Apache-2.0 OR BSD-3-Clause'
[[Cython.rules]]
-version = '>= 3.0.10, < 3.0.12'
+version = '>= 3.0.10, <= 3.0.12'
patch = 'Cython-3.0.10.patch'
license = 'Apache-2.0'
@@ -200,6 +200,15 @@ version = '<=1.3.2'
patch = 'joblib-1.3.2.patch'
license = 'BSD-3-Clause'
+[[jq.rules]]
+version = '==1.8.0'
+patch = 'jq-1.8.0.patch'
+license = 'BSD-2-Clause'
+
+[[jq.add-sources]]
+version = '1.8.0'
+url = 'https://github.com/mwilliamson/jq.py/archive/refs/tags/1.8.0.tar.gz'
+
[[jupyter_server.rules]]
patch = 'jupyter_server.patch'
license = 'BSD-3-Clause'
@@ -286,6 +295,12 @@ version = '== 0.59.1'
patch = 'numba-0.59.1.patch'
license = 'BSD-2-Clause'
+[[numpy.rules]]
+version = '== 2.2.4'
+patch = 'numpy-2.2.4.patch'
+license = 'BSD-3-Clause'
+dist-type = 'sdist'
+
[[numpy.rules]]
version = '>= 2.0.0rc1, < 2.1'
patch = 'numpy-2.0.0.patch'
@@ -337,6 +352,11 @@ version = '== 3.10.5'
patch = 'orjson-3.10.5.patch'
license = 'Apache-2.0 OR MIT'
+[[ormsgpack.rules]]
+version = '>= 1.8.0, <= 1.9.1'
+patch = 'ormsgpack-1.8.0-1.9.1.patch'
+license = 'Apache-2.0 OR MIT'
+
[[overrides.rules]]
version = '== 7.4.0'
# Important: This patch esentially breaks the package, it's not upstreamable. The package relies on bytecode parsing
@@ -358,6 +378,12 @@ patch = 'pandas-2.2.2.patch'
license = 'BSD-3-Clause'
dist-type = 'sdist'
+[[pandas.rules]]
+version = '== 2.2.3'
+patch = 'pandas-2.2.3.patch'
+license = 'BSD-3-Clause'
+dist-type = 'sdist'
+
[[pandas.rules]]
version = '== 2.0.3'
patch = 'pandas-2.0.3.patch'
@@ -394,11 +420,23 @@ patch = 'protobuf-3.21.9.patch'
license = 'BSD-3-Clause'
[[psycopg2.rules]]
-patch = "psycopg2.patch"
+version = '<= 2.9.9'
+patch = "psycopg2-2.9.9.patch"
+license = "LGPL-3.0-or-later WITH openssl-exception"
+
+[[psycopg2.rules]]
+version = '>= 2.9.10'
+patch = "psycopg2-2.9.10.patch"
license = "LGPL-3.0-or-later WITH openssl-exception"
[[psycopg2-binary.rules]]
-patch = "psycopg2-binary.patch"
+version = '<= 2.9.9'
+patch = "psycopg2-2.9.9.patch"
+license = "LGPL-3.0-or-later WITH openssl-exception"
+
+[[psycopg2-binary.rules]]
+version = '>= 2.9.10'
+patch = "psycopg2-2.9.10.patch"
license = "LGPL-3.0-or-later WITH openssl-exception"
[[py4j.rules]]
@@ -416,6 +454,11 @@ version = '== 12.0.0'
patch = 'pyarrow-12.0.0.patch'
license = 'Apache-2.0'
+[[pyarrow.rules]]
+version = '== 19.0.0'
+patch = 'pyarrow-19.0.0.patch'
+license = 'Apache-2.0'
+
[[pybind11.rules]]
# Upstreamed
install-priority = 0
@@ -476,6 +519,15 @@ version = ">= 4.8.0"
patch = 'pymongo-4.8.0.patch'
license = 'Apache-2.0'
+[[PyMuPDF.rules]]
+version = "== 1.25.4"
+patch = "pymupdf.patch"
+# That project is AGPL, so do not actually include *any* code of pymupdf in the patch, not even an
+# empty line, in the diff context. The code we write in the patch is UPL - that is compatible with
+# AGPL in the sense that if someone were to apply it and distribute *that*, our patch is now part
+# of the AGPL'd codebase
+license = 'UPL'
+
[[pyOpenSSL.rules]]
# Pin this version to avoid pulling newer cryptography than we have patch for
version = "== 23.2.0"
@@ -518,10 +570,15 @@ patch = 'pythran-0.13.patch'
license = 'BSD-3-Clause'
[[pythran.rules]]
-version = '>= 0.14'
+version = '>= 0.14, < 0.16'
patch = 'pythran-0.15.patch'
license = 'BSD-3-Clause'
+[[pythran.rules]]
+version = '>= 0.16'
+patch = 'pythran-0.16.patch'
+license = 'BSD-3-Clause'
+
[[pyzmq.rules]]
# 26+ needs Cython 3
version = '< 26'
@@ -717,6 +774,10 @@ version = '== 3.*'
# transformers tends to depend on a specific version of tokenizers. Pin it to avoid pulling unpatched tokenizers
version = '== 4.33.3'
+[[trio.rules]]
+patch = 'trio.patch'
+license = 'Apache-2.0 OR MIT'
+
[[typing_extensions.rules]]
patch = 'typing_extensions.patch'
license = 'PSF-2.0'
@@ -732,6 +793,7 @@ version = '>= 2, < 2.0.3'
install-priority = 0
[[uvloop.rules]]
+version = '<= 0.19.0'
patch = 'uvloop.patch'
license = 'MIT'
diff --git a/graalpython/lib-graalpython/patches/numpy-2.2.4.patch b/graalpython/lib-graalpython/patches/numpy-2.2.4.patch
new file mode 100644
index 0000000000..49760fcb51
--- /dev/null
+++ b/graalpython/lib-graalpython/patches/numpy-2.2.4.patch
@@ -0,0 +1,182 @@
+diff --git a/numpy/__init__.py b/numpy/__init__.py
+index 2a4fd03..4df4f2d 100644
+--- a/numpy/__init__.py
++++ b/numpy/__init__.py
+@@ -371,7 +371,7 @@ def __getattr__(attr):
+ return char
+ elif attr == "array_api":
+ raise AttributeError("`numpy.array_api` is not available from "
+- "numpy 2.0 onwards", name=None)
++ "numpy 2.0 onwards")
+ elif attr == "core":
+ import numpy.core as core
+ return core
+@@ -384,7 +384,7 @@ def __getattr__(attr):
+ return distutils
+ else:
+ raise AttributeError("`numpy.distutils` is not available from "
+- "Python 3.12 onwards", name=None)
++ "Python 3.12 onwards")
+
+ if attr in __future_scalars__:
+ # And future warnings for those that will change, but also give
+@@ -394,13 +394,12 @@ def __getattr__(attr):
+ "corresponding NumPy scalar.", FutureWarning, stacklevel=2)
+
+ if attr in __former_attrs__:
+- raise AttributeError(__former_attrs__[attr], name=None)
++ raise AttributeError(__former_attrs__[attr])
+
+ if attr in __expired_attributes__:
+ raise AttributeError(
+ f"`np.{attr}` was removed in the NumPy 2.0 release. "
+ f"{__expired_attributes__[attr]}",
+- name=None
+ )
+
+ if attr == "chararray":
+diff --git a/numpy/_core/include/numpy/ndarrayobject.h b/numpy/_core/include/numpy/ndarrayobject.h
+index 0462625..3625e34 100644
+--- a/numpy/_core/include/numpy/ndarrayobject.h
++++ b/numpy/_core/include/numpy/ndarrayobject.h
+@@ -220,7 +220,7 @@ NPY_TITLE_KEY_check(PyObject *key, PyObject *value)
+ if (key == title) {
+ return 1;
+ }
+-#ifdef PYPY_VERSION
++#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
+ /*
+ * On PyPy, dictionary keys do not always preserve object identity.
+ * Fall back to comparison by value.
+diff --git a/numpy/_core/src/multiarray/compiled_base.c b/numpy/_core/src/multiarray/compiled_base.c
+index e3af951..48a7030 100644
+--- a/numpy/_core/src/multiarray/compiled_base.c
++++ b/numpy/_core/src/multiarray/compiled_base.c
+@@ -1465,6 +1465,7 @@ fail:
+ NPY_NO_EXPORT PyObject *
+ arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *const *args, Py_ssize_t len_args)
+ {
++#if 0 // GraalPy change
+ PyObject *obj;
+ PyObject *str;
+ const char *docstr;
+@@ -1569,6 +1570,7 @@ arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *const *args, Py_ssize_t
+ }
+
+ #undef _ADDDOC
++#endif // GraalPy change
+
+ Py_RETURN_NONE;
+ }
+diff --git a/numpy/_core/src/multiarray/shape.c b/numpy/_core/src/multiarray/shape.c
+index 340fe72..8f13674 100644
+--- a/numpy/_core/src/multiarray/shape.c
++++ b/numpy/_core/src/multiarray/shape.c
+@@ -97,6 +97,11 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck,
+ "cannot resize an array with refcheck=True on PyPy.\n"
+ "Use the np.resize function or refcheck=False");
+ return NULL;
++#elif defined(GRAALVM_PYTHON)
++ PyErr_SetString(PyExc_ValueError,
++ "cannot resize an array with refcheck=True on GraalPy.\n"
++ "Use the np.resize function or refcheck=False");
++ return NULL;
+ #else
+ refcnt = Py_REFCNT(self);
+ #endif /* PYPY_VERSION */
+diff --git a/numpy/_core/src/multiarray/stringdtype/dtype.c b/numpy/_core/src/multiarray/stringdtype/dtype.c
+index 0350375..8b254cb 100644
+--- a/numpy/_core/src/multiarray/stringdtype/dtype.c
++++ b/numpy/_core/src/multiarray/stringdtype/dtype.c
+@@ -841,7 +841,7 @@ init_string_dtype(void)
+ };
+
+ /* Loaded dynamically, so needs to be set here: */
+- Py_TYPE(((PyObject *)&PyArray_StringDType)) = &PyArrayDTypeMeta_Type;
++ Py_SET_TYPE(((PyObject *)&PyArray_StringDType), &PyArrayDTypeMeta_Type);
+ ((PyTypeObject *)&PyArray_StringDType)->tp_base = &PyArrayDescr_Type;
+ if (PyType_Ready((PyTypeObject *)&PyArray_StringDType) < 0) {
+ return -1;
+diff --git a/numpy/_core/src/multiarray/temp_elide.c b/numpy/_core/src/multiarray/temp_elide.c
+index 662a2fa..791ede8 100644
+--- a/numpy/_core/src/multiarray/temp_elide.c
++++ b/numpy/_core/src/multiarray/temp_elide.c
+@@ -58,7 +58,7 @@
+ * supported too by using the appropriate Windows APIs.
+ */
+
+-#if defined HAVE_BACKTRACE && defined HAVE_DLFCN_H && ! defined PYPY_VERSION
++#if defined HAVE_BACKTRACE && defined HAVE_DLFCN_H && ! defined PYPY_VERSION && !defined(GRAALVM_PYTHON)
+
+ #include
+
+diff --git a/numpy/_core/src/npymath/ieee754.c.src b/numpy/_core/src/npymath/ieee754.c.src
+index 8fccc9a..3bb9cf0 100644
+--- a/numpy/_core/src/npymath/ieee754.c.src
++++ b/numpy/_core/src/npymath/ieee754.c.src
+@@ -362,6 +362,11 @@ int npy_get_floatstatus_barrier(char* param)
+ * By using a volatile, the compiler cannot reorder this call
+ */
+ if (param != NULL) {
++ // GraalPy change: the pointer needs to be dereferenced to establish
++ // a data dependency to to ensure the compiler won't reorder the call
++ if (points_to_py_handle_space(param)) {
++ param = (char*)pointer_to_stub(param);
++ }
+ volatile char NPY_UNUSED(c) = *(char*)param;
+ }
+
+diff --git a/numpy/_core/src/npymath/ieee754.cpp b/numpy/_core/src/npymath/ieee754.cpp
+index 1c59bf3..519fabc 100644
+--- a/numpy/_core/src/npymath/ieee754.cpp
++++ b/numpy/_core/src/npymath/ieee754.cpp
+@@ -428,6 +428,11 @@ npy_get_floatstatus_barrier(char *param)
+ * By using a volatile, the compiler cannot reorder this call
+ */
+ if (param != NULL) {
++ // GraalPy change: the pointer needs to be dereferenced to establish
++ // a data dependency to to ensure the compiler won't reorder the call
++ if (points_to_py_handle_space(param)) {
++ param = (char*)pointer_to_stub(param);
++ }
+ volatile char NPY_UNUSED(c) = *(char *)param;
+ }
+
+diff --git a/numpy/lib/__init__.py b/numpy/lib/__init__.py
+index 928121c..bbe6a7e 100644
+--- a/numpy/lib/__init__.py
++++ b/numpy/lib/__init__.py
+@@ -70,7 +70,6 @@ def __getattr__(attr):
+ "numpy.lib.emath was an alias for emath module that was removed "
+ "in NumPy 2.0. Replace usages of numpy.lib.emath with "
+ "numpy.emath.",
+- name=None
+ )
+ elif attr in (
+ "histograms", "type_check", "nanfunctions", "function_base",
+@@ -81,13 +80,11 @@ def __getattr__(attr):
+ f"numpy.lib.{attr} is now private. If you are using a public "
+ "function, it should be available in the main numpy namespace, "
+ "otherwise check the NumPy 2.0 migration guide.",
+- name=None
+ )
+ elif attr == "arrayterator":
+ raise AttributeError(
+ "numpy.lib.arrayterator submodule is now private. To access "
+ "Arrayterator class use numpy.lib.Arrayterator.",
+- name=None
+ )
+ else:
+ raise AttributeError("module {!r} has no attribute "
+diff --git a/vendored-meson/meson/mesonbuild/utils/universal.py b/vendored-meson/meson/mesonbuild/utils/universal.py
+index 6aee268..539be8b 100644
+--- a/vendored-meson/meson/mesonbuild/utils/universal.py
++++ b/vendored-meson/meson/mesonbuild/utils/universal.py
+@@ -728,6 +728,7 @@ def windows_detect_native_arch() -> str:
+ """
+ if sys.platform != 'win32':
+ return ''
++ return 'amd64' # Workaround for GraalPy bug on Windows with kernel32.GetCurrentProcess()
+ try:
+ import ctypes
+ process_arch = ctypes.c_ushort()
diff --git a/graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch b/graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch
new file mode 100644
index 0000000000..3a9542a058
--- /dev/null
+++ b/graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch
@@ -0,0 +1,364 @@
+diff --git a/src/deserialize/deserializer.rs b/src/deserialize/deserializer.rs
+index 41cf7f1..99cd68e 100644
+--- a/src/deserialize/deserializer.rs
++++ b/src/deserialize/deserializer.rs
+@@ -292,7 +292,10 @@ impl<'de> Deserializer<'de> {
+ marker => Err(Error::InvalidType(marker)),
+ }?;
+ let value = self.deserialize()?;
++ #[cfg(not(GraalPy))]
+ let pyhash = unsafe { (*key.as_ptr().cast::()).hash };
++ #[cfg(GraalPy)]
++ let pyhash = unsafe { pyo3::ffi::PyObject_Hash(key.as_ptr()) };
+ let _ = ffi!(_PyDict_SetItem_KnownHash(
+ dict_ptr,
+ key.as_ptr(),
+@@ -471,7 +474,7 @@ impl<'de> Deserializer<'de> {
+ let ptr = ffi!(PyTuple_New(len as pyo3::ffi::Py_ssize_t));
+ for i in 0..len {
+ let elem = self.deserialize_map_key()?;
+- ffi!(PyTuple_SET_ITEM(
++ ffi!(PyTuple_SetItem(
+ ptr,
+ i as pyo3::ffi::Py_ssize_t,
+ elem.as_ptr()
+diff --git a/src/ext.rs b/src/ext.rs
+index b2573b4..9668d4f 100644
+--- a/src/ext.rs
++++ b/src/ext.rs
+@@ -22,7 +22,7 @@ unsafe extern "C" fn ext_new(
+ );
+ return null_mut();
+ }
+- let tag = PyTuple_GET_ITEM(args, 0);
++ let tag = PyTuple_GetItem(args, 0);
+ if PyLong_Check(tag) == 0 {
+ PyErr_SetString(
+ PyExc_TypeError,
+@@ -30,7 +30,7 @@ unsafe extern "C" fn ext_new(
+ );
+ return null_mut();
+ }
+- let data = PyTuple_GET_ITEM(args, 1);
++ let data = PyTuple_GetItem(args, 1);
+ if PyBytes_Check(data) == 0 {
+ PyErr_SetString(
+ PyExc_TypeError,
+diff --git a/src/ffi.rs b/src/ffi.rs
+index 4e5ddc3..20c9db4 100644
+--- a/src/ffi.rs
++++ b/src/ffi.rs
+@@ -7,13 +7,16 @@ use std::ptr::NonNull;
+ #[allow(non_snake_case)]
+ #[inline(always)]
+ pub unsafe fn PyBytes_AS_STRING(op: *mut PyObject) -> *const c_char {
+- &(*op.cast::()).ob_sval as *const c_char
++ #[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))]
++ return &(*op.cast::()).ob_sval as *const c_char;
++ #[cfg(any(PyPy, GraalPy, Py_LIMITED_API))]
++ return crate::PyBytes_AsString(op);
+ }
+
+ #[allow(non_snake_case)]
+ #[inline(always)]
+ pub unsafe fn PyBytes_GET_SIZE(op: *mut PyObject) -> Py_ssize_t {
+- (*op.cast::()).ob_size
++ Py_SIZE(op)
+ }
+
+ #[repr(C)]
+@@ -63,11 +66,21 @@ pub fn pylong_is_positive(op: *mut PyObject) -> bool {
+ unsafe { (*(op as *mut PyLongObject)).long_value.lv_tag & SIGN_MASK == 0 }
+ }
+
+-#[cfg(not(Py_3_12))]
++#[cfg(not(any(Py_3_12, GraalPy)))]
+ pub fn pylong_is_positive(op: *mut PyObject) -> bool {
+ unsafe { (*(op as *mut PyVarObject)).ob_size > 0 }
+ }
+
++extern "C" {
++ #[cfg(not(PyPy))]
++ pub fn _PyLong_Sign(v: *mut PyObject) -> c_int;
++}
++
++#[cfg(GraalPy)]
++pub fn pylong_is_positive(op: *mut PyObject) -> bool {
++ unsafe { _PyLong_Sign(op) > 0 }
++}
++
+ pub struct PyDictIter {
+ op: *mut PyObject,
+ pos: isize,
+diff --git a/src/lib.rs b/src/lib.rs
+index f10b1c4..1a9768b 100644
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -143,7 +143,7 @@ fn raise_unpackb_exception(msg: &str) -> *mut PyObject {
+ let err_msg =
+ PyUnicode_FromStringAndSize(msg.as_ptr() as *const c_char, msg.len() as isize);
+ let args = PyTuple_New(1);
+- PyTuple_SET_ITEM(args, 0, err_msg);
++ PyTuple_SetItem(args, 0, err_msg);
+ PyErr_SetObject(typeref::MsgpackDecodeError, args);
+ Py_DECREF(args);
+ };
+@@ -199,10 +199,10 @@ pub unsafe extern "C" fn unpackb(
+ if !kwnames.is_null() {
+ let tuple_size = PyTuple_GET_SIZE(kwnames);
+ for i in 0..tuple_size {
+- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t);
+- if arg == typeref::EXT_HOOK {
++ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t);
++ if PyUnicode_Compare(arg, typeref::EXT_HOOK) == 0 {
+ ext_hook = Some(NonNull::new_unchecked(*args.offset(num_args + i)));
+- } else if arg == typeref::OPTION {
++ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 {
+ optsptr = Some(NonNull::new_unchecked(*args.offset(num_args + i)));
+ } else {
+ return raise_unpackb_exception("unpackb() got an unexpected keyword argument");
+@@ -247,15 +247,15 @@ pub unsafe extern "C" fn packb(
+ if !kwnames.is_null() {
+ let tuple_size = PyTuple_GET_SIZE(kwnames);
+ for i in 0..tuple_size {
+- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t);
+- if arg == typeref::DEFAULT {
++ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t);
++ if PyUnicode_Compare(arg, typeref::DEFAULT) == 0 {
+ if unlikely!(default.is_some()) {
+ return raise_packb_exception(
+ "packb() got multiple values for argument: 'default'",
+ );
+ }
+ default = Some(NonNull::new_unchecked(*args.offset(num_args + i)));
+- } else if arg == typeref::OPTION {
++ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 {
+ if unlikely!(optsptr.is_some()) {
+ return raise_packb_exception(
+ "packb() got multiple values for argument: 'option'",
+diff --git a/src/serialize/datetime.rs b/src/serialize/datetime.rs
+index 63212d6..5ac2b2b 100644
+--- a/src/serialize/datetime.rs
++++ b/src/serialize/datetime.rs
+@@ -61,9 +61,14 @@ pub struct Time {
+
+ impl Time {
+ pub fn new(ptr: *mut pyo3::ffi::PyObject, opts: Opt) -> Result {
++ #[cfg(not(GraalPy))]
+ if unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_Time)).hastzinfo != 0 } {
+ return Err(TimeError::HasTimezone);
+ }
++ #[cfg(GraalPy)]
++ if unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(ptr) != crate::typeref::NONE } {
++ return Err(TimeError::HasTimezone);
++ }
+ Ok(Time {
+ ptr: ptr,
+ opts: opts,
+@@ -114,23 +119,28 @@ impl std::fmt::Display for DateTimeError {
+ }
+
+ fn utcoffset(ptr: *mut pyo3::ffi::PyObject) -> Result {
++ #[cfg(not(GraalPy))]
+ if !unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 } {
+ return Ok(Offset::default());
+ }
+
+ let tzinfo = ffi!(PyDateTime_DATE_GET_TZINFO(ptr));
++ #[cfg(GraalPy)]
++ if unsafe { tzinfo == crate::typeref::NONE } {
++ return Ok(Offset::default());
++ }
+ let py_offset: *mut pyo3::ffi::PyObject;
+ if ffi!(PyObject_HasAttr(tzinfo, CONVERT_METHOD_STR)) == 1 {
+ // pendulum
+- py_offset = ffi!(PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR));
++ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR) };
+ } else if ffi!(PyObject_HasAttr(tzinfo, NORMALIZE_METHOD_STR)) == 1 {
+ // pytz
+- let normalized = ffi!(PyObject_CallMethodOneArg(tzinfo, NORMALIZE_METHOD_STR, ptr));
+- py_offset = ffi!(PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR));
++ let normalized = ffi!(PyObject_CallMethodObjArgs(tzinfo, NORMALIZE_METHOD_STR, ptr, std::ptr::null_mut::()));
++ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR) };
+ ffi!(Py_DECREF(normalized));
+ } else if ffi!(PyObject_HasAttr(tzinfo, DST_STR)) == 1 {
+ // dateutil/arrow, datetime.timezone.utc
+- py_offset = ffi!(PyObject_CallMethodOneArg(tzinfo, UTCOFFSET_METHOD_STR, ptr));
++ py_offset = ffi!(PyObject_CallMethodObjArgs(tzinfo, UTCOFFSET_METHOD_STR, ptr, std::ptr::null_mut::()));
+ } else {
+ return Err(DateTimeError::LibraryUnsupported);
+ }
+@@ -193,7 +203,10 @@ impl TimeLike for DateTime {
+
+ impl DateTimeLike for DateTime {
+ fn has_tz(&self) -> bool {
+- unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 }
++ #[cfg(not(GraalPy))]
++ return unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 };
++ #[cfg(GraalPy)]
++ return unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(self.ptr) != crate::typeref::NONE };
+ }
+
+ fn offset(&self) -> Offset {
+diff --git a/src/serialize/numpy.rs b/src/serialize/numpy.rs
+index afc5cdf..4d007bd 100644
+--- a/src/serialize/numpy.rs
++++ b/src/serialize/numpy.rs
+@@ -392,8 +392,8 @@ impl NumpyDatetimeUnit {
+ fn from_pyobject(ptr: *mut PyObject) -> Self {
+ let dtype = ffi!(PyObject_GetAttr(ptr, DTYPE_STR));
+ let descr = ffi!(PyObject_GetAttr(dtype, DESCR_STR));
+- let el0 = ffi!(PyList_GET_ITEM(descr, 0));
+- let descr_str = ffi!(PyTuple_GET_ITEM(el0, 1));
++ let el0 = ffi!(PyList_GetItem(descr, 0));
++ let descr_str = ffi!(PyTuple_GetItem(el0, 1));
+ let uni = crate::unicode::unicode_to_str(descr_str).unwrap();
+ if uni.len() < 5 {
+ return Self::NaT;
+diff --git a/src/serialize/serializer.rs b/src/serialize/serializer.rs
+index 309e6e1..6f7dec7 100644
+--- a/src/serialize/serializer.rs
++++ b/src/serialize/serializer.rs
+@@ -864,7 +864,7 @@ impl Serialize for DictTupleKey {
+ let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize;
+ let mut seq = serializer.serialize_seq(Some(len)).unwrap();
+ for i in 0..len {
+- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize));
++ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize));
+ let value = DictKey::new(item, self.opts, self.recursion + 1);
+ seq.serialize_element(&value)?;
+ }
+diff --git a/src/serialize/tuple.rs b/src/serialize/tuple.rs
+index fa81cb6..9b66019 100644
+--- a/src/serialize/tuple.rs
++++ b/src/serialize/tuple.rs
+@@ -41,7 +41,7 @@ impl Serialize for Tuple {
+ let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize;
+ let mut seq = serializer.serialize_seq(Some(len)).unwrap();
+ for i in 0..len {
+- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize));
++ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize));
+ let value = PyObject::new(
+ item,
+ self.opts,
+diff --git a/src/serialize/writer.rs b/src/serialize/writer.rs
+index a790bdd..35346d9 100644
+--- a/src/serialize/writer.rs
++++ b/src/serialize/writer.rs
+@@ -27,7 +27,6 @@ impl BytesWriter {
+ pub fn finish(&mut self) -> NonNull {
+ unsafe {
+ std::ptr::write(self.buffer_ptr(), 0);
+- (*self.bytes.cast::()).ob_size = self.len as Py_ssize_t;
+ self.resize(self.len);
+ NonNull::new_unchecked(self.bytes as *mut PyObject)
+ }
+@@ -35,10 +34,14 @@ impl BytesWriter {
+
+ fn buffer_ptr(&self) -> *mut u8 {
+ unsafe {
+- std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!(
++ #[cfg(not(GraalPy))]
++ return std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!(
+ (*self.bytes).ob_sval
+ ))
+- .add(self.len)
++ .add(self.len);
++ #[cfg(GraalPy)]
++ return std::mem::transmute::<*mut i8, *mut u8>(PyBytes_AsString(self.bytes.cast::()))
++ .add(self.len);
+ }
+ }
+
+diff --git a/src/unicode.rs b/src/unicode.rs
+index 53aca09..552fa6c 100644
+--- a/src/unicode.rs
++++ b/src/unicode.rs
+@@ -6,6 +6,7 @@ use pyo3::ffi::*;
+
+ // see unicodeobject.h for documentation
+
++#[cfg(not(GraalPy))]
+ pub fn unicode_from_str(buf: &str) -> *mut PyObject {
+ if buf.is_empty() {
+ ffi!(Py_INCREF(EMPTY_UNICODE));
+@@ -27,6 +28,13 @@ pub fn unicode_from_str(buf: &str) -> *mut PyObject {
+ }
+ }
+
++#[cfg(GraalPy)]
++pub fn unicode_from_str(buf: &str) -> *mut PyObject {
++ unsafe {
++ PyUnicode_FromStringAndSize(buf.as_ptr() as *const i8, buf.len() as isize)
++ }
++}
++
+ fn pyunicode_ascii(buf: &str) -> *mut PyObject {
+ unsafe {
+ let ptr = ffi!(PyUnicode_New(buf.len() as isize, 127));
+@@ -80,6 +88,7 @@ fn pyunicode_fourbyte(buf: &str, num_chars: usize) -> *mut PyObject {
+
+ #[inline]
+ pub fn hash_str(op: *mut PyObject) -> Py_hash_t {
++ #[cfg(not(GraalPy))]
+ unsafe {
+ let data_ptr: *mut c_void = if (*op.cast::()).compact() == 1
+ && (*op.cast::()).ascii() == 1
+@@ -92,7 +101,11 @@ pub fn hash_str(op: *mut PyObject) -> Py_hash_t {
+ (*(op as *mut PyASCIIObject)).length * ((*(op as *mut PyASCIIObject)).kind()) as isize;
+ let hash = _Py_HashBytes(data_ptr, num_bytes);
+ (*op.cast::()).hash = hash;
+- hash
++ return hash;
++ }
++ #[cfg(GraalPy)]
++ unsafe {
++ return PyObject_Hash(op);
+ }
+ }
+
+@@ -109,19 +122,24 @@ pub fn unicode_to_str_via_ffi(op: *mut PyObject) -> Option<&'static str> {
+
+ #[inline]
+ pub fn unicode_to_str(op: *mut PyObject) -> Option<&'static str> {
++ #[cfg(not(GraalPy))]
+ unsafe {
+ if unlikely!((*op.cast::()).compact() == 0) {
+- unicode_to_str_via_ffi(op)
++ return unicode_to_str_via_ffi(op);
+ } else if (*op.cast::()).ascii() == 1 {
+ let ptr = op.cast::().offset(1) as *const u8;
+ let len = (*op.cast::()).length as usize;
+- Some(str_from_slice!(ptr, len))
++ return Some(str_from_slice!(ptr, len));
+ } else if (*op.cast::()).utf8_length != 0 {
+ let ptr = (*op.cast::()).utf8 as *const u8;
+ let len = (*op.cast::()).utf8_length as usize;
+- Some(str_from_slice!(ptr, len))
++ return Some(str_from_slice!(ptr, len));
+ } else {
+- unicode_to_str_via_ffi(op)
++ return unicode_to_str_via_ffi(op);
+ }
+ }
++ #[cfg(GraalPy)]
++ unsafe {
++ return unicode_to_str_via_ffi(op);
++ }
+ }
+diff --git a/src/util.rs b/src/util.rs
+index 2bcc32d..89faf1a 100644
+--- a/src/util.rs
++++ b/src/util.rs
+@@ -8,7 +8,7 @@ macro_rules! py_is {
+
+ macro_rules! ob_type {
+ ($obj:expr) => {
+- unsafe { (*($obj as *mut pyo3::ffi::PyObject)).ob_type }
++ unsafe { pyo3::ffi::Py_TYPE($obj as *mut pyo3::ffi::PyObject) }
+ };
+ }
+
+--
+2.43.0
+
diff --git a/graalpython/lib-graalpython/patches/pandas-2.2.3.patch b/graalpython/lib-graalpython/patches/pandas-2.2.3.patch
new file mode 100644
index 0000000000..1312dfbb7d
--- /dev/null
+++ b/graalpython/lib-graalpython/patches/pandas-2.2.3.patch
@@ -0,0 +1,52 @@
+diff --git a/pandas/_libs/include/pandas/vendored/klib/khash_python.h b/pandas/_libs/include/pandas/vendored/klib/khash_python.h
+index 5a933b4..f579fc6 100644
+--- a/pandas/_libs/include/pandas/vendored/klib/khash_python.h
++++ b/pandas/_libs/include/pandas/vendored/klib/khash_python.h
+@@ -173,13 +173,15 @@ static inline int floatobject_cmp(PyFloatObject *a, PyFloatObject *b) {
+ // PyObject_RichCompareBool for complexobjects has a different behavior
+ // needs to be replaced
+ static inline int complexobject_cmp(PyComplexObject *a, PyComplexObject *b) {
+- return (Py_IS_NAN(a->cval.real) && Py_IS_NAN(b->cval.real) &&
+- Py_IS_NAN(a->cval.imag) && Py_IS_NAN(b->cval.imag)) ||
+- (Py_IS_NAN(a->cval.real) && Py_IS_NAN(b->cval.real) &&
+- a->cval.imag == b->cval.imag) ||
+- (a->cval.real == b->cval.real && Py_IS_NAN(a->cval.imag) &&
+- Py_IS_NAN(b->cval.imag)) ||
+- (a->cval.real == b->cval.real && a->cval.imag == b->cval.imag);
++ Py_complex a_cval = PyComplex_AsCComplex((PyObject*)a);
++ Py_complex b_cval = PyComplex_AsCComplex((PyObject*)b);
++ return (Py_IS_NAN(a_cval.real) && Py_IS_NAN(b_cval.real) &&
++ Py_IS_NAN(a_cval.imag) && Py_IS_NAN(b_cval.imag)) ||
++ (Py_IS_NAN(a_cval.real) && Py_IS_NAN(b_cval.real) &&
++ a_cval.imag == b_cval.imag) ||
++ (a_cval.real == b_cval.real && Py_IS_NAN(a_cval.imag) &&
++ Py_IS_NAN(b_cval.imag)) ||
++ (a_cval.real == b_cval.real && a_cval.imag == b_cval.imag);
+ }
+
+ static inline int pyobject_cmp(PyObject *a, PyObject *b);
+@@ -250,8 +252,9 @@ static inline Py_hash_t floatobject_hash(PyFloatObject *key) {
+
+ // replaces _Py_HashDouble with _Pandas_HashDouble
+ static inline Py_hash_t complexobject_hash(PyComplexObject *key) {
+- Py_uhash_t realhash = (Py_uhash_t)_Pandas_HashDouble(key->cval.real);
+- Py_uhash_t imaghash = (Py_uhash_t)_Pandas_HashDouble(key->cval.imag);
++ Py_complex cval = PyComplex_AsCComplex((PyObject*)key);
++ Py_uhash_t realhash = (Py_uhash_t)_Pandas_HashDouble(cval.real);
++ Py_uhash_t imaghash = (Py_uhash_t)_Pandas_HashDouble(cval.imag);
+ if (realhash == (Py_uhash_t)-1 || imaghash == (Py_uhash_t)-1) {
+ return -1;
+ }
+diff --git a/pyproject.toml b/pyproject.toml
+index db9f055..c191232 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -5,7 +5,7 @@ requires = [
+ "meson-python==0.13.1",
+ "meson==1.2.1",
+ "wheel",
+- "Cython~=3.0.5", # Note: sync with setup.py, environment.yml and asv.conf.json
++ "Cython==3.0.10", # Note: sync with setup.py, environment.yml and asv.conf.json
+ # Force numpy higher than 2.0, so that built wheels are compatible
+ # with both numpy 1 and 2
+ "numpy>=2.0",
diff --git a/graalpython/lib-graalpython/patches/psycopg2.patch b/graalpython/lib-graalpython/patches/psycopg2-2.9.10.patch
similarity index 51%
rename from graalpython/lib-graalpython/patches/psycopg2.patch
rename to graalpython/lib-graalpython/patches/psycopg2-2.9.10.patch
index a3d7e3aa2d..1b35cdc301 100644
--- a/graalpython/lib-graalpython/patches/psycopg2.patch
+++ b/graalpython/lib-graalpython/patches/psycopg2-2.9.10.patch
@@ -1,15 +1,15 @@
diff --git a/psycopg/utils.c b/psycopg/utils.c
-index 16be906..c78a24b 100644
+index 1dfb87d..28cc6c1 100644
--- a/psycopg/utils.c
+++ b/psycopg/utils.c
@@ -392,7 +392,9 @@ psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg)
static int
psyco_is_main_interp(void)
{
--#if PY_VERSION_HEX >= 0x03080000
+-#if PY_VERSION_HEX >= 0x030d0000
+#if GRAALVM_PYTHON
+ return 1;
-+#elif PY_VERSION_HEX >= 0x03080000
- /* tested with Python 3.8.0a2 */
- return _PyInterpreterState_Get() == PyInterpreterState_Main();
- #else
++#elif PY_VERSION_HEX >= 0x030d0000
+ /* tested with Python 3.13.0a6 */
+ return PyInterpreterState_Get() == PyInterpreterState_Main();
+ #elif PY_VERSION_HEX >= 0x03080000
diff --git a/graalpython/lib-graalpython/patches/psycopg2-binary.patch b/graalpython/lib-graalpython/patches/psycopg2-2.9.9.patch
similarity index 100%
rename from graalpython/lib-graalpython/patches/psycopg2-binary.patch
rename to graalpython/lib-graalpython/patches/psycopg2-2.9.9.patch
diff --git a/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch b/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch
new file mode 100644
index 0000000000..70adda0ede
--- /dev/null
+++ b/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch
@@ -0,0 +1,164 @@
+diff --git a/pyarrow/error.pxi b/pyarrow/error.pxi
+index cbe2552..8d0d9d9 100644
+--- a/pyarrow/error.pxi
++++ b/pyarrow/error.pxi
+@@ -248,7 +248,7 @@ cdef class SignalStopHandler:
+ if exc_value.signum:
+ # Re-emit the exact same signal. We restored the Python signal
+ # handler above, so it should receive it.
+- if os.name == 'nt':
++ if os.name == 'nt' or sys.implementation.name == 'graalpy':
+ SendSignal(exc_value.signum)
+ else:
+ SendSignalToThread(exc_value.signum,
+diff --git a/pyarrow/memory.pxi b/pyarrow/memory.pxi
+index 1ddcb01..6805e42 100644
+--- a/pyarrow/memory.pxi
++++ b/pyarrow/memory.pxi
+@@ -20,6 +20,10 @@
+ # cython: embedsignature = True
+
+
++cdef extern from "Python.h":
++ void Py_INCREF(object)
++
++
+ cdef class MemoryPool(_Weakrefable):
+ """
+ Base class for memory allocation.
+@@ -35,6 +39,13 @@ cdef class MemoryPool(_Weakrefable):
+
+ cdef void init(self, CMemoryPool* pool):
+ self.pool = pool
++ # GraalPy change: pyarrow doesn't maintain python references from
++ # buffers to pools, but they dereference the pointer to the pool in the
++ # destructor. They just assume buffers will get GC'ed before their
++ # pools. You can easily get a segfault even on CPython if you make
++ # a buffer outlive its pool. Since we can't guarantee destruction
++ # order, we just leak the pool.
++ Py_INCREF(self)
+
+ def release_unused(self):
+ """
+diff --git a/pyarrow_build_backend.py b/pyarrow_build_backend.py
+new file mode 100644
+index 0000000..0929c5f
+--- /dev/null
++++ b/pyarrow_build_backend.py
+@@ -0,0 +1,93 @@
++import os
++import re
++import sys
++import tarfile
++import subprocess
++import tempfile
++import shutil
++import tarfile
++import urllib.request
++from pathlib import Path
++
++VERSION = '19.0.0'
++
++
++def build_sdist(sdist_directory, config_settings=None):
++ nv = f'pyarrow-{VERSION}'
++ srcdir = Path(__file__).parent
++ archive_path = Path(sdist_directory) / f'{nv}.tar.gz'
++
++ def tarfilter(info):
++ if re.match(r'\./(?:.git|venv|[^-/]+-venv|dist)', info.name):
++ return None
++ info.name = f'./{nv}/{info.name}'
++ return info
++
++ with tarfile.open(archive_path, 'w:gz') as tar:
++ tar.add('.', filter=tarfilter)
++ return archive_path.name
++
++
++def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
++ wheel_directory = Path(wheel_directory).absolute()
++ with tempfile.TemporaryDirectory() as tmpdir:
++ tmpdir = Path(tmpdir).absolute()
++ tarname = f'apache-arrow-{VERSION}.tar.gz'
++ tarpath = tmpdir / tarname
++ urllib.request.urlretrieve(f"https://github.com/apache/arrow/archive/refs/tags/{tarname}", tarpath)
++ with tarfile.open(tarpath) as tar:
++ tar.extractall(tmpdir)
++ arrow_dir = tmpdir / f'arrow-apache-arrow-{VERSION}'
++ assert arrow_dir.is_dir()
++ arrow_dist = tmpdir / 'arrow-dist'
++ build_dir = tmpdir / 'arrow-build'
++ subprocess.check_call([
++ 'cmake', '-S', str(arrow_dir / 'cpp'), '-B', str(build_dir),
++ '-DCMAKE_INSTALL_LIBDIR=lib',
++ f'-DCMAKE_INSTALL_PREFIX={arrow_dist}',
++ '-DCMAKE_BUILD_TYPE=Release',
++ '-DARROW_RPATH_ORIGIN=ON',
++ '-DARROW_BUILD_TESTS=OFF',
++ '-DARROW_BUILD_SHARED=ON',
++ '-DARROW_BUILD_STATIC=OFF',
++ # Features
++ '-DARROW_COMPUTE=ON',
++ '-DARROW_CSV=ON',
++ '-DARROW_JSON=ON',
++ '-DARROW_FILESYSTEM=ON',
++ '-DARROW_DATASET=ON',
++ '-DARROW_PARQUET=ON',
++ '-DPARQUET_REQUIRE_ENCRYPTION=ON',
++ '-DARROW_GANDIVA=ON',
++ '-DARROW_WITH_BZ2=ON',
++ '-DARROW_WITH_ZLIB=ON',
++ '-DARROW_WITH_ZSTD=ON',
++ '-DARROW_WITH_LZ4=ON',
++ '-DARROW_WITH_SNAPPY=ON',
++ '-DARROW_WITH_BROTLI=ON',
++ ])
++ subprocess.check_call([
++ 'cmake', '--build', str(build_dir), '--parallel',
++ ])
++ subprocess.check_call([
++ 'cmake', '--install', str(build_dir),
++ ])
++ env = os.environ.copy()
++ env['ARROW_HOME'] = str(arrow_dist)
++ env['CMAKE_PREFIX_PATH'] = str(arrow_dist)
++ env['PYARROW_WITH_DATASET'] = '1'
++ env['PYARROW_WITH_PARQUET'] = '1'
++ env['PYARROW_WITH_PARQUET_ENCRYPTION'] = '1'
++ env['PYARROW_WITH_GANDIVA'] = '1'
++ env['PYARROW_BUNDLE_ARROW_CPP'] = '1'
++ env['PYARROW_BUNDLE_CYTHON_CPP'] = '1'
++ subprocess.run(
++ [sys.executable, 'setup.py', 'bdist_wheel'],
++ env=env,
++ check=True,
++ )
++ wheels = list(Path('dist').glob('*.whl'))
++ assert len(wheels) == 1, f"Expected 1 wheel, found {len(wheels)}"
++ wheel = wheels[0]
++ shutil.copyfile(wheel, wheel_directory / wheel.name)
++ return str(wheel.name)
+diff --git a/pyproject.toml b/pyproject.toml
+index ef2043f..cb08a86 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -17,7 +17,7 @@
+
+ [build-system]
+ requires = [
+- "cython >= 0.29.31",
++ "cython >= 0.29.31, < 3",
+ # Starting with NumPy 1.25, NumPy is (by default) as far back compatible
+ # as oldest-support-numpy was (customizable with a NPY_TARGET_VERSION
+ # define). For older Python versions (where NumPy 1.25 is not yet available)
+@@ -29,7 +29,8 @@ requires = [
+ "setuptools_scm[toml]>=8",
+ "setuptools>=64",
+ ]
+-build-backend = "setuptools.build_meta"
++build-backend = "pyarrow_build_backend"
++backend-path = ["."]
+
+ [project]
+ name = "pyarrow"
diff --git a/graalpython/lib-graalpython/patches/pymupdf.patch b/graalpython/lib-graalpython/patches/pymupdf.patch
new file mode 100644
index 0000000000..27869eccd6
--- /dev/null
+++ b/graalpython/lib-graalpython/patches/pymupdf.patch
@@ -0,0 +1,124 @@
+diff --git a/graalpy-config b/graalpy-config
+new file mode 100755
+index 00000000..1f69f726
+--- /dev/null
++++ b/graalpy-config
+@@ -0,0 +1,78 @@
++#!/bin/sh
++
++# Adapted from CPython but deferring to GraalPy
++
++exit_with_usage ()
++{
++ echo "Usage: $0 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--help|--abiflags|--configdir|--embed"
++ exit $1
++}
++
++if [ "$1" = "" ] ; then
++ exit_with_usage 1
++fi
++
++# Returns the actual prefix where this script was installed to.
++EXE=$(cd $(dirname "$0") && pwd -P)
++if which readlink >/dev/null 2>&1 ; then
++ if readlink -f "$RESULT" >/dev/null 2>&1; then
++ EXE=$(readlink -f "$RESULT")
++ fi
++fi
++EXE=$EXE/graalpy
++
++if ! test -x "$EXE" ; then
++ EXE=graalpy
++fi
++
++# Scan for --help or unknown argument.
++for ARG in $*
++do
++ case $ARG in
++ --help)
++ exit_with_usage 0
++ ;;
++ --embed)
++ echo "graalpy-config does not print embedding flags"
++ exit 1
++ ;;
++ --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--abiflags|--configdir)
++ ;;
++ *)
++ exit_with_usage 1
++ ;;
++ esac
++done
++
++for ARG in "$@"
++do
++ case "$ARG" in
++ --prefix)
++ $EXE -c "print(__import__('sysconfig').get_config_var('prefix'))"
++ ;;
++ --exec-prefix)
++ $EXE -c "print(__import__('sysconfig').get_config_var('exec_prefix'))"
++ ;;
++ --includes)
++ $EXE -c "from sysconfig import get_path; print('-I'+get_path('include'), '-I'+get_path('platinclude'))"
++ ;;
++ --cflags)
++ $EXE -c "import sysconfig as s; print('-I' + s.get_path('include'), '-I' + s.get_path('platinclude'), s.get_config_var('CFLAGS').replace('NDEBUG', 'DEBUG'), s.get_config_var('OPT').replace('NDEBUG', 'DEBUG'))"
++ ;;
++ --libs)
++ $EXE -c "import sysconfig as s; print('-L' + s.get_config_var('LIBDIR'))"
++ ;;
++ --ldflags)
++ $EXE -c "import sysconfig as s; print('-L' + s.get_config_var('LIBDIR'))"
++ ;;
++ --extension-suffix)
++ $EXE -c "import sysconfig as s; print(s.get_config_var('EXT_SUFFIX'))"
++ ;;
++ --abiflags)
++ $EXE -c "import sysconfig as s; print(s.get_config_var('ABIFLAGS'))"
++ ;;
++ --configdir)
++ echo ""
++ ;;
++esac
++done
+diff --git a/setup.py b/setup.py
+index 5fba2c97..3fe63b07 100755
+--- a/setup.py
++++ b/setup.py
+@@ -1452,0 +1452,35 @@
++if sys.implementation.name == "graalpy":
++ import os
++ import re
++ import subprocess
++ import shutil
++ import sysconfig
++ from pathlib import Path
++
++ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
++ wheel_directory = Path(wheel_directory).absolute()
++ sdir = Path(__file__).absolute().parent
++ python311 = shutil.which("python3.11")
++ if not python311:
++ raise RuntimeError("python3.11 must be available on the PATH for cross-compilation")
++ env = os.environ.copy()
++ env["PIPCL_PYTHON_CONFIG"] = str(sdir / "graalpy-config")
++ env["PYMUPDF_SETUP_PY_LIMITED_API"] = "1"
++ subprocess.run(
++ [python311, "setup.py", "bdist_wheel"],
++ env=env,
++ cwd=sdir,
++ check=True,
++ )
++ wheels = list((sdir / 'dist').glob('*.whl'))
++ assert len(wheels) == 1, f"Expected 1 wheel, found {len(wheels)}"
++ wheel = wheels[0]
++ assert "-cp311-abi3" in wheel.name, f"Expected wheel to be for CPython 3.11 ABI 3, got {wheel.name}"
++ graalpy_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX")
++ m = re.match(r"\.graalpy(\d+[^\-]*)-(\d+)", sysconfig.get_config_var("EXT_SUFFIX"))
++ gpver = m[1]
++ cpver = m[2]
++ graalpy_wheel_tag = f"graalpy{cpver}-graalpy{gpver}_{cpver}_native"
++ name = wheel.name.replace("cp311-abi3", graalpy_wheel_tag)
++ shutil.copyfile(wheel, wheel_directory / name)
++ return str(name)
diff --git a/graalpython/lib-graalpython/patches/pythran-0.16.patch b/graalpython/lib-graalpython/patches/pythran-0.16.patch
new file mode 100644
index 0000000000..3fda5ec7ab
--- /dev/null
+++ b/graalpython/lib-graalpython/patches/pythran-0.16.patch
@@ -0,0 +1,70 @@
+diff --git a/pythran/pythonic/python/core.hpp b/pythran/pythonic/python/core.hpp
+index 4cbe3e0..24340b0 100644
+--- a/pythran/pythonic/python/core.hpp
++++ b/pythran/pythonic/python/core.hpp
+@@ -53,7 +53,14 @@ namespace python
+ {
+
+ #ifndef PyString_AS_STRING
+-#define PyString_AS_STRING (char *)_PyUnicode_COMPACT_DATA
++ static inline const char* PyString_AS_STRING(PyObject* obj) {
++ const char* str = PyUnicode_AsUTF8(obj);
++ if (!str) {
++ PyErr_Clear();
++ str = "";
++ }
++ return str;
++ }
+ #endif
+
+ inline void PyObject_TypePrettyPrinter(std::ostream &oss, PyObject *obj)
+diff --git a/pythran/pythonic/types/str.hpp b/pythran/pythonic/types/str.hpp
+index e5dbe60..41d1658 100644
+--- a/pythran/pythonic/types/str.hpp
++++ b/pythran/pythonic/types/str.hpp
+@@ -741,10 +741,17 @@ namespace std
+ #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
+
+ #ifndef PyString_Check
+-#define PyString_Check(x) PyUnicode_Check(x) && PyUnicode_IS_COMPACT_ASCII(x)
++#define PyString_Check(x) PyUnicode_Check(x)
+ #endif
+ #ifndef PyString_AS_STRING
+-#define PyString_AS_STRING (char *)_PyUnicode_COMPACT_DATA
++ static inline const char* PyString_AS_STRING(PyObject* obj) {
++ const char* str = PyUnicode_AsUTF8(obj);
++ if (!str) {
++ PyErr_Clear();
++ str = "";
++ }
++ return str;
++ }
+ #endif
+ #ifndef PyString_GET_SIZE
+ #define PyString_GET_SIZE PyUnicode_GET_LENGTH
+diff --git a/pythran/tables.py b/pythran/tables.py
+index d62abe1..4ba279d 100644
+--- a/pythran/tables.py
++++ b/pythran/tables.py
+@@ -4617,7 +4617,10 @@ def save_arguments(module_name, elements):
+ # some function are actually forward function, detect those
+ # and accept to use our description instead.
+ if looks_like_a_forward_function(spec):
+- assert signature.args.args, "{} require an explicit description".format(elem)
++ # GraalPy change: we have signatures for more builtins than
++ # CPython and this trips up on type constructors like `dict` or
++ # `BaseException`.
++ # assert signature.args.args, "{} require an explicit description".format(elem)
+ continue
+
+ args = [ast.Name(arg, ast.Param(), None, None)
+@@ -4630,7 +4633,8 @@ def save_arguments(module_name, elements):
+ defaults = list(spec.defaults or [])
+ args += [ast.Name(arg, ast.Param(), None, None)
+ for arg in spec.kwonlyargs]
+- defaults += [spec.kwonlydefaults[kw] for kw in spec.kwonlyargs]
++ if spec.kwonlydefaults:
++ defaults += [spec.kwonlydefaults[kw] for kw in spec.kwonlyargs]
+
+ # Check if we already have a pythran description for that object
+ if signature.args.args:
diff --git a/graalpython/lib-graalpython/patches/torch-2.4.1.patch b/graalpython/lib-graalpython/patches/torch-2.4.1.patch
index 5f7724d365..3dc4d354e3 100644
--- a/graalpython/lib-graalpython/patches/torch-2.4.1.patch
+++ b/graalpython/lib-graalpython/patches/torch-2.4.1.patch
@@ -178,6 +178,19 @@ index f5fdbf155..d76176cb6 100644
class TestWrapperSubclassAliasing(TestCase):
+diff --git a/third_party/fbgemm/CMakeLists.txt b/third_party/fbgemm/CMakeLists.txt
+index 134523e7d..a00538e3c 100644
+--- a/third_party/fbgemm/CMakeLists.txt
++++ b/third_party/fbgemm/CMakeLists.txt
+@@ -10,6 +10,8 @@
+
+ cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
+
++add_compile_options(-Wno-error=maybe-uninitialized -Wno-error=uninitialized -Wno-error=restrict)
++
+ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
+
+ # Define function to extract filelists from defs.bzl file
diff --git a/third_party/pybind11/include/pybind11/detail/common.h b/third_party/pybind11/include/pybind11/detail/common.h
index 454e6061b..7feafc7d7 100644
--- a/third_party/pybind11/include/pybind11/detail/common.h
@@ -614,6 +627,24 @@ index cbe9ab37a..18740a0d8 100644
return module;
}
+diff --git a/torch/csrc/dynamo/extra_state.cpp b/torch/csrc/dynamo/extra_state.cpp
+index 7c9b4be00..b8edbcfda 100644
+--- a/torch/csrc/dynamo/extra_state.cpp
++++ b/torch/csrc/dynamo/extra_state.cpp
+@@ -65,11 +65,13 @@ void destroy_extra_state(void* obj) {
+ }
+
+ void set_extra_state(PyCodeObject* code, ExtraState* extra_state) {
++#if 0 // GraalPy change
+ ExtraState* old_extra_state = get_extra_state(code);
+ CHECK(
+ old_extra_state == nullptr || old_extra_state == SKIP_CODE ||
+ old_extra_state != extra_state);
+ _PyCode_SetExtra((PyObject*)code, extra_index, extra_state);
++#endif // GraalPy change
+ }
+
+ ExtraState* init_and_set_extra_state(PyCodeObject* code) {
diff --git a/torch/csrc/jit/python/python_tracer.cpp b/torch/csrc/jit/python/python_tracer.cpp
index 92e6e2d3a..4d2ec0bfe 100644
--- a/torch/csrc/jit/python/python_tracer.cpp
diff --git a/graalpython/lib-graalpython/patches/trio.patch b/graalpython/lib-graalpython/patches/trio.patch
new file mode 100644
index 0000000000..dee5d3d252
--- /dev/null
+++ b/graalpython/lib-graalpython/patches/trio.patch
@@ -0,0 +1,103 @@
+diff --git a/trio/_socket.py b/trio/_socket.py
+index 003f6c4..da7411c 100644
+--- a/trio/_socket.py
++++ b/trio/_socket.py
+@@ -317,9 +317,7 @@ def fromfd(
+ return from_stdlib_socket(_stdlib_socket.fromfd(fd, family, type_, proto))
+
+
+-if sys.platform == "win32" or (
+- not TYPE_CHECKING and hasattr(_stdlib_socket, "fromshare")
+-):
++if hasattr(_stdlib_socket, "fromshare"):
+
+ @_wraps(_stdlib_socket.fromshare, assigned=(), updated=())
+ def fromshare(info: bytes) -> SocketType:
+@@ -606,9 +604,7 @@ class SocketType:
+ def set_inheritable(self, inheritable: bool) -> None:
+ raise NotImplementedError
+
+- if sys.platform == "win32" or (
+- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "share")
+- ):
++ if hasattr(_stdlib_socket.socket, "share"):
+
+ def share(self, process_id: int) -> bytes:
+ raise NotImplementedError
+@@ -699,9 +695,7 @@ class SocketType:
+ ) -> Awaitable[tuple[int, AddressFormat]]:
+ raise NotImplementedError
+
+- if sys.platform != "win32" or (
+- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg")
+- ):
++ if hasattr(_stdlib_socket.socket, "recvmsg"):
+
+ def recvmsg(
+ self,
+@@ -712,9 +706,7 @@ class SocketType:
+ ) -> Awaitable[tuple[bytes, list[tuple[int, int, bytes]], int, object]]:
+ raise NotImplementedError
+
+- if sys.platform != "win32" or (
+- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg_into")
+- ):
++ if hasattr(_stdlib_socket.socket, "recvmsg_into"):
+
+ def recvmsg_into(
+ self,
+@@ -748,9 +740,7 @@ class SocketType:
+ async def sendto(self, *args: object) -> int:
+ raise NotImplementedError
+
+- if sys.platform != "win32" or (
+- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "sendmsg")
+- ):
++ if hasattr(_stdlib_socket.socket, "sendmsg"):
+
+ @_wraps(_stdlib_socket.socket.sendmsg, assigned=(), updated=())
+ async def sendmsg(
+@@ -867,9 +857,7 @@ class _SocketType(SocketType):
+ def set_inheritable(self, inheritable: bool) -> None:
+ return self._sock.set_inheritable(inheritable)
+
+- if sys.platform == "win32" or (
+- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "share")
+- ):
++ if hasattr(_stdlib_socket.socket, "share"):
+
+ def share(self, process_id: int) -> bytes:
+ return self._sock.share(process_id)
+@@ -1181,9 +1169,7 @@ class _SocketType(SocketType):
+ # recvmsg
+ ################################################################
+
+- if sys.platform != "win32" or (
+- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg")
+- ):
++ if hasattr(_stdlib_socket.socket, "recvmsg"):
+ if TYPE_CHECKING:
+
+ def recvmsg(
+@@ -1204,9 +1190,7 @@ class _SocketType(SocketType):
+ # recvmsg_into
+ ################################################################
+
+- if sys.platform != "win32" or (
+- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg_into")
+- ):
++ if hasattr(_stdlib_socket.socket, "recvmsg_into"):
+ if TYPE_CHECKING:
+
+ def recvmsg_into(
+@@ -1276,9 +1260,7 @@ class _SocketType(SocketType):
+ # sendmsg
+ ################################################################
+
+- if sys.platform != "win32" or (
+- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "sendmsg")
+- ):
++ if hasattr(_stdlib_socket.socket, "sendmsg"):
+
+ @_wraps(_stdlib_socket.socket.sendmsg, assigned=(), updated=())
+ async def sendmsg(
diff --git a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java
index 7efc01cd3a..fa26d06389 100644
--- a/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java
+++ b/graalpython/org.graalvm.python.embedding/src/org/graalvm/python/embedding/GraalPyResources.java
@@ -198,7 +198,12 @@ private GraalPyResources() {
* location
* /org.graalvm.python.vfs/src
- is set as the python sources location
*
- *
+ *
+ * When the virtual filesystem is located in other than the default resource directory,
+ * {@code org.graalvm.python.vfs}, i.e., using Maven or Gradle option {@code resourceDirectory},
+ * use {@link #contextBuilder(VirtualFileSystem)} and
+ * {@link VirtualFileSystem.Builder#resourceDirectory(String)} when building the
+ * {@link VirtualFileSystem}.
*
* @return a new {@link Context} instance
* @since 24.2.0
@@ -233,6 +238,12 @@ public static Context createContext() {
* }
* }
*
+ *
+ * When the virtual filesystem is located in other than the default resource directory,
+ * {@code org.graalvm.python.vfs}, i.e., using Maven or Gradle option {@code resourceDirectory},
+ * use {@link #contextBuilder(VirtualFileSystem)} and
+ * {@link VirtualFileSystem.Builder#resourceDirectory(String)} when building the
+ * {@link VirtualFileSystem}.
*
* @see PythonOptions
@@ -308,13 +319,14 @@ public static Context.Builder contextBuilder(VirtualFileSystem vfs) {
/**
* Creates a GraalPy context preconfigured with GraalPy and polyglot Context configuration
- * options for use with resources located in a real filesystem.
+ * options for use with resources located in an external directory in real filesystem.
*
* Following resource paths are preconfigured:
*
- * ${resourcesDirectory}/venv
- is set as the python virtual environment
+ * ${externalResourcesDirectory}/venv
- is set as the python virtual
+ * environment location
+ * ${externalResourcesDirectory}/src
- is set as the python sources
* location
- * ${resourcesDirectory}/src
- is set as the python sources location
*
*
*
@@ -343,19 +355,20 @@ public static Context.Builder contextBuilder(VirtualFileSystem vfs) {
*
*
*
- * @param resourcesDirectory the root directory with GraalPy specific embedding resources
+ * @param externalResourcesDirectory the root directory with GraalPy specific embedding
+ * resources
* @return a new {@link org.graalvm.polyglot.Context.Builder} instance
* @since 24.2.0
*/
- public static Context.Builder contextBuilder(Path resourcesDirectory) {
+ public static Context.Builder contextBuilder(Path externalResourcesDirectory) {
String execPath;
if (VirtualFileSystemImpl.isWindows()) {
- execPath = resourcesDirectory.resolve(VirtualFileSystemImpl.VFS_VENV).resolve("Scripts").resolve("python.exe").toAbsolutePath().toString();
+ execPath = externalResourcesDirectory.resolve(VirtualFileSystemImpl.VFS_VENV).resolve("Scripts").resolve("python.exe").toAbsolutePath().toString();
} else {
- execPath = resourcesDirectory.resolve(VirtualFileSystemImpl.VFS_VENV).resolve("bin").resolve("python").toAbsolutePath().toString();
+ execPath = externalResourcesDirectory.resolve(VirtualFileSystemImpl.VFS_VENV).resolve("bin").resolve("python").toAbsolutePath().toString();
}
- String srcPath = resourcesDirectory.resolve(VirtualFileSystemImpl.VFS_SRC).toAbsolutePath().toString();
+ String srcPath = externalResourcesDirectory.resolve(VirtualFileSystemImpl.VFS_SRC).toAbsolutePath().toString();
return createContextBuilder().
// allow all IO access
allowIO(IOAccess.ALL).
@@ -437,8 +450,9 @@ public static Path getNativeExecutablePath() {
* The structure of the created resource directory will stay the same like the embedded Python
* resources structure:
*
- * ${resourcesDirectory}/venv
- the python virtual environment location
- * ${resourcesDirectory}/src
- the python sources location
+ * ${externalResourcesDirectory}/venv
- the python virtual environment
+ * location
+ * ${externalResourcesDirectory}/src
- the python sources location
*
*
*
@@ -456,17 +470,17 @@ public static Path getNativeExecutablePath() {
*
*
* @param vfs the {@link VirtualFileSystem} from which resources are to be extracted
- * @param resourcesDirectory the target directory to extract the resources to
+ * @param externalResourcesDirectory the target directory to extract the resources to
* @throws IOException if resources isn't a directory
* @see #contextBuilder(Path)
* @see VirtualFileSystem.Builder#resourceLoadingClass(Class)
*
* @since 24.2.0
*/
- public static void extractVirtualFileSystemResources(VirtualFileSystem vfs, Path resourcesDirectory) throws IOException {
- if (Files.exists(resourcesDirectory) && !Files.isDirectory(resourcesDirectory)) {
- throw new IOException(String.format("%s has to be a directory", resourcesDirectory.toString()));
+ public static void extractVirtualFileSystemResources(VirtualFileSystem vfs, Path externalResourcesDirectory) throws IOException {
+ if (Files.exists(externalResourcesDirectory) && !Files.isDirectory(externalResourcesDirectory)) {
+ throw new IOException(String.format("%s has to be a directory", externalResourcesDirectory.toString()));
}
- vfs.impl.extractResources(resourcesDirectory);
+ vfs.impl.extractResources(externalResourcesDirectory);
}
}
diff --git a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GraalPyGradlePlugin.java b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GraalPyGradlePlugin.java
index f0ff56f0e1..0b964a9720 100644
--- a/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GraalPyGradlePlugin.java
+++ b/graalpython/org.graalvm.python.gradle.plugin/src/main/java/org/graalvm/python/GraalPyGradlePlugin.java
@@ -117,11 +117,11 @@ public void apply(Project project) {
if (extension.getPythonResourcesDirectory().isPresent() && extension.getExternalDirectory().isPresent()) {
throw new GradleException(
- "Cannot set both 'externalDirectory' and 'resourcesDirectory' at the same time. " +
+ "Cannot set both 'externalDirectory' and 'resourceDirectory' at the same time. " +
"New property 'externalDirectory' is a replacement for deprecated 'pythonResourcesDirectory'. " +
"If you want to deploy the virtual environment into physical filesystem, use 'externalDirectory'. " +
"The deployment of the external directory alongside the application is not handled by the GraalPy Maven plugin in such case." +
- "If you wish to bundle the virtual filesystem in Java resources, use 'resourcesDirectory'. " +
+ "If you wish to bundle the virtual filesystem in Java resources, use 'resourceDirectory'. " +
"For more details, please refer to https://www.graalvm.org/latest/reference-manual/python/Embedding-Build-Tools. ");
}
@@ -132,9 +132,9 @@ public void apply(Project project) {
// Run the vfsFilesListTask conditionally only if 'externalDirectory' is not set
if (!extension.getPythonResourcesDirectory().isPresent() && !extension.getExternalDirectory().isPresent()) {
if (!extension.getResourceDirectory().isPresent()) {
- proj.getLogger().info(String.format("Virtual filesystem is deployed to default resources directory '%s'. " +
+ proj.getLogger().warn(String.format("Virtual filesystem is deployed to default resources directory '%s'. " +
"This can cause conflicts if used with other Java libraries that also deploy GraalPy virtual filesystem. " +
- "Consider adding `resourcesDirectory = \"GRAALPY-VFS/${groupId}/${artifactId}\"` to your build.gradle script " +
+ "Consider adding `resourceDirectory = \"GRAALPY-VFS/${groupId}/${artifactId}\"` to your build.gradle script " +
"(replace the placeholders with values specific to your project), " +
"moving any existing sources from '%s' to '%s', and using VirtualFileSystem$Builder#resourceDirectory." +
"For more details, please refer to https://www.graalvm.org/latest/reference-manual/python/Embedding-Build-Tools. ",
@@ -192,7 +192,7 @@ private TaskProvider registerResourcesTask(Project project, Confi
t.getLogger().warn("The GraalPy plugin pythonHome configuration setting was deprecated and has no effect anymore.\n" +
"For execution in jvm mode, the python language home is always available.\n" +
"When building a native executable using GraalVM Native Image, then the full python language home is by default embedded into the native executable.\n" +
- "For more details, please refer to the documentation of GraalVM Native Image options IncludeLanguageResources and CopyLanguageResources documentation.");
+ "For more details, please refer to the documentation of GraalVM Native Image options IncludeLanguageResources and CopyLanguageResources.");
}
t.getPackages().set(extension.getPackages());
diff --git a/mx.graalpython/copyrights/overrides b/mx.graalpython/copyrights/overrides
index 9b09b5c78f..1a30d74d25 100644
--- a/mx.graalpython/copyrights/overrides
+++ b/mx.graalpython/copyrights/overrides
@@ -617,7 +617,11 @@ graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java,zippy.copyright
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/PFloat.java,zippy.copyright
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java,zippy.copyright
+graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignAbstractClassBuiltins.java,zippy.copyright
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignBooleanBuiltins.java,zippy.copyright
+graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java,zippy.copyright
+graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java,zippy.copyright
+graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignIterableBuiltins.java,zippy.copyright
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignNumberBuiltins.java,zippy.copyright
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/FrameBuiltins.java,zippy.copyright
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/AbstractFunctionBuiltins.java,zippy.copyright
diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py
index 92ae8a88d7..05c541dd3e 100644
--- a/mx.graalpython/suite.py
+++ b/mx.graalpython/suite.py
@@ -9,9 +9,9 @@
"name": "graalpython",
"versionConflictResolution": "latest",
- "version": "25.0.0",
+ "version": "24.2.1",
"graalpython:pythonVersion": "3.11.7",
- "release": False,
+ "release": True,
"groupId": "org.graalvm.python",
"url": "http://www.graalvm.org/python",
@@ -45,7 +45,7 @@
},
{
"name": "sdk",
- "version": "0f61c409358b6ecdb637d69410c8d3960b289e9c",
+ "version": "c9096be682f7aa67f5133fb098762e2152ff355f",
"subdir": True,
"urls": [
{"url": "https://github.com/oracle/graal", "kind": "git"},
@@ -53,7 +53,7 @@
},
{
"name": "tools",
- "version": "0f61c409358b6ecdb637d69410c8d3960b289e9c",
+ "version": "c9096be682f7aa67f5133fb098762e2152ff355f",
"subdir": True,
"urls": [
{"url": "https://github.com/oracle/graal", "kind": "git"},
@@ -61,7 +61,7 @@
},
{
"name": "sulong",
- "version": "0f61c409358b6ecdb637d69410c8d3960b289e9c",
+ "version": "c9096be682f7aa67f5133fb098762e2152ff355f",
"subdir": True,
"urls": [
{"url": "https://github.com/oracle/graal", "kind": "git"},
@@ -69,7 +69,7 @@
},
{
"name": "regex",
- "version": "0f61c409358b6ecdb637d69410c8d3960b289e9c",
+ "version": "c9096be682f7aa67f5133fb098762e2152ff355f",
"subdir": True,
"urls": [
{"url": "https://github.com/oracle/graal", "kind": "git"},
@@ -108,12 +108,12 @@
],
"digest": "sha512:16920fd41f398696c563417049472c0d81abb2d293ecb45bbbe97c12651669833e34eac238e2e4a6f8761ea58fb39806425d2741e88e8c3097fe2b5457ebf488",
},
- "XZ-5.2.6": {
+ "XZ-5.6.2": {
"urls": [
- "https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/xz-5.2.6.tar.gz",
+ "https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/xz-5.6.2.tar.gz",
],
"packedResource": True,
- "digest": "sha512:090958dd6c202c989746686094c86707ad4ae835026640080fc0a9d0fad699821b7d5cb3a67e6700661a0938818ba153662366f89ab8ec47e0bae4a3fe9b1961",
+ "digest": "sha512:c32c32c95e3541b906e0284e66a953ace677e0ce6af2084e7b122600047bf7542c1b0fabb5909b19ff79fba6def530be674df1c675b22a47a8d57f3f0b736a82",
},
"BOUNCYCASTLE-PROVIDER": {
"digest": "sha512:fb10c3c089921c8173ad285329f730e0e78de175d1b50b9bdd79c6a85a265af9b3331caa0c1ed57e5f47047319ce3b0f3bb5def0a3db9cccf2755cc95e145e52",
@@ -636,10 +636,10 @@
"bin/",
],
"cmakeConfig": {
- "XZ_SRC": "",
+ "XZ_SRC": "",
"XZ_VERSION_MAJOR": "5",
- "XZ_VERSION_MINOR": "2",
- "XZ_VERSION_PATCH": "6",
+ "XZ_VERSION_MINOR": "6",
+ "XZ_VERSION_PATCH": "2",
},
"os_arch": {
"windows": {
@@ -654,7 +654,7 @@
},
},
"buildDependencies": [
- "XZ-5.2.6",
+ "XZ-5.6.2",
],
},
diff --git a/mx.graalpython/verify_patches.py b/mx.graalpython/verify_patches.py
index 1ebc371694..8aa4e84c10 100644
--- a/mx.graalpython/verify_patches.py
+++ b/mx.graalpython/verify_patches.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2023, 2025, 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
@@ -45,6 +45,7 @@
# Approved license identifiers in SPDX "short identifier" format
ALLOWED_LICENSES = {
+ 'UPL', # https://spdx.org/licenses/UPL-1.0.html
'MIT', # https://spdx.org/licenses/MIT.html
'BSD-3-Clause', # https://spdx.org/licenses/BSD-3-Clause.html
'BSD-2-Clause', # https://spdx.org/licenses/BSD-2-Clause.html