From fe4cf0b08cf4b44ea2e07affa78a4b09ce34d347 Mon Sep 17 00:00:00 2001 From: Danilo Ansaloni Date: Thu, 23 Jan 2025 19:38:03 +0100 Subject: [PATCH 01/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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> 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/23] 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/23] 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> 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> 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> 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/23] 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> 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> 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/23] 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/23] 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/23] 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/23] 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/23] 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 0d0fb1665a3a9451276accb3d665ed5800329eb3 Mon Sep 17 00:00:00 2001 From: Danilo Ansaloni Date: Tue, 4 Mar 2025 20:30:23 +0100 Subject: [PATCH 16/23] Start 24.2.1 dev cycle. --- ci.jsonnet | 2 +- .../com.oracle.graal.python.test.integration/pom.xml | 2 +- .../src/tests/standalone/gradle/build/build.gradle | 2 +- .../tests/standalone/gradle/build/build.gradle.kts | 2 +- .../src/tests/standalone/jbang/EmptyPIPComments.j | 2 +- .../standalone/jbang/EmptyPythonResourceComment.j | 2 +- .../jbang/EmptyPythonResourceCommentWithBlanks.j | 2 +- .../tests/standalone/jbang/NoPackagesResourcesDir.j | 2 +- .../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 +- .../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 | 12 ++++++------ 16 files changed, 22 insertions(+), 22 deletions(-) diff --git a/ci.jsonnet b/ci.jsonnet index a3a4e1743e..7d5f235fe3 100644 --- a/ci.jsonnet +++ b/ci.jsonnet @@ -1 +1 @@ -{ "overlay": "585265d3c6bafc1d12054374377589b360307957" } +{ "overlay": "16d0e566573ebdcf380bf6f309c02724baf4172b" } diff --git a/graalpython/com.oracle.graal.python.test.integration/pom.xml b/graalpython/com.oracle.graal.python.test.integration/pom.xml index 0f55209ba9..6251cedd21 100644 --- a/graalpython/com.oracle.graal.python.test.integration/pom.xml +++ b/graalpython/com.oracle.graal.python.test.integration/pom.xml @@ -64,7 +64,7 @@ Additionally, one can change the polyglot artifacts version with 17 17 UTF-8 - 24.2.0 + 24.2.1 diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle b/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle index 15c3c89c12..2dfdd3f5ce 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle @@ -1,6 +1,6 @@ plugins { id "application" - id 'org.graalvm.python' version '24.2.0' + id 'org.graalvm.python' version '24.2.1' id "org.graalvm.buildtools.native" version "0.10.2" } diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle.kts b/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle.kts index a086b6635e..8ccf16421d 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle.kts +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/gradle/build/build.gradle.kts @@ -1,6 +1,6 @@ plugins { application - id("org.graalvm.python") version "24.2.0" + id("org.graalvm.python") version "24.2.1" id("org.graalvm.buildtools.native") version "0.10.2" } diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPIPComments.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPIPComments.j index 6b140a59b8..08561a0c15 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPIPComments.j +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPIPComments.j @@ -1,6 +1,6 @@ ///usr/bin/env jbang "$0" "$@" ; exit $? -//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.0} +//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1} //PIP // one blank after PIP //PIP diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceComment.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceComment.j index 768e188e9e..31330e96fd 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceComment.j +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceComment.j @@ -1,6 +1,6 @@ ///usr/bin/env jbang "$0" "$@" ; exit $? -//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.0} +//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1} //PYTHON_RESOURCES_DIRECTORY public class EmptyPythonResourceComment { diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceCommentWithBlanks.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceCommentWithBlanks.j index f4b7556997..6f71f88213 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceCommentWithBlanks.j +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/EmptyPythonResourceCommentWithBlanks.j @@ -1,6 +1,6 @@ ///usr/bin/env jbang "$0" "$@" ; exit $? -//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.0} +//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1} // resource dir with blanks //PYTHON_RESOURCES_DIRECTORY diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/NoPackagesResourcesDir.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/NoPackagesResourcesDir.j index 749ae89606..24a4866b26 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/NoPackagesResourcesDir.j +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/NoPackagesResourcesDir.j @@ -1,6 +1,6 @@ ///usr/bin/env jbang "$0" "$@" ; exit $? -//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.0} +//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1} //PYTHON_RESOURCES_DIRECTORY python-resources public class NoPackagesResourcesDir { diff --git a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/TwoPythonResourceComments.j b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/TwoPythonResourceComments.j index c2d902d358..ab31f0a738 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/TwoPythonResourceComments.j +++ b/graalpython/com.oracle.graal.python.test/src/tests/standalone/jbang/TwoPythonResourceComments.j @@ -1,6 +1,6 @@ ///usr/bin/env jbang "$0" "$@" ; exit $? -//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.0} +//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1} //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 04b27f55e3..e525172eb1 100644 --- a/graalpython/graalpy-archetype-polyglot-app/pom.xml +++ b/graalpython/graalpy-archetype-polyglot-app/pom.xml @@ -45,7 +45,7 @@ SOFTWARE. org.graalvm.python graalpy-archetype-polyglot-app - 24.2.0 + 24.2.1 http://www.graalvm.org/python Maven archetype providing a skeleton GraalPy - Java polyglot application. maven-archetype diff --git a/graalpython/graalpy-archetype-polyglot-app/src/main/resources/archetype-resources/pom.xml b/graalpython/graalpy-archetype-polyglot-app/src/main/resources/archetype-resources/pom.xml index 90be4e32ca..e67d93e879 100644 --- a/graalpython/graalpy-archetype-polyglot-app/src/main/resources/archetype-resources/pom.xml +++ b/graalpython/graalpy-archetype-polyglot-app/src/main/resources/archetype-resources/pom.xml @@ -10,7 +10,7 @@ #set( $symbol_dollar = '$' ) - 24.2.0 + 24.2.1 python-community 0.10.4 17 diff --git a/graalpython/graalpy-jbang/examples/hello.java b/graalpython/graalpy-jbang/examples/hello.java index b005158ef6..11049392fc 100644 --- a/graalpython/graalpy-jbang/examples/hello.java +++ b/graalpython/graalpy-jbang/examples/hello.java @@ -40,7 +40,7 @@ */ ///usr/bin/env jbang "$0" "$@" ; exit $? //JAVA 17+ -//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.0} +//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1} // specify python packages and their versions as if used with pip //PIP termcolor==2.2 diff --git a/graalpython/graalpy-jbang/templates/graalpy-template.java.qute b/graalpython/graalpy-jbang/templates/graalpy-template.java.qute index 5a61e3dea9..9a94477922 100644 --- a/graalpython/graalpy-jbang/templates/graalpy-template.java.qute +++ b/graalpython/graalpy-jbang/templates/graalpy-template.java.qute @@ -5,7 +5,7 @@ {/for} {#if dependencies.isEmpty()}// //DEPS {/if} {| -//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.0} +//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1} // specify python packages and their versions as if used with pip //PIP termcolor==2.2 |} diff --git a/graalpython/graalpy-jbang/templates/graalpy-template_local_repo.java.qute b/graalpython/graalpy-jbang/templates/graalpy-template_local_repo.java.qute index 2fb3914dc1..6b41f4e288 100644 --- a/graalpython/graalpy-jbang/templates/graalpy-template_local_repo.java.qute +++ b/graalpython/graalpy-jbang/templates/graalpy-template_local_repo.java.qute @@ -8,7 +8,7 @@ //REPOS mc=https://repo1.maven.org/maven2/ //REPOS local=file://{path_to_local_repo} {| -//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.0} +//DEPS org.graalvm.python:jbang:${env.GRAALPY_VERSION:24.2.1} // specify python packages and their versions as if used with pip //PIP termcolor==2.2 |} diff --git a/graalpython/graalpy-maven-plugin/pom.xml b/graalpython/graalpy-maven-plugin/pom.xml index 4838e2cec7..5a8fe1acde 100644 --- a/graalpython/graalpy-maven-plugin/pom.xml +++ b/graalpython/graalpy-maven-plugin/pom.xml @@ -48,7 +48,7 @@ SOFTWARE. graalpy-maven-plugin maven-plugin - 24.2.0 + 24.2.1 http://www.graalvm.org/python graalpy-maven-plugin Handles python related resources in a maven GraalPy - Java polyglot application. @@ -57,7 +57,7 @@ SOFTWARE. 17 17 UTF-8 - 24.2.0 + 24.2.1 diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 16abd25b65..af58122c58 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -9,9 +9,9 @@ "name": "graalpython", "versionConflictResolution": "latest", - "version": "24.2.0", + "version": "24.2.1", "graalpython:pythonVersion": "3.11.7", - "release": True, + "release": False, "groupId": "org.graalvm.python", "url": "http://www.graalvm.org/python", @@ -45,7 +45,7 @@ }, { "name": "sdk", - "version": "826d284d76d4e3c2379e952824f4ab7e96c805ee", + "version": "c9096be682f7aa67f5133fb098762e2152ff355f", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"}, @@ -53,7 +53,7 @@ }, { "name": "tools", - "version": "826d284d76d4e3c2379e952824f4ab7e96c805ee", + "version": "c9096be682f7aa67f5133fb098762e2152ff355f", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"}, @@ -61,7 +61,7 @@ }, { "name": "sulong", - "version": "826d284d76d4e3c2379e952824f4ab7e96c805ee", + "version": "c9096be682f7aa67f5133fb098762e2152ff355f", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"}, @@ -69,7 +69,7 @@ }, { "name": "regex", - "version": "826d284d76d4e3c2379e952824f4ab7e96c805ee", + "version": "c9096be682f7aa67f5133fb098762e2152ff355f", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"}, From 10573cbf474ce2981d7114bc0f90ced4aaaf9dfa Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 20 Mar 2025 11:42:01 +0100 Subject: [PATCH 17/23] Pass NULL instead of None as arg to METHNOARGS functions (cherry picked from commit 935e46a1e7f5ed7e965407ccbdcf26fe35a6cc9e) --- .../builtins/objects/cext/capi/ExternalFunctionNodes.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java index 18528ad4a6..8d236077eb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java @@ -1309,7 +1309,7 @@ public MethNoargsRoot(PythonLanguage language, TruffleString name, boolean isSta @Override protected Object[] prepareCArguments(VirtualFrame frame) { - return new Object[]{readSelf(frame), PNone.NONE}; + return new Object[]{readSelf(frame), PNone.NO_VALUE}; } @Override From 11936fb04188f8ab0b75d6b09379baa934cc701a Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 20 Mar 2025 11:58:24 +0100 Subject: [PATCH 18/23] Support calling PyType_Modified on any Python class (cherry picked from commit cef2e89e85d4d8681092968c477574153b3fd9e7) --- .../modules/cext/PythonCextTypeBuiltins.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java index eea71e9ebd..a7e76df0a2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java @@ -228,20 +228,24 @@ static Object doIt(PythonAbstractNativeObject clazz, @CApiBuiltin(ret = ArgDescriptor.Void, args = {PyTypeObject}, call = Direct) abstract static class PyType_Modified extends CApiUnaryBuiltinNode { - @TruffleBoundary @Specialization - static Object doIt(PythonAbstractNativeObject clazz, + static Object doIt(PythonAbstractClass object, @Bind("this") Node inliningTarget) { - PythonContext context = PythonContext.get(inliningTarget); - CyclicAssumption nativeClassStableAssumption = context.getNativeClassStableAssumption(clazz, false); - if (nativeClassStableAssumption != null) { - nativeClassStableAssumption.invalidate("PyType_Modified(\"" + TypeNodes.GetNameNode.executeUncached(clazz).toJavaStringUncached() + "\") called"); + if (object instanceof PythonAbstractNativeObject clazz) { + PythonContext context = PythonContext.get(inliningTarget); + CyclicAssumption nativeClassStableAssumption = context.getNativeClassStableAssumption(clazz, false); + if (nativeClassStableAssumption != null) { + nativeClassStableAssumption.invalidate("PyType_Modified(\"" + TypeNodes.GetNameNode.executeUncached(clazz).toJavaStringUncached() + "\") called"); + } + MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(clazz); + mroStorage.lookupChanged(); + // Reload slots from native, which also invalidates cached slot lookups + clazz.setTpSlots(TpSlots.fromNative(clazz, context)); + } else { + MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(object); + mroStorage.lookupChanged(); } - MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(clazz); - mroStorage.lookupChanged(); - // Reload slots from native, which also invalidates cached slot lookups - clazz.setTpSlots(TpSlots.fromNative(clazz, context)); return PNone.NO_VALUE; } } From 9b12f6854fd3f5e09448603a8c36293c8f769ee2 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 20 Mar 2025 13:30:40 +0100 Subject: [PATCH 19/23] Enable PyUnicode_DecodeRawUnicodeEscape (cherry picked from commit e36f7d45604e1aad0678cf43964958022dbb001d) --- .../com.oracle.graal.python.cext/src/unicodeobject.c | 9 +++++---- .../python/builtins/objects/cext/capi/CApiFunction.java | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c b/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c index 42699b743a..852906637e 100644 --- a/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/unicodeobject.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2024, Oracle and/or its affiliates. +/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -6220,16 +6220,17 @@ _PyUnicode_DecodeRawUnicodeEscapeStateful(const char *s, Py_XDECREF(exc); return NULL; } - +#endif // GraalPy change PyObject * PyUnicode_DecodeRawUnicodeEscape(const char *s, Py_ssize_t size, const char *errors) { - return _PyUnicode_DecodeRawUnicodeEscapeStateful(s, size, errors, NULL); + return PyUnicode_Decode(s, size, "raw_unicode_escape", errors); + // return _PyUnicode_DecodeRawUnicodeEscapeStateful(s, size, errors, NULL); } - +#if 0 // GraalPy change PyObject * PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java index 5909dc1427..ae89ccf769 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java @@ -504,6 +504,7 @@ public final class CApiFunction { @CApiBuiltin(name = "PyUnicode_DecodeLatin1", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeLocale", ret = PyObject, args = {ConstCharPtrAsTruffleString, ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeLocaleAndSize", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = CImpl) + @CApiBuiltin(name = "PyUnicode_DecodeRawUnicodeEscape", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeUTF16", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, INT_LIST}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeUTF16Stateful", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, INT_LIST, PY_SSIZE_T_PTR}, call = CImpl) @CApiBuiltin(name = "PyUnicode_DecodeUTF32", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, INT_LIST}, call = CImpl) @@ -942,7 +943,6 @@ public final class CApiFunction { @CApiBuiltin(name = "PyUnicode_BuildEncodingMap", ret = PyObject, args = {PyObject}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_CopyCharacters", ret = Py_ssize_t, args = {PyObject, Py_ssize_t, PyObject, Py_ssize_t, Py_ssize_t}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_DecodeCharmap", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, PyObject, ConstCharPtrAsTruffleString}, call = NotImplemented) - @CApiBuiltin(name = "PyUnicode_DecodeRawUnicodeEscape", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_DecodeUTF7", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_DecodeUTF7Stateful", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString, PY_SSIZE_T_PTR}, call = NotImplemented) @CApiBuiltin(name = "PyUnicode_DecodeUnicodeEscape", ret = PyObject, args = {ConstCharPtrAsTruffleString, Py_ssize_t, ConstCharPtrAsTruffleString}, call = NotImplemented) From dc7165228972aa20e2edd533e02ddebd6cffa833 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Fri, 21 Mar 2025 06:31:18 +0100 Subject: [PATCH 20/23] Add patch to install pymupdf (cherry picked from commit 98e11fb717901205a4d3a25b4307afe6c7eafa52) --- .../modules/cext/PythonCextTypeBuiltins.java | 2 +- .../objects/cext/capi/CApiFunction.java | 2 +- .../cext/capi/ExternalFunctionNodes.java | 2 +- .../lib-graalpython/patches/metadata.toml | 9 ++ .../lib-graalpython/patches/pymupdf.patch | 124 ++++++++++++++++++ mx.graalpython/verify_patches.py | 3 +- 6 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 graalpython/lib-graalpython/patches/pymupdf.patch diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java index a7e76df0a2..a997a8a2aa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java index ae89ccf769..97ad1090b1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java index 8d236077eb..3111ccef04 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index ac1ccb7262..2d414e4baa 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -476,6 +476,15 @@ version = ">= 4.8.0" patch = 'pymongo-4.8.0.patch' license = 'Apache-2.0' +[[PyMuPDF.rules]] +version = "== 1.25.4" +patch = "pymupdf.patch" +# That project is AGPL, so do not actually include *any* code of pymupdf in the patch, not even an +# empty line, in the diff context. The code we write in the patch is UPL - that is compatible with +# AGPL in the sense that if someone were to apply it and distribute *that*, our patch is now part +# of the AGPL'd codebase +license = 'UPL' + [[pyOpenSSL.rules]] # Pin this version to avoid pulling newer cryptography than we have patch for version = "== 23.2.0" diff --git a/graalpython/lib-graalpython/patches/pymupdf.patch b/graalpython/lib-graalpython/patches/pymupdf.patch new file mode 100644 index 0000000000..27869eccd6 --- /dev/null +++ b/graalpython/lib-graalpython/patches/pymupdf.patch @@ -0,0 +1,124 @@ +diff --git a/graalpy-config b/graalpy-config +new file mode 100755 +index 00000000..1f69f726 +--- /dev/null ++++ b/graalpy-config +@@ -0,0 +1,78 @@ ++#!/bin/sh ++ ++# Adapted from CPython but deferring to GraalPy ++ ++exit_with_usage () ++{ ++ echo "Usage: $0 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--help|--abiflags|--configdir|--embed" ++ exit $1 ++} ++ ++if [ "$1" = "" ] ; then ++ exit_with_usage 1 ++fi ++ ++# Returns the actual prefix where this script was installed to. ++EXE=$(cd $(dirname "$0") && pwd -P) ++if which readlink >/dev/null 2>&1 ; then ++ if readlink -f "$RESULT" >/dev/null 2>&1; then ++ EXE=$(readlink -f "$RESULT") ++ fi ++fi ++EXE=$EXE/graalpy ++ ++if ! test -x "$EXE" ; then ++ EXE=graalpy ++fi ++ ++# Scan for --help or unknown argument. ++for ARG in $* ++do ++ case $ARG in ++ --help) ++ exit_with_usage 0 ++ ;; ++ --embed) ++ echo "graalpy-config does not print embedding flags" ++ exit 1 ++ ;; ++ --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--abiflags|--configdir) ++ ;; ++ *) ++ exit_with_usage 1 ++ ;; ++ esac ++done ++ ++for ARG in "$@" ++do ++ case "$ARG" in ++ --prefix) ++ $EXE -c "print(__import__('sysconfig').get_config_var('prefix'))" ++ ;; ++ --exec-prefix) ++ $EXE -c "print(__import__('sysconfig').get_config_var('exec_prefix'))" ++ ;; ++ --includes) ++ $EXE -c "from sysconfig import get_path; print('-I'+get_path('include'), '-I'+get_path('platinclude'))" ++ ;; ++ --cflags) ++ $EXE -c "import sysconfig as s; print('-I' + s.get_path('include'), '-I' + s.get_path('platinclude'), s.get_config_var('CFLAGS').replace('NDEBUG', 'DEBUG'), s.get_config_var('OPT').replace('NDEBUG', 'DEBUG'))" ++ ;; ++ --libs) ++ $EXE -c "import sysconfig as s; print('-L' + s.get_config_var('LIBDIR'))" ++ ;; ++ --ldflags) ++ $EXE -c "import sysconfig as s; print('-L' + s.get_config_var('LIBDIR'))" ++ ;; ++ --extension-suffix) ++ $EXE -c "import sysconfig as s; print(s.get_config_var('EXT_SUFFIX'))" ++ ;; ++ --abiflags) ++ $EXE -c "import sysconfig as s; print(s.get_config_var('ABIFLAGS'))" ++ ;; ++ --configdir) ++ echo "" ++ ;; ++esac ++done +diff --git a/setup.py b/setup.py +index 5fba2c97..3fe63b07 100755 +--- a/setup.py ++++ b/setup.py +@@ -1452,0 +1452,35 @@ ++if sys.implementation.name == "graalpy": ++ import os ++ import re ++ import subprocess ++ import shutil ++ import sysconfig ++ from pathlib import Path ++ ++ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): ++ wheel_directory = Path(wheel_directory).absolute() ++ sdir = Path(__file__).absolute().parent ++ python311 = shutil.which("python3.11") ++ if not python311: ++ raise RuntimeError("python3.11 must be available on the PATH for cross-compilation") ++ env = os.environ.copy() ++ env["PIPCL_PYTHON_CONFIG"] = str(sdir / "graalpy-config") ++ env["PYMUPDF_SETUP_PY_LIMITED_API"] = "1" ++ subprocess.run( ++ [python311, "setup.py", "bdist_wheel"], ++ env=env, ++ cwd=sdir, ++ check=True, ++ ) ++ wheels = list((sdir / 'dist').glob('*.whl')) ++ assert len(wheels) == 1, f"Expected 1 wheel, found {len(wheels)}" ++ wheel = wheels[0] ++ assert "-cp311-abi3" in wheel.name, f"Expected wheel to be for CPython 3.11 ABI 3, got {wheel.name}" ++ graalpy_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") ++ m = re.match(r"\.graalpy(\d+[^\-]*)-(\d+)", sysconfig.get_config_var("EXT_SUFFIX")) ++ gpver = m[1] ++ cpver = m[2] ++ graalpy_wheel_tag = f"graalpy{cpver}-graalpy{gpver}_{cpver}_native" ++ name = wheel.name.replace("cp311-abi3", graalpy_wheel_tag) ++ shutil.copyfile(wheel, wheel_directory / name) ++ return str(name) diff --git a/mx.graalpython/verify_patches.py b/mx.graalpython/verify_patches.py index 1ebc371694..8aa4e84c10 100644 --- a/mx.graalpython/verify_patches.py +++ b/mx.graalpython/verify_patches.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -45,6 +45,7 @@ # Approved license identifiers in SPDX "short identifier" format ALLOWED_LICENSES = { + 'UPL', # https://spdx.org/licenses/UPL-1.0.html 'MIT', # https://spdx.org/licenses/MIT.html 'BSD-3-Clause', # https://spdx.org/licenses/BSD-3-Clause.html 'BSD-2-Clause', # https://spdx.org/licenses/BSD-2-Clause.html From beb30c8fc33209b7f33c523850df05c45d4ba891 Mon Sep 17 00:00:00 2001 From: Michael Simacek Date: Mon, 10 Mar 2025 09:45:46 +0100 Subject: [PATCH 21/23] Skip time-dependent test (cherry picked from commit 438997b0c0db5ec59f9944a13f6b5b061dd765f8) --- .../src/tests/unittest_tags/test_strptime.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt index 019ffaf499..220ef38651 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt +++ b/graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_strptime.txt @@ -35,7 +35,8 @@ test.test_strptime.StrptimeTests.test_percent @ darwin-arm64,darwin-x86_64,linux test.test_strptime.StrptimeTests.test_second @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_strptime.StrptimeTests.test_strptime_exception_context @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_strptime.StrptimeTests.test_time @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 -test.test_strptime.StrptimeTests.test_timezone @ darwin-arm64,darwin-x86_64,win32-AMD64 +# Seems to be dependent on the actual time/date/timezone of the machine, at least on GraalPy. Needs investigation +!test.test_strptime.StrptimeTests.test_timezone test.test_strptime.StrptimeTests.test_unconverteddata @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_strptime.StrptimeTests.test_year @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 test.test_strptime.TimeRETests.test_blankpattern @ darwin-arm64,darwin-x86_64,linux-aarch64,linux-x86_64,win32-AMD64 From abd391210a10593c7e35c132a2894dcfe8755798 Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Wed, 2 Apr 2025 18:58:53 +0000 Subject: [PATCH 22/23] release GraalVM 24.2.1 --- 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 af58122c58..05c541dd3e 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -11,7 +11,7 @@ "version": "24.2.1", "graalpython:pythonVersion": "3.11.7", - "release": False, + "release": True, "groupId": "org.graalvm.python", "url": "http://www.graalvm.org/python", From 7d196446914364f49ebff17434d0ccd10753df5e Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Mon, 14 Apr 2025 18:13:56 +0100 Subject: [PATCH 23/23] new dev cycle GraalVM 24.2.2 --- mx.graalpython/suite.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 05c541dd3e..d4269ffd74 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -9,9 +9,9 @@ "name": "graalpython", "versionConflictResolution": "latest", - "version": "24.2.1", + "version": "24.2.2", "graalpython:pythonVersion": "3.11.7", - "release": True, + "release": False, "groupId": "org.graalvm.python", "url": "http://www.graalvm.org/python",