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.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..0f55209ba9 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.0
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..15c3c89c12 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.0'
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..a086b6635e 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.0"
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..6b140a59b8 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.0}
//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..768e188e9e 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.0}
//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..f4b7556997 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.0}
// 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..749ae89606 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.0}
//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..c2d902d358 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.0}
//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/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/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..04b27f55e3 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.0
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..90be4e32ca 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.0
python-community
0.10.4
17
diff --git a/graalpython/graalpy-jbang/examples/hello.java b/graalpython/graalpy-jbang/examples/hello.java
index 2afc0c82b3..b005158ef6 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.0}
// 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..5a61e3dea9 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.0}
// 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..2fb3914dc1 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.0}
// 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..4838e2cec7 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.0
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.0
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..95e4d84a06 100644
--- a/graalpython/lib-graalpython/patches/metadata.toml
+++ b/graalpython/lib-graalpython/patches/metadata.toml
@@ -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'
@@ -358,6 +367,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 +409,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 +443,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
@@ -717,6 +749,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 +768,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/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/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..16abd25b65 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.0",
"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": "826d284d76d4e3c2379e952824f4ab7e96c805ee",
"subdir": True,
"urls": [
{"url": "https://github.com/oracle/graal", "kind": "git"},
@@ -53,7 +53,7 @@
},
{
"name": "tools",
- "version": "0f61c409358b6ecdb637d69410c8d3960b289e9c",
+ "version": "826d284d76d4e3c2379e952824f4ab7e96c805ee",
"subdir": True,
"urls": [
{"url": "https://github.com/oracle/graal", "kind": "git"},
@@ -61,7 +61,7 @@
},
{
"name": "sulong",
- "version": "0f61c409358b6ecdb637d69410c8d3960b289e9c",
+ "version": "826d284d76d4e3c2379e952824f4ab7e96c805ee",
"subdir": True,
"urls": [
{"url": "https://github.com/oracle/graal", "kind": "git"},
@@ -69,7 +69,7 @@
},
{
"name": "regex",
- "version": "0f61c409358b6ecdb637d69410c8d3960b289e9c",
+ "version": "826d284d76d4e3c2379e952824f4ab7e96c805ee",
"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",
],
},