From fe4cf0b08cf4b44ea2e07affa78a4b09ce34d347 Mon Sep 17 00:00:00 2001
From: Danilo Ansaloni
Date: Thu, 23 Jan 2025 19:38:03 +0100
Subject: [PATCH 01/22] Restart the 24.2 dev cycle.
Begin of the feature freeze for the 24.2 release.
Revert "Start 25.0.0 dev cycle."
This reverts commit f4105848044ea7cb58318895c7da184c3af64217.
---
graalpython/com.oracle.graal.python.test.integration/pom.xml | 2 +-
.../src/tests/standalone/gradle/build/build.gradle | 2 +-
.../src/tests/standalone/gradle/build/build.gradle.kts | 2 +-
.../src/tests/standalone/jbang/EmptyPIPComments.j | 2 +-
.../src/tests/standalone/jbang/EmptyPythonResourceComment.j | 2 +-
.../standalone/jbang/EmptyPythonResourceCommentWithBlanks.j | 2 +-
.../src/tests/standalone/jbang/NoPackagesResourcesDir.j | 2 +-
.../src/tests/standalone/jbang/TwoPythonResourceComments.j | 2 +-
graalpython/graalpy-archetype-polyglot-app/pom.xml | 2 +-
.../src/main/resources/archetype-resources/pom.xml | 2 +-
graalpython/graalpy-jbang/examples/hello.java | 2 +-
.../graalpy-jbang/templates/graalpy-template.java.qute | 2 +-
.../templates/graalpy-template_local_repo.java.qute | 2 +-
graalpython/graalpy-maven-plugin/pom.xml | 4 ++--
mx.graalpython/suite.py | 2 +-
15 files changed, 16 insertions(+), 16 deletions(-)
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/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/mx.graalpython/suite.py b/mx.graalpython/suite.py
index 92ae8a88d7..efb3e6a4ee 100644
--- a/mx.graalpython/suite.py
+++ b/mx.graalpython/suite.py
@@ -9,7 +9,7 @@
"name": "graalpython",
"versionConflictResolution": "latest",
- "version": "25.0.0",
+ "version": "24.2.0",
"graalpython:pythonVersion": "3.11.7",
"release": False,
"groupId": "org.graalvm.python",
From b94c39b17b87b69dfa53683f5f2cb334a4857dae Mon Sep 17 00:00:00 2001
From: Danilo Ansaloni
Date: Thu, 23 Jan 2025 19:40:45 +0100
Subject: [PATCH 02/22] Update imports
---
ci.jsonnet | 2 +-
mx.graalpython/suite.py | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/ci.jsonnet b/ci.jsonnet
index 48bf915fd3..f4fbcec95d 100644
--- a/ci.jsonnet
+++ b/ci.jsonnet
@@ -1 +1 @@
-{ "overlay": "840dea7f9575e2e96e2143685751932513fd0c78" }
+{ "overlay": "da4fbb453006eea9997babadc69b70c2e0cee0ab" }
diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py
index efb3e6a4ee..763a0fd5f6 100644
--- a/mx.graalpython/suite.py
+++ b/mx.graalpython/suite.py
@@ -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"},
From 9095026c26d47b96e20762b12a94340a482ed727 Mon Sep 17 00:00:00 2001
From: stepan
Date: Wed, 29 Jan 2025 21:40:54 +0100
Subject: [PATCH 03/22] Move the longest running Gradle Kotlin tests to the
'long running' batch
(cherry picked from commit 1fa8957d0236aed27dd4b7d9a381cef87af09bfc)
---
.../src/tests/standalone/test_gradle_plugin.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
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..52d95fc704 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
@@ -677,11 +677,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 +701,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()
From 99bc51c61f38c4a5ecbc0b19a59909178c530382 Mon Sep 17 00:00:00 2001
From: stepan
Date: Wed, 29 Jan 2025 21:57:12 +0100
Subject: [PATCH 04/22] Update CI overlay
(cherry picked from commit f25f7853affa54cf53e93e45699dd94b761de48f)
---
ci.jsonnet | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ci.jsonnet b/ci.jsonnet
index f4fbcec95d..a3a4e1743e 100644
--- a/ci.jsonnet
+++ b/ci.jsonnet
@@ -1 +1 @@
-{ "overlay": "da4fbb453006eea9997babadc69b70c2e0cee0ab" }
+{ "overlay": "585265d3c6bafc1d12054374377589b360307957" }
From 77a8b4168109e94e605ff3d5482673f511a465e4 Mon Sep 17 00:00:00 2001
From: stepan
Date: Wed, 29 Jan 2025 14:34:09 +0100
Subject: [PATCH 05/22] Change the log level of 'Unexpected executable for slot
pointer' messages to fine
(cherry picked from commit b95a25d3910688780a94c5f89639a5fbbcd1df64)
---
.../com/oracle/graal/python/builtins/objects/type/TpSlots.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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);
From 195d4bb37d421be7ce29522ebb33b07dae8427fa Mon Sep 17 00:00:00 2001
From: Benoit Daloze
Date: Fri, 17 Jan 2025 14:59:17 +0100
Subject: [PATCH 06/22] Properly order traits in GetForeignObjectClassNode
(cherry picked from commit 8922dc627a1da6cc1bc7f4cbe684889112db5eff)
---
.../src/tests/test_interop.py | 6 ++---
.../object/GetForeignObjectClassNode.java | 25 +++++++++++--------
2 files changed, 18 insertions(+), 13 deletions(-)
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..d3b511aea6 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
@@ -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)
@@ -472,9 +472,9 @@ def test_java_import_from_jar(self):
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])
+ self.assertEqual(type(Integer).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])
def test_java_exceptions(self):
# TODO: more tests
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..9bf4d52ea1 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.PythonClass ?
+
+ // Interop traits
+ EXECUTABLE("Executable"),
+ INSTANTIABLE("Instantiable"),
+
+ // 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");
// Last in MRO
public static final Trait[] VALUES = Trait.values();
@@ -217,14 +222,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);
}
From 17c4bf0a37d29af3e72c99336c15de4cfc3f9cbf Mon Sep 17 00:00:00 2001
From: Benoit Daloze
Date: Fri, 17 Jan 2025 16:54:29 +0100
Subject: [PATCH 07/22] Move __bases__ and __instancecheck__ from
ForeignObjectBuiltins to ForeignAbstractClassBuiltins
(cherry picked from commit f69bb094614ffc48fcc0a32fda8b7d69b354b8fb)
---
.../graal/python/builtins/Python3Core.java | 2 +
.../builtins/PythonBuiltinClassType.java | 2 +
.../foreign/ForeignAbstractClassBuiltins.java | 94 +++++++++++++++++++
.../foreign/ForeignObjectBuiltins.java | 51 +---------
.../object/GetForeignObjectClassNode.java | 2 +-
mx.graalpython/copyrights/overrides | 1 +
6 files changed, 101 insertions(+), 51 deletions(-)
create mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignAbstractClassBuiltins.java
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..8351695719 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
@@ -259,6 +259,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 +488,7 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed,
new ForeignObjectBuiltins(),
new ForeignNumberBuiltins(),
new ForeignBooleanBuiltins(),
+ new ForeignAbstractClassBuiltins(),
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..b4d755082a 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
@@ -304,6 +304,7 @@ public enum PythonBuiltinClassType implements TruffleObject {
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),
+ ForeignAbstractClass("ForeignAbstractClass", J_POLYGLOT, Flags.PUBLIC_BASE_WDICT),
// bz2
BZ2Compressor("BZ2Compressor", "_bz2"),
@@ -839,6 +840,7 @@ public final Shape getInstanceShape(PythonLanguage lang) {
ForeignNumber.base = ForeignObject;
ForeignBoolean.base = ForeignNumber;
+ ForeignAbstractClass.base = ForeignObject;
PBaseExceptionGroup.base = PBaseException;
SystemExit.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..adde80b51e
--- /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 (except for CallNode)
+ * 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/ForeignObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java
index 617458040f..19ad62ff6f 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,13 @@
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;
@@ -66,7 +62,6 @@
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;
@@ -82,7 +77,6 @@
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;
@@ -497,47 +491,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/nodes/object/GetForeignObjectClassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java
index 9bf4d52ea1..e7cb56977d 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
@@ -93,7 +93,7 @@ public enum Trait {
NUMBER("Number", PythonBuiltinClassType.ForeignNumber), // int, float, complex
STRING("String", PythonBuiltinClassType.PString),
EXCEPTION("Exception", PythonBuiltinClassType.PBaseException),
- META_OBJECT("AbstractClass"), // PythonBuiltinClassType.PythonClass ?
+ META_OBJECT("AbstractClass", PythonBuiltinClassType.ForeignAbstractClass),
// Interop traits
EXECUTABLE("Executable"),
diff --git a/mx.graalpython/copyrights/overrides b/mx.graalpython/copyrights/overrides
index 9b09b5c78f..0a1351458c 100644
--- a/mx.graalpython/copyrights/overrides
+++ b/mx.graalpython/copyrights/overrides
@@ -617,6 +617,7 @@ 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/ForeignNumberBuiltins.java,zippy.copyright
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/FrameBuiltins.java,zippy.copyright
From c5ab7ea52787e1c05318bc4aba10686868973439 Mon Sep 17 00:00:00 2001
From: Benoit Daloze
Date: Mon, 27 Jan 2025 16:17:22 +0100
Subject: [PATCH 08/22] Make it easier to set the base in
PythonBuiltinClassType
(cherry picked from commit bcd576ff22da723adb7c90a6188dce6b4a943198)
---
.../builtins/PythonBuiltinClassType.java | 20 ++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
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 b4d755082a..b7a4e04a27 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,9 +302,9 @@ 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),
- ForeignAbstractClass("ForeignAbstractClass", J_POLYGLOT, Flags.PUBLIC_BASE_WDICT),
+ 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),
// bz2
BZ2Compressor("BZ2Compressor", "_bz2"),
@@ -628,6 +628,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);
}
@@ -640,6 +645,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());
}
@@ -838,10 +848,6 @@ public final Shape getInstanceShape(PythonLanguage lang) {
Boolean.base = PInt;
- ForeignNumber.base = ForeignObject;
- ForeignBoolean.base = ForeignNumber;
- ForeignAbstractClass.base = ForeignObject;
-
PBaseExceptionGroup.base = PBaseException;
SystemExit.base = PBaseException;
KeyboardInterrupt.base = PBaseException;
From 05ec2d779f8a7fe6abec0d73bbb268202624774c Mon Sep 17 00:00:00 2001
From: Benoit Daloze
Date: Mon, 27 Jan 2025 16:49:54 +0100
Subject: [PATCH 09/22] Move the remaining trait-specific methods from
ForeignObject to the dedicated trait classes
(cherry picked from commit 60b82ae3527d9737d7fd41ca0c0eda02f2ba7b62)
---
.../src/tests/test_interop.py | 4 +-
.../graal/python/builtins/Python3Core.java | 6 +
.../builtins/PythonBuiltinClassType.java | 3 +
.../foreign/ForeignAbstractClassBuiltins.java | 2 +-
.../foreign/ForeignExecutableBuiltins.java | 110 ++++++++++++++
.../foreign/ForeignInstantiableBuiltins.java | 143 ++++++++++++++++++
.../foreign/ForeignIterableBuiltins.java | 83 ++++++++++
.../foreign/ForeignObjectBuiltins.java | 117 +-------------
.../graal/python/nodes/ErrorMessages.java | 1 -
.../object/GetForeignObjectClassNode.java | 10 +-
mx.graalpython/copyrights/overrides | 3 +
11 files changed, 356 insertions(+), 126 deletions(-)
create mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java
create mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java
create mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignIterableBuiltins.java
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 d3b511aea6..c065cacbd8 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
@@ -1040,7 +1040,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 8351695719..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;
@@ -489,6 +492,9 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed,
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 b7a4e04a27..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
@@ -305,6 +305,9 @@ public enum PythonBuiltinClassType implements TruffleObject {
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"),
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
index adde80b51e..48cfd68373 100644
--- 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
@@ -51,7 +51,7 @@
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INSTANCECHECK__;
/*
- * 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.
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..22c632fac0
--- /dev/null
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java
@@ -0,0 +1,110 @@
+/*
+ * 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.builtins.objects.function.PKeyword;
+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.nodes.object.IsForeignObjectNode;
+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.Fallback;
+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, takesVarKeywordArgs = true)
+ @GenerateNodeFactory
+ public abstract static class CallNode extends PythonBuiltinNode {
+ @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 {
+ 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);
+ }
+ }
+
+ @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);
+ }
+ }
+
+}
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..7ab0b0d664
--- /dev/null
+++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java
@@ -0,0 +1,143 @@
+/*
+ * 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.builtins.objects.function.PKeyword;
+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.nodes.object.IsForeignObjectNode;
+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.Fallback;
+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, 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 e) {
+ throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
+ } catch (UnsupportedMessageException e) {
+ throw CompilerDirectives.shouldNotReachHere(e);
+ } 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 {
+ @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 {
+ 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);
+ }
+ }
+
+ @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);
+ }
+ }
+
+}
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 19ad62ff6f..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
@@ -29,11 +29,8 @@
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.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___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.util.PythonUtils.TS_ENCODING;
@@ -49,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;
@@ -61,17 +57,13 @@
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.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;
@@ -82,12 +74,10 @@
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;
@@ -102,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.
@@ -138,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 {
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/object/GetForeignObjectClassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetForeignObjectClassNode.java
index e7cb56977d..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
@@ -96,8 +96,8 @@ public enum Trait {
META_OBJECT("AbstractClass", PythonBuiltinClassType.ForeignAbstractClass),
// Interop traits
- EXECUTABLE("Executable"),
- INSTANTIABLE("Instantiable"),
+ 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.[]
@@ -106,7 +106,7 @@ public enum Trait {
ARRAY("List", PythonBuiltinClassType.PList),
// Iterator before Iterable so that foreign iterator+iterable prefers iterator.__iter__
ITERATOR("Iterator", PythonBuiltinClassType.PIterator),
- ITERABLE("Iterable");
+ ITERABLE("Iterable", PythonBuiltinClassType.ForeignIterable);
// Last in MRO
public static final Trait[] VALUES = Trait.values();
@@ -116,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();
diff --git a/mx.graalpython/copyrights/overrides b/mx.graalpython/copyrights/overrides
index 0a1351458c..1a30d74d25 100644
--- a/mx.graalpython/copyrights/overrides
+++ b/mx.graalpython/copyrights/overrides
@@ -619,6 +619,9 @@ graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects
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
From 38c69a533e60b1517874c4daf5ba0eaa1a3fcb0a Mon Sep 17 00:00:00 2001
From: Benoit Daloze
Date: Mon, 27 Jan 2025 17:22:31 +0100
Subject: [PATCH 10/22] Simplify logic for foreign __new__ and __call__: they
do not accept keyword arguments
* So the error is now:
TypeError: ForeignInstantiable.__call__() got an unexpected keyword argument 'kwarg'
vs before:
TypeError: invalid instantiation of foreign object
(cherry picked from commit 95b076038980628431dc08d661dc74e0b4bd5deb)
---
.../src/tests/test_interop.py | 15 ++++--
.../foreign/ForeignExecutableBuiltins.java | 17 ++-----
.../foreign/ForeignInstantiableBuiltins.java | 50 ++-----------------
3 files changed, 19 insertions(+), 63 deletions(-)
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 c065cacbd8..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
@@ -471,11 +471,20 @@ 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.ForeignAbstractClass, polyglot.ForeignInstantiable, 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.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
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
index 22c632fac0..ea02d004c7 100644
--- 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
@@ -35,13 +35,11 @@
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.builtins.objects.function.PKeyword;
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.nodes.object.IsForeignObjectNode;
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
import com.oracle.graal.python.runtime.GilNode;
import com.oracle.graal.python.runtime.IndirectCallData;
@@ -50,7 +48,6 @@
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.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
@@ -69,14 +66,13 @@ protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFa
return ForeignExecutableBuiltinsFactory.getFactories();
}
- @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
+ @Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true)
@GenerateNodeFactory
public abstract static class CallNode extends PythonBuiltinNode {
- @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,
+ @Specialization
+ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments,
@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,
@@ -98,13 +94,6 @@ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] argument
throw CompilerDirectives.shouldNotReachHere(e);
}
}
-
- @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);
- }
}
}
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
index 7ab0b0d664..d5b095145e 100644
--- 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
@@ -36,13 +36,11 @@
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.builtins.objects.function.PKeyword;
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.nodes.object.IsForeignObjectNode;
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
import com.oracle.graal.python.runtime.GilNode;
import com.oracle.graal.python.runtime.IndirectCallData;
@@ -51,7 +49,6 @@
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.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
@@ -70,46 +67,14 @@ protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFa
return ForeignInstantiableBuiltinsFactory.getFactories();
}
- @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 e) {
- throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
- } catch (UnsupportedMessageException e) {
- throw CompilerDirectives.shouldNotReachHere(e);
- } 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)
+ @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(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,
+ @Specialization
+ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments,
@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,
@@ -131,13 +96,6 @@ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] argument
throw CompilerDirectives.shouldNotReachHere(e);
}
}
-
- @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);
- }
}
}
From 7c829c5f0ece9d7a56e08863240e9ac66778561b Mon Sep 17 00:00:00 2001
From: Benoit Daloze
Date: Fri, 17 Jan 2025 16:39:17 +0100
Subject: [PATCH 11/22] Rethrow internal errors during
PythonLanguage#initializeContext
* Such as AssertionError, etc.
* Ensure to not print Python exceptions twice by always throwing
an exit exception after printing stacktraces with AlwaysRunExcepthook.
(cherry picked from commit 53180fecb184d4b89b1765527f39f99423d399c9)
---
.../graal/python/shell/GraalPythonMain.java | 2 +
.../exception/TopLevelExceptionHandler.java | 37 +++++++++++--------
2 files changed, 23 insertions(+), 16 deletions(-)
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/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 {
From 96d33d879b537c0c5f733c9cf00e82f355e1f7e3 Mon Sep 17 00:00:00 2001
From: Danilo Ansaloni
Date: Tue, 3 Sep 2024 19:40:34 +0200
Subject: [PATCH 12/22] Update XZ version.
(cherry picked from commit 10f8ae3547ff2abba2ed100d7116355155a51985)
---
mx.graalpython/suite.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py
index 763a0fd5f6..8cc53b105a 100644
--- a/mx.graalpython/suite.py
+++ b/mx.graalpython/suite.py
@@ -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",
],
},
From ce7f385fd261f0f8f75122d6964045c3065ad04d Mon Sep 17 00:00:00 2001
From: stepan
Date: Wed, 19 Feb 2025 14:27:35 +0100
Subject: [PATCH 13/22] Fix: Maven plugin incorrectly prints warning about
default resources directory. Fix few typos in warning messages.
---
.../src/tests/standalone/test_gradle_plugin.py | 6 +++++-
.../src/tests/standalone/test_maven_plugin.py | 2 ++
.../python/maven/plugin/ManageResourcesMojo.java | 4 ++--
.../java/org/graalvm/python/GraalPyGradlePlugin.java | 10 +++++-----
4 files changed, 14 insertions(+), 8 deletions(-)
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 52d95fc704..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)
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/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/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());
From 3b46423445fef929fc1546c5d88efc8a46551935 Mon Sep 17 00:00:00 2001
From: stepan
Date: Wed, 19 Feb 2025 14:51:56 +0100
Subject: [PATCH 14/22] Improve the GraalPyResources docs
---
.../python/embedding/GraalPyResources.java | 46 ++++++++++++-------
1 file changed, 30 insertions(+), 16 deletions(-)
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);
}
}
From 875be24f018563e373e3da5452e4ea725c6108fa Mon Sep 17 00:00:00 2001
From: Danilo Ansaloni
Date: Tue, 4 Mar 2025 20:29:50 +0100
Subject: [PATCH 15/22] Release GraalVM 24.2.0.
---
mx.graalpython/suite.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py
index 8cc53b105a..16abd25b65 100644
--- a/mx.graalpython/suite.py
+++ b/mx.graalpython/suite.py
@@ -11,7 +11,7 @@
"version": "24.2.0",
"graalpython:pythonVersion": "3.11.7",
- "release": False,
+ "release": True,
"groupId": "org.graalvm.python",
"url": "http://www.graalvm.org/python",
From c25c88dfc60b8f4312276cae65fc741aeac565ee Mon Sep 17 00:00:00 2001
From: Michael Simacek
Date: Thu, 3 Apr 2025 09:35:01 +0200
Subject: [PATCH 16/22] Set overlay to graalpy-patch-branch branch
---
ci.jsonnet | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ci.jsonnet b/ci.jsonnet
index a3a4e1743e..f3fbf47e80 100644
--- a/ci.jsonnet
+++ b/ci.jsonnet
@@ -1 +1 @@
-{ "overlay": "585265d3c6bafc1d12054374377589b360307957" }
+{ "overlay": "ea6007b968048485d43905914816208f870ac88b" }
From 83b9de9d33b366c7f0bd734cf184485954608f34 Mon Sep 17 00:00:00 2001
From: Ivo Horak
Date: Thu, 30 Jan 2025 13:31:35 +0100
Subject: [PATCH 17/22] Add pyarrow v19.0.0 patch
---
.../lib-graalpython/patches/metadata.toml | 5 +
.../patches/pyarrow-19.0.0.patch | 164 ++++++++++++++++++
2 files changed, 169 insertions(+)
create mode 100644 graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch
diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml
index ac1ccb7262..450bbfe206 100644
--- a/graalpython/lib-graalpython/patches/metadata.toml
+++ b/graalpython/lib-graalpython/patches/metadata.toml
@@ -416,6 +416,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
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"
From 3fce96f2d48cfebb5884b08abba0fbd1a806e2ba Mon Sep 17 00:00:00 2001
From: Michael Simacek
Date: Wed, 29 Jan 2025 14:14:41 +0100
Subject: [PATCH 18/22] Add patch for psycopg2-2.9.10
---
.../lib-graalpython/patches/metadata.toml | 16 ++++++++++++++--
.../{psycopg2.patch => psycopg2-2.9.10.patch} | 12 ++++++------
...sycopg2-binary.patch => psycopg2-2.9.9.patch} | 0
3 files changed, 20 insertions(+), 8 deletions(-)
rename graalpython/lib-graalpython/patches/{psycopg2.patch => psycopg2-2.9.10.patch} (51%)
rename graalpython/lib-graalpython/patches/{psycopg2-binary.patch => psycopg2-2.9.9.patch} (100%)
diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml
index 450bbfe206..7356d3a129 100644
--- a/graalpython/lib-graalpython/patches/metadata.toml
+++ b/graalpython/lib-graalpython/patches/metadata.toml
@@ -394,11 +394,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]]
+version = '<= 2.9.9'
+patch = "psycopg2-2.9.9.patch"
license = "LGPL-3.0-or-later WITH openssl-exception"
[[psycopg2-binary.rules]]
-patch = "psycopg2-binary.patch"
+version = '>= 2.9.10'
+patch = "psycopg2-2.9.10.patch"
license = "LGPL-3.0-or-later WITH openssl-exception"
[[py4j.rules]]
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
From 92d279e435d8cb77482b03091f60f5ad4b8309f3 Mon Sep 17 00:00:00 2001
From: Tim Felgentreff
Date: Tue, 25 Feb 2025 10:35:26 +0100
Subject: [PATCH 19/22] [GR-62557] Add patch for jq to recythonize the C code.
---
.../lib-graalpython/patches/jq-1.8.0.patch | 59 +++++++++++++++++++
.../lib-graalpython/patches/metadata.toml | 9 +++
2 files changed, 68 insertions(+)
create mode 100644 graalpython/lib-graalpython/patches/jq-1.8.0.patch
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 7356d3a129..1f3a11255e 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'
From 5c17862c8db7d67f8c8582490a11c916b19a2f62 Mon Sep 17 00:00:00 2001
From: Tim Felgentreff
Date: Tue, 25 Feb 2025 15:03:47 +0100
Subject: [PATCH 20/22] Add pandas 2.2.3 patch
---
.../lib-graalpython/patches/metadata.toml | 6 +++
.../patches/pandas-2.2.3.patch | 52 +++++++++++++++++++
2 files changed, 58 insertions(+)
create mode 100644 graalpython/lib-graalpython/patches/pandas-2.2.3.patch
diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml
index 1f3a11255e..55e95f5619 100644
--- a/graalpython/lib-graalpython/patches/metadata.toml
+++ b/graalpython/lib-graalpython/patches/metadata.toml
@@ -367,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'
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",
From 0432e9c039ad5774c77389646e20b1e860c88621 Mon Sep 17 00:00:00 2001
From: Michael Simacek
Date: Fri, 21 Mar 2025 13:15:17 +0100
Subject: [PATCH 21/22] Add patch for trio
---
.../lib-graalpython/patches/metadata.toml | 4 +
.../lib-graalpython/patches/trio.patch | 103 ++++++++++++++++++
2 files changed, 107 insertions(+)
create mode 100644 graalpython/lib-graalpython/patches/trio.patch
diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml
index 55e95f5619..e6bd9477b7 100644
--- a/graalpython/lib-graalpython/patches/metadata.toml
+++ b/graalpython/lib-graalpython/patches/metadata.toml
@@ -749,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'
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(
From 3481bf2a210898aaa6674356b5c005b34e88bddc Mon Sep 17 00:00:00 2001
From: Michael Simacek
Date: Fri, 21 Mar 2025 13:19:05 +0100
Subject: [PATCH 22/22] Pin uvloop
---
graalpython/lib-graalpython/patches/metadata.toml | 1 +
1 file changed, 1 insertion(+)
diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml
index e6bd9477b7..95e4d84a06 100644
--- a/graalpython/lib-graalpython/patches/metadata.toml
+++ b/graalpython/lib-graalpython/patches/metadata.toml
@@ -768,6 +768,7 @@ version = '>= 2, < 2.0.3'
install-priority = 0
[[uvloop.rules]]
+version = '<= 0.19.0'
patch = 'uvloop.patch'
license = 'MIT'
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy