From fe4cf0b08cf4b44ea2e07affa78a4b09ce34d347 Mon Sep 17 00:00:00 2001 From: Danilo Ansaloni Date: Thu, 23 Jan 2025 19:38:03 +0100 Subject: [PATCH 01/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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 c25c88dfc60b8f4312276cae65fc741aeac565ee Mon Sep 17 00:00:00 2001 From: Michael Simacek Date: Thu, 3 Apr 2025 09:35:01 +0200 Subject: [PATCH 23/36] Set overlay to graalpy-patch-branch branch --- ci.jsonnet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci.jsonnet b/ci.jsonnet index a3a4e1743e..f3fbf47e80 100644 --- a/ci.jsonnet +++ b/ci.jsonnet @@ -1 +1 @@ -{ "overlay": "585265d3c6bafc1d12054374377589b360307957" } +{ "overlay": "ea6007b968048485d43905914816208f870ac88b" } From 83b9de9d33b366c7f0bd734cf184485954608f34 Mon Sep 17 00:00:00 2001 From: Ivo Horak Date: Thu, 30 Jan 2025 13:31:35 +0100 Subject: [PATCH 24/36] Add pyarrow v19.0.0 patch --- .../lib-graalpython/patches/metadata.toml | 5 + .../patches/pyarrow-19.0.0.patch | 164 ++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index ac1ccb7262..450bbfe206 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -416,6 +416,11 @@ version = '== 12.0.0' patch = 'pyarrow-12.0.0.patch' license = 'Apache-2.0' +[[pyarrow.rules]] +version = '== 19.0.0' +patch = 'pyarrow-19.0.0.patch' +license = 'Apache-2.0' + [[pybind11.rules]] # Upstreamed install-priority = 0 diff --git a/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch b/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch new file mode 100644 index 0000000000..70adda0ede --- /dev/null +++ b/graalpython/lib-graalpython/patches/pyarrow-19.0.0.patch @@ -0,0 +1,164 @@ +diff --git a/pyarrow/error.pxi b/pyarrow/error.pxi +index cbe2552..8d0d9d9 100644 +--- a/pyarrow/error.pxi ++++ b/pyarrow/error.pxi +@@ -248,7 +248,7 @@ cdef class SignalStopHandler: + if exc_value.signum: + # Re-emit the exact same signal. We restored the Python signal + # handler above, so it should receive it. +- if os.name == 'nt': ++ if os.name == 'nt' or sys.implementation.name == 'graalpy': + SendSignal(exc_value.signum) + else: + SendSignalToThread(exc_value.signum, +diff --git a/pyarrow/memory.pxi b/pyarrow/memory.pxi +index 1ddcb01..6805e42 100644 +--- a/pyarrow/memory.pxi ++++ b/pyarrow/memory.pxi +@@ -20,6 +20,10 @@ + # cython: embedsignature = True + + ++cdef extern from "Python.h": ++ void Py_INCREF(object) ++ ++ + cdef class MemoryPool(_Weakrefable): + """ + Base class for memory allocation. +@@ -35,6 +39,13 @@ cdef class MemoryPool(_Weakrefable): + + cdef void init(self, CMemoryPool* pool): + self.pool = pool ++ # GraalPy change: pyarrow doesn't maintain python references from ++ # buffers to pools, but they dereference the pointer to the pool in the ++ # destructor. They just assume buffers will get GC'ed before their ++ # pools. You can easily get a segfault even on CPython if you make ++ # a buffer outlive its pool. Since we can't guarantee destruction ++ # order, we just leak the pool. ++ Py_INCREF(self) + + def release_unused(self): + """ +diff --git a/pyarrow_build_backend.py b/pyarrow_build_backend.py +new file mode 100644 +index 0000000..0929c5f +--- /dev/null ++++ b/pyarrow_build_backend.py +@@ -0,0 +1,93 @@ ++import os ++import re ++import sys ++import tarfile ++import subprocess ++import tempfile ++import shutil ++import tarfile ++import urllib.request ++from pathlib import Path ++ ++VERSION = '19.0.0' ++ ++ ++def build_sdist(sdist_directory, config_settings=None): ++ nv = f'pyarrow-{VERSION}' ++ srcdir = Path(__file__).parent ++ archive_path = Path(sdist_directory) / f'{nv}.tar.gz' ++ ++ def tarfilter(info): ++ if re.match(r'\./(?:.git|venv|[^-/]+-venv|dist)', info.name): ++ return None ++ info.name = f'./{nv}/{info.name}' ++ return info ++ ++ with tarfile.open(archive_path, 'w:gz') as tar: ++ tar.add('.', filter=tarfilter) ++ return archive_path.name ++ ++ ++def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): ++ wheel_directory = Path(wheel_directory).absolute() ++ with tempfile.TemporaryDirectory() as tmpdir: ++ tmpdir = Path(tmpdir).absolute() ++ tarname = f'apache-arrow-{VERSION}.tar.gz' ++ tarpath = tmpdir / tarname ++ urllib.request.urlretrieve(f"https://github.com/apache/arrow/archive/refs/tags/{tarname}", tarpath) ++ with tarfile.open(tarpath) as tar: ++ tar.extractall(tmpdir) ++ arrow_dir = tmpdir / f'arrow-apache-arrow-{VERSION}' ++ assert arrow_dir.is_dir() ++ arrow_dist = tmpdir / 'arrow-dist' ++ build_dir = tmpdir / 'arrow-build' ++ subprocess.check_call([ ++ 'cmake', '-S', str(arrow_dir / 'cpp'), '-B', str(build_dir), ++ '-DCMAKE_INSTALL_LIBDIR=lib', ++ f'-DCMAKE_INSTALL_PREFIX={arrow_dist}', ++ '-DCMAKE_BUILD_TYPE=Release', ++ '-DARROW_RPATH_ORIGIN=ON', ++ '-DARROW_BUILD_TESTS=OFF', ++ '-DARROW_BUILD_SHARED=ON', ++ '-DARROW_BUILD_STATIC=OFF', ++ # Features ++ '-DARROW_COMPUTE=ON', ++ '-DARROW_CSV=ON', ++ '-DARROW_JSON=ON', ++ '-DARROW_FILESYSTEM=ON', ++ '-DARROW_DATASET=ON', ++ '-DARROW_PARQUET=ON', ++ '-DPARQUET_REQUIRE_ENCRYPTION=ON', ++ '-DARROW_GANDIVA=ON', ++ '-DARROW_WITH_BZ2=ON', ++ '-DARROW_WITH_ZLIB=ON', ++ '-DARROW_WITH_ZSTD=ON', ++ '-DARROW_WITH_LZ4=ON', ++ '-DARROW_WITH_SNAPPY=ON', ++ '-DARROW_WITH_BROTLI=ON', ++ ]) ++ subprocess.check_call([ ++ 'cmake', '--build', str(build_dir), '--parallel', ++ ]) ++ subprocess.check_call([ ++ 'cmake', '--install', str(build_dir), ++ ]) ++ env = os.environ.copy() ++ env['ARROW_HOME'] = str(arrow_dist) ++ env['CMAKE_PREFIX_PATH'] = str(arrow_dist) ++ env['PYARROW_WITH_DATASET'] = '1' ++ env['PYARROW_WITH_PARQUET'] = '1' ++ env['PYARROW_WITH_PARQUET_ENCRYPTION'] = '1' ++ env['PYARROW_WITH_GANDIVA'] = '1' ++ env['PYARROW_BUNDLE_ARROW_CPP'] = '1' ++ env['PYARROW_BUNDLE_CYTHON_CPP'] = '1' ++ subprocess.run( ++ [sys.executable, 'setup.py', 'bdist_wheel'], ++ env=env, ++ check=True, ++ ) ++ wheels = list(Path('dist').glob('*.whl')) ++ assert len(wheels) == 1, f"Expected 1 wheel, found {len(wheels)}" ++ wheel = wheels[0] ++ shutil.copyfile(wheel, wheel_directory / wheel.name) ++ return str(wheel.name) +diff --git a/pyproject.toml b/pyproject.toml +index ef2043f..cb08a86 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -17,7 +17,7 @@ + + [build-system] + requires = [ +- "cython >= 0.29.31", ++ "cython >= 0.29.31, < 3", + # Starting with NumPy 1.25, NumPy is (by default) as far back compatible + # as oldest-support-numpy was (customizable with a NPY_TARGET_VERSION + # define). For older Python versions (where NumPy 1.25 is not yet available) +@@ -29,7 +29,8 @@ requires = [ + "setuptools_scm[toml]>=8", + "setuptools>=64", + ] +-build-backend = "setuptools.build_meta" ++build-backend = "pyarrow_build_backend" ++backend-path = ["."] + + [project] + name = "pyarrow" From 3fce96f2d48cfebb5884b08abba0fbd1a806e2ba Mon Sep 17 00:00:00 2001 From: Michael Simacek Date: Wed, 29 Jan 2025 14:14:41 +0100 Subject: [PATCH 25/36] Add patch for psycopg2-2.9.10 --- .../lib-graalpython/patches/metadata.toml | 16 ++++++++++++++-- .../{psycopg2.patch => psycopg2-2.9.10.patch} | 12 ++++++------ ...sycopg2-binary.patch => psycopg2-2.9.9.patch} | 0 3 files changed, 20 insertions(+), 8 deletions(-) rename graalpython/lib-graalpython/patches/{psycopg2.patch => psycopg2-2.9.10.patch} (51%) rename graalpython/lib-graalpython/patches/{psycopg2-binary.patch => psycopg2-2.9.9.patch} (100%) diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index 450bbfe206..7356d3a129 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -394,11 +394,23 @@ patch = 'protobuf-3.21.9.patch' license = 'BSD-3-Clause' [[psycopg2.rules]] -patch = "psycopg2.patch" +version = '<= 2.9.9' +patch = "psycopg2-2.9.9.patch" +license = "LGPL-3.0-or-later WITH openssl-exception" + +[[psycopg2.rules]] +version = '>= 2.9.10' +patch = "psycopg2-2.9.10.patch" +license = "LGPL-3.0-or-later WITH openssl-exception" + +[[psycopg2-binary.rules]] +version = '<= 2.9.9' +patch = "psycopg2-2.9.9.patch" license = "LGPL-3.0-or-later WITH openssl-exception" [[psycopg2-binary.rules]] -patch = "psycopg2-binary.patch" +version = '>= 2.9.10' +patch = "psycopg2-2.9.10.patch" license = "LGPL-3.0-or-later WITH openssl-exception" [[py4j.rules]] diff --git a/graalpython/lib-graalpython/patches/psycopg2.patch b/graalpython/lib-graalpython/patches/psycopg2-2.9.10.patch similarity index 51% rename from graalpython/lib-graalpython/patches/psycopg2.patch rename to graalpython/lib-graalpython/patches/psycopg2-2.9.10.patch index a3d7e3aa2d..1b35cdc301 100644 --- a/graalpython/lib-graalpython/patches/psycopg2.patch +++ b/graalpython/lib-graalpython/patches/psycopg2-2.9.10.patch @@ -1,15 +1,15 @@ diff --git a/psycopg/utils.c b/psycopg/utils.c -index 16be906..c78a24b 100644 +index 1dfb87d..28cc6c1 100644 --- a/psycopg/utils.c +++ b/psycopg/utils.c @@ -392,7 +392,9 @@ psyco_set_error(PyObject *exc, cursorObject *curs, const char *msg) static int psyco_is_main_interp(void) { --#if PY_VERSION_HEX >= 0x03080000 +-#if PY_VERSION_HEX >= 0x030d0000 +#if GRAALVM_PYTHON + return 1; -+#elif PY_VERSION_HEX >= 0x03080000 - /* tested with Python 3.8.0a2 */ - return _PyInterpreterState_Get() == PyInterpreterState_Main(); - #else ++#elif PY_VERSION_HEX >= 0x030d0000 + /* tested with Python 3.13.0a6 */ + return PyInterpreterState_Get() == PyInterpreterState_Main(); + #elif PY_VERSION_HEX >= 0x03080000 diff --git a/graalpython/lib-graalpython/patches/psycopg2-binary.patch b/graalpython/lib-graalpython/patches/psycopg2-2.9.9.patch similarity index 100% rename from graalpython/lib-graalpython/patches/psycopg2-binary.patch rename to graalpython/lib-graalpython/patches/psycopg2-2.9.9.patch From 92d279e435d8cb77482b03091f60f5ad4b8309f3 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 25 Feb 2025 10:35:26 +0100 Subject: [PATCH 26/36] [GR-62557] Add patch for jq to recythonize the C code. --- .../lib-graalpython/patches/jq-1.8.0.patch | 59 +++++++++++++++++++ .../lib-graalpython/patches/metadata.toml | 9 +++ 2 files changed, 68 insertions(+) create mode 100644 graalpython/lib-graalpython/patches/jq-1.8.0.patch diff --git a/graalpython/lib-graalpython/patches/jq-1.8.0.patch b/graalpython/lib-graalpython/patches/jq-1.8.0.patch new file mode 100644 index 0000000000..c62c51759a --- /dev/null +++ b/graalpython/lib-graalpython/patches/jq-1.8.0.patch @@ -0,0 +1,59 @@ +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -2,13 +2,10 @@ + requires = [ + "setuptools>=43", + "wheel", ++ "Cython==3.0.10", + ] + build-backend = "setuptools.build_meta" + + [tool.cibuildwheel] +-before-build = [ +- "pip install cython==3.0.10", +- "cython {project}/jq.pyx", +-] + test-requires = "-r test-requirements.txt" + test-command = "pytest {project}/tests" +diff --git a/setup.py b/setup.py +index 0b97097..54ed7b3 100644 +--- a/setup.py ++++ b/setup.py +@@ -94,15 +94,27 @@ else: + os.path.join(jq_lib_dir, "modules/oniguruma/src/.libs/libonig.a"), + ] + ++ ++try: ++ # Follow recommendation from https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules ++ from Cython.Build import cythonize ++except ImportError: ++ cythonize = lambda o: o ++ ext = ".c" ++else: ++ ext = ".pyx" ++ ++ + jq_extension = Extension( + "jq", +- sources=["jq.c"], ++ sources=[_path_in_dir(f"jq{ext}")], + define_macros=[("MS_WIN64" , 1)] if os.name == "nt" and sys.maxsize > 2**32 else None, # https://github.com/cython/cython/issues/2670 + include_dirs=[os.path.join(jq_lib_dir, "src")], + extra_link_args=["-lm"] + (["-Wl,-Bstatic", "-lpthread", "-lshlwapi", "-static-libgcc"] if os.name == 'nt' else []) + link_args_deps, + extra_objects=extra_objects, + ) + ++ + setup( + name='jq', + version='1.8.0', +@@ -112,7 +124,7 @@ setup( + url='https://github.com/mwilliamson/jq.py', + python_requires='>=3.6', + license='BSD 2-Clause', +- ext_modules = [jq_extension], ++ ext_modules = cythonize([jq_extension]), + cmdclass={"build_ext": jq_build_ext}, + classifiers=[ + 'Development Status :: 5 - Production/Stable', diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index 7356d3a129..1f3a11255e 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -200,6 +200,15 @@ version = '<=1.3.2' patch = 'joblib-1.3.2.patch' license = 'BSD-3-Clause' +[[jq.rules]] +version = '==1.8.0' +patch = 'jq-1.8.0.patch' +license = 'BSD-2-Clause' + +[[jq.add-sources]] +version = '1.8.0' +url = 'https://github.com/mwilliamson/jq.py/archive/refs/tags/1.8.0.tar.gz' + [[jupyter_server.rules]] patch = 'jupyter_server.patch' license = 'BSD-3-Clause' From 5c17862c8db7d67f8c8582490a11c916b19a2f62 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 25 Feb 2025 15:03:47 +0100 Subject: [PATCH 27/36] Add pandas 2.2.3 patch --- .../lib-graalpython/patches/metadata.toml | 6 +++ .../patches/pandas-2.2.3.patch | 52 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 graalpython/lib-graalpython/patches/pandas-2.2.3.patch diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index 1f3a11255e..55e95f5619 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -367,6 +367,12 @@ patch = 'pandas-2.2.2.patch' license = 'BSD-3-Clause' dist-type = 'sdist' +[[pandas.rules]] +version = '== 2.2.3' +patch = 'pandas-2.2.3.patch' +license = 'BSD-3-Clause' +dist-type = 'sdist' + [[pandas.rules]] version = '== 2.0.3' patch = 'pandas-2.0.3.patch' diff --git a/graalpython/lib-graalpython/patches/pandas-2.2.3.patch b/graalpython/lib-graalpython/patches/pandas-2.2.3.patch new file mode 100644 index 0000000000..1312dfbb7d --- /dev/null +++ b/graalpython/lib-graalpython/patches/pandas-2.2.3.patch @@ -0,0 +1,52 @@ +diff --git a/pandas/_libs/include/pandas/vendored/klib/khash_python.h b/pandas/_libs/include/pandas/vendored/klib/khash_python.h +index 5a933b4..f579fc6 100644 +--- a/pandas/_libs/include/pandas/vendored/klib/khash_python.h ++++ b/pandas/_libs/include/pandas/vendored/klib/khash_python.h +@@ -173,13 +173,15 @@ static inline int floatobject_cmp(PyFloatObject *a, PyFloatObject *b) { + // PyObject_RichCompareBool for complexobjects has a different behavior + // needs to be replaced + static inline int complexobject_cmp(PyComplexObject *a, PyComplexObject *b) { +- return (Py_IS_NAN(a->cval.real) && Py_IS_NAN(b->cval.real) && +- Py_IS_NAN(a->cval.imag) && Py_IS_NAN(b->cval.imag)) || +- (Py_IS_NAN(a->cval.real) && Py_IS_NAN(b->cval.real) && +- a->cval.imag == b->cval.imag) || +- (a->cval.real == b->cval.real && Py_IS_NAN(a->cval.imag) && +- Py_IS_NAN(b->cval.imag)) || +- (a->cval.real == b->cval.real && a->cval.imag == b->cval.imag); ++ Py_complex a_cval = PyComplex_AsCComplex((PyObject*)a); ++ Py_complex b_cval = PyComplex_AsCComplex((PyObject*)b); ++ return (Py_IS_NAN(a_cval.real) && Py_IS_NAN(b_cval.real) && ++ Py_IS_NAN(a_cval.imag) && Py_IS_NAN(b_cval.imag)) || ++ (Py_IS_NAN(a_cval.real) && Py_IS_NAN(b_cval.real) && ++ a_cval.imag == b_cval.imag) || ++ (a_cval.real == b_cval.real && Py_IS_NAN(a_cval.imag) && ++ Py_IS_NAN(b_cval.imag)) || ++ (a_cval.real == b_cval.real && a_cval.imag == b_cval.imag); + } + + static inline int pyobject_cmp(PyObject *a, PyObject *b); +@@ -250,8 +252,9 @@ static inline Py_hash_t floatobject_hash(PyFloatObject *key) { + + // replaces _Py_HashDouble with _Pandas_HashDouble + static inline Py_hash_t complexobject_hash(PyComplexObject *key) { +- Py_uhash_t realhash = (Py_uhash_t)_Pandas_HashDouble(key->cval.real); +- Py_uhash_t imaghash = (Py_uhash_t)_Pandas_HashDouble(key->cval.imag); ++ Py_complex cval = PyComplex_AsCComplex((PyObject*)key); ++ Py_uhash_t realhash = (Py_uhash_t)_Pandas_HashDouble(cval.real); ++ Py_uhash_t imaghash = (Py_uhash_t)_Pandas_HashDouble(cval.imag); + if (realhash == (Py_uhash_t)-1 || imaghash == (Py_uhash_t)-1) { + return -1; + } +diff --git a/pyproject.toml b/pyproject.toml +index db9f055..c191232 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -5,7 +5,7 @@ requires = [ + "meson-python==0.13.1", + "meson==1.2.1", + "wheel", +- "Cython~=3.0.5", # Note: sync with setup.py, environment.yml and asv.conf.json ++ "Cython==3.0.10", # Note: sync with setup.py, environment.yml and asv.conf.json + # Force numpy higher than 2.0, so that built wheels are compatible + # with both numpy 1 and 2 + "numpy>=2.0", From 0432e9c039ad5774c77389646e20b1e860c88621 Mon Sep 17 00:00:00 2001 From: Michael Simacek Date: Fri, 21 Mar 2025 13:15:17 +0100 Subject: [PATCH 28/36] Add patch for trio --- .../lib-graalpython/patches/metadata.toml | 4 + .../lib-graalpython/patches/trio.patch | 103 ++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 graalpython/lib-graalpython/patches/trio.patch diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index 55e95f5619..e6bd9477b7 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -749,6 +749,10 @@ version = '== 3.*' # transformers tends to depend on a specific version of tokenizers. Pin it to avoid pulling unpatched tokenizers version = '== 4.33.3' +[[trio.rules]] +patch = 'trio.patch' +license = 'Apache-2.0 OR MIT' + [[typing_extensions.rules]] patch = 'typing_extensions.patch' license = 'PSF-2.0' diff --git a/graalpython/lib-graalpython/patches/trio.patch b/graalpython/lib-graalpython/patches/trio.patch new file mode 100644 index 0000000000..dee5d3d252 --- /dev/null +++ b/graalpython/lib-graalpython/patches/trio.patch @@ -0,0 +1,103 @@ +diff --git a/trio/_socket.py b/trio/_socket.py +index 003f6c4..da7411c 100644 +--- a/trio/_socket.py ++++ b/trio/_socket.py +@@ -317,9 +317,7 @@ def fromfd( + return from_stdlib_socket(_stdlib_socket.fromfd(fd, family, type_, proto)) + + +-if sys.platform == "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket, "fromshare") +-): ++if hasattr(_stdlib_socket, "fromshare"): + + @_wraps(_stdlib_socket.fromshare, assigned=(), updated=()) + def fromshare(info: bytes) -> SocketType: +@@ -606,9 +604,7 @@ class SocketType: + def set_inheritable(self, inheritable: bool) -> None: + raise NotImplementedError + +- if sys.platform == "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "share") +- ): ++ if hasattr(_stdlib_socket.socket, "share"): + + def share(self, process_id: int) -> bytes: + raise NotImplementedError +@@ -699,9 +695,7 @@ class SocketType: + ) -> Awaitable[tuple[int, AddressFormat]]: + raise NotImplementedError + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg") +- ): ++ if hasattr(_stdlib_socket.socket, "recvmsg"): + + def recvmsg( + self, +@@ -712,9 +706,7 @@ class SocketType: + ) -> Awaitable[tuple[bytes, list[tuple[int, int, bytes]], int, object]]: + raise NotImplementedError + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg_into") +- ): ++ if hasattr(_stdlib_socket.socket, "recvmsg_into"): + + def recvmsg_into( + self, +@@ -748,9 +740,7 @@ class SocketType: + async def sendto(self, *args: object) -> int: + raise NotImplementedError + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "sendmsg") +- ): ++ if hasattr(_stdlib_socket.socket, "sendmsg"): + + @_wraps(_stdlib_socket.socket.sendmsg, assigned=(), updated=()) + async def sendmsg( +@@ -867,9 +857,7 @@ class _SocketType(SocketType): + def set_inheritable(self, inheritable: bool) -> None: + return self._sock.set_inheritable(inheritable) + +- if sys.platform == "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "share") +- ): ++ if hasattr(_stdlib_socket.socket, "share"): + + def share(self, process_id: int) -> bytes: + return self._sock.share(process_id) +@@ -1181,9 +1169,7 @@ class _SocketType(SocketType): + # recvmsg + ################################################################ + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg") +- ): ++ if hasattr(_stdlib_socket.socket, "recvmsg"): + if TYPE_CHECKING: + + def recvmsg( +@@ -1204,9 +1190,7 @@ class _SocketType(SocketType): + # recvmsg_into + ################################################################ + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "recvmsg_into") +- ): ++ if hasattr(_stdlib_socket.socket, "recvmsg_into"): + if TYPE_CHECKING: + + def recvmsg_into( +@@ -1276,9 +1260,7 @@ class _SocketType(SocketType): + # sendmsg + ################################################################ + +- if sys.platform != "win32" or ( +- not TYPE_CHECKING and hasattr(_stdlib_socket.socket, "sendmsg") +- ): ++ if hasattr(_stdlib_socket.socket, "sendmsg"): + + @_wraps(_stdlib_socket.socket.sendmsg, assigned=(), updated=()) + async def sendmsg( From 3481bf2a210898aaa6674356b5c005b34e88bddc Mon Sep 17 00:00:00 2001 From: Michael Simacek Date: Fri, 21 Mar 2025 13:19:05 +0100 Subject: [PATCH 29/36] Pin uvloop --- graalpython/lib-graalpython/patches/metadata.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index e6bd9477b7..95e4d84a06 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -768,6 +768,7 @@ version = '>= 2, < 2.0.3' install-priority = 0 [[uvloop.rules]] +version = '<= 0.19.0' patch = 'uvloop.patch' license = 'MIT' From 490978a97bb192b95c32be13e2b7bbb616805ea3 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 25 Mar 2025 13:38:45 +0100 Subject: [PATCH 30/36] Expand range for Cython patch --- graalpython/lib-graalpython/patches/metadata.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index 105675338a..75a63b2145 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -105,7 +105,7 @@ patch = 'cryptography-42.0.5.patch' license = 'Apache-2.0 OR BSD-3-Clause' [[Cython.rules]] -version = '>= 3.0.10, < 3.0.12' +version = '>= 3.0.10, <= 3.0.12' patch = 'Cython-3.0.10.patch' license = 'Apache-2.0' From 810f9b6b603525fc460d8ca36090dca047b2e15e Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Mon, 31 Mar 2025 10:45:55 +0200 Subject: [PATCH 31/36] Extend patch for torch 2.4.1 to sidestep set_extra_state bit --- .../lib-graalpython/patches/torch-2.4.1.patch | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/graalpython/lib-graalpython/patches/torch-2.4.1.patch b/graalpython/lib-graalpython/patches/torch-2.4.1.patch index 5f7724d365..caebd3aa86 100644 --- a/graalpython/lib-graalpython/patches/torch-2.4.1.patch +++ b/graalpython/lib-graalpython/patches/torch-2.4.1.patch @@ -537,6 +537,20 @@ index c301da982..a2668be20 100644 +const int THP_PyOpcode_Caches_size = 0; + +#endif // GraalPy change +diff --git a/torch/csrc/dynamo/extra_state.c b/torch/csrc/dynamo/extra_state.c +index cbe9ab37a..18740a0d8 100644 +--- a/torch/csrc/dynamo/extra_state.c ++++ b/torch/csrc/dynamo/extra_state.c +@@ -100,9 +100,6 @@ void destroy_extra_state(void* obj) { + } + + void set_extra_state(PyCodeObject* code, ExtraState* extra_state) { +- ExtraState* old_extra_state = get_extra_state(code); +- CHECK(extra_state == nullptr || old_extra_state != extra_state); +- _PyCode_SetExtra((PyObject*)code, extra_index, extra_state); + } + + ExtraState* init_and_set_extra_state(PyCodeObject* code) { diff --git a/torch/csrc/dynamo/eval_frame.c b/torch/csrc/dynamo/eval_frame.c index cbe9ab37a..18740a0d8 100644 --- a/torch/csrc/dynamo/eval_frame.c From 479174b8f09e54706804f3d05cd03640c517cceb Mon Sep 17 00:00:00 2001 From: Michael Simacek Date: Tue, 15 Apr 2025 09:14:20 +0200 Subject: [PATCH 32/36] Widen range of numpy patch --- graalpython/lib-graalpython/patches/metadata.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index 75a63b2145..ac29e68dcc 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -296,7 +296,7 @@ patch = 'numba-0.59.1.patch' license = 'BSD-2-Clause' [[numpy.rules]] -version = '>= 2.0.0rc1, < 2.1' +version = '>= 2.0.0rc1, < 2.3' patch = 'numpy-2.0.0.patch' license = 'BSD-3-Clause' dist-type = 'sdist' From eb40b18b6055eb069d1ca46a4e4bb65642bff6ad Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Tue, 15 Apr 2025 12:39:08 +0200 Subject: [PATCH 33/36] Add patch for ormsgpack --- .../lib-graalpython/patches/metadata.toml | 5 + .../patches/ormsgpack-1.8.0-1.9.1.patch | 364 ++++++++++++++++++ 2 files changed, 369 insertions(+) create mode 100644 graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index ac29e68dcc..3c331d1657 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -346,6 +346,11 @@ version = '== 3.10.5' patch = 'orjson-3.10.5.patch' license = 'Apache-2.0 OR MIT' +[[ormsgpack.rules]] +version = '>= 1.8.0, <= 1.9.1' +patch = 'ormsgpack-1.8.0-1.9.1.patch' +license = 'Apache-2.0 OR MIT' + [[overrides.rules]] version = '== 7.4.0' # Important: This patch esentially breaks the package, it's not upstreamable. The package relies on bytecode parsing diff --git a/graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch b/graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch new file mode 100644 index 0000000000..3a9542a058 --- /dev/null +++ b/graalpython/lib-graalpython/patches/ormsgpack-1.8.0-1.9.1.patch @@ -0,0 +1,364 @@ +diff --git a/src/deserialize/deserializer.rs b/src/deserialize/deserializer.rs +index 41cf7f1..99cd68e 100644 +--- a/src/deserialize/deserializer.rs ++++ b/src/deserialize/deserializer.rs +@@ -292,7 +292,10 @@ impl<'de> Deserializer<'de> { + marker => Err(Error::InvalidType(marker)), + }?; + let value = self.deserialize()?; ++ #[cfg(not(GraalPy))] + let pyhash = unsafe { (*key.as_ptr().cast::()).hash }; ++ #[cfg(GraalPy)] ++ let pyhash = unsafe { pyo3::ffi::PyObject_Hash(key.as_ptr()) }; + let _ = ffi!(_PyDict_SetItem_KnownHash( + dict_ptr, + key.as_ptr(), +@@ -471,7 +474,7 @@ impl<'de> Deserializer<'de> { + let ptr = ffi!(PyTuple_New(len as pyo3::ffi::Py_ssize_t)); + for i in 0..len { + let elem = self.deserialize_map_key()?; +- ffi!(PyTuple_SET_ITEM( ++ ffi!(PyTuple_SetItem( + ptr, + i as pyo3::ffi::Py_ssize_t, + elem.as_ptr() +diff --git a/src/ext.rs b/src/ext.rs +index b2573b4..9668d4f 100644 +--- a/src/ext.rs ++++ b/src/ext.rs +@@ -22,7 +22,7 @@ unsafe extern "C" fn ext_new( + ); + return null_mut(); + } +- let tag = PyTuple_GET_ITEM(args, 0); ++ let tag = PyTuple_GetItem(args, 0); + if PyLong_Check(tag) == 0 { + PyErr_SetString( + PyExc_TypeError, +@@ -30,7 +30,7 @@ unsafe extern "C" fn ext_new( + ); + return null_mut(); + } +- let data = PyTuple_GET_ITEM(args, 1); ++ let data = PyTuple_GetItem(args, 1); + if PyBytes_Check(data) == 0 { + PyErr_SetString( + PyExc_TypeError, +diff --git a/src/ffi.rs b/src/ffi.rs +index 4e5ddc3..20c9db4 100644 +--- a/src/ffi.rs ++++ b/src/ffi.rs +@@ -7,13 +7,16 @@ use std::ptr::NonNull; + #[allow(non_snake_case)] + #[inline(always)] + pub unsafe fn PyBytes_AS_STRING(op: *mut PyObject) -> *const c_char { +- &(*op.cast::()).ob_sval as *const c_char ++ #[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))] ++ return &(*op.cast::()).ob_sval as *const c_char; ++ #[cfg(any(PyPy, GraalPy, Py_LIMITED_API))] ++ return crate::PyBytes_AsString(op); + } + + #[allow(non_snake_case)] + #[inline(always)] + pub unsafe fn PyBytes_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { +- (*op.cast::()).ob_size ++ Py_SIZE(op) + } + + #[repr(C)] +@@ -63,11 +66,21 @@ pub fn pylong_is_positive(op: *mut PyObject) -> bool { + unsafe { (*(op as *mut PyLongObject)).long_value.lv_tag & SIGN_MASK == 0 } + } + +-#[cfg(not(Py_3_12))] ++#[cfg(not(any(Py_3_12, GraalPy)))] + pub fn pylong_is_positive(op: *mut PyObject) -> bool { + unsafe { (*(op as *mut PyVarObject)).ob_size > 0 } + } + ++extern "C" { ++ #[cfg(not(PyPy))] ++ pub fn _PyLong_Sign(v: *mut PyObject) -> c_int; ++} ++ ++#[cfg(GraalPy)] ++pub fn pylong_is_positive(op: *mut PyObject) -> bool { ++ unsafe { _PyLong_Sign(op) > 0 } ++} ++ + pub struct PyDictIter { + op: *mut PyObject, + pos: isize, +diff --git a/src/lib.rs b/src/lib.rs +index f10b1c4..1a9768b 100644 +--- a/src/lib.rs ++++ b/src/lib.rs +@@ -143,7 +143,7 @@ fn raise_unpackb_exception(msg: &str) -> *mut PyObject { + let err_msg = + PyUnicode_FromStringAndSize(msg.as_ptr() as *const c_char, msg.len() as isize); + let args = PyTuple_New(1); +- PyTuple_SET_ITEM(args, 0, err_msg); ++ PyTuple_SetItem(args, 0, err_msg); + PyErr_SetObject(typeref::MsgpackDecodeError, args); + Py_DECREF(args); + }; +@@ -199,10 +199,10 @@ pub unsafe extern "C" fn unpackb( + if !kwnames.is_null() { + let tuple_size = PyTuple_GET_SIZE(kwnames); + for i in 0..tuple_size { +- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t); +- if arg == typeref::EXT_HOOK { ++ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t); ++ if PyUnicode_Compare(arg, typeref::EXT_HOOK) == 0 { + ext_hook = Some(NonNull::new_unchecked(*args.offset(num_args + i))); +- } else if arg == typeref::OPTION { ++ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 { + optsptr = Some(NonNull::new_unchecked(*args.offset(num_args + i))); + } else { + return raise_unpackb_exception("unpackb() got an unexpected keyword argument"); +@@ -247,15 +247,15 @@ pub unsafe extern "C" fn packb( + if !kwnames.is_null() { + let tuple_size = PyTuple_GET_SIZE(kwnames); + for i in 0..tuple_size { +- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t); +- if arg == typeref::DEFAULT { ++ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t); ++ if PyUnicode_Compare(arg, typeref::DEFAULT) == 0 { + if unlikely!(default.is_some()) { + return raise_packb_exception( + "packb() got multiple values for argument: 'default'", + ); + } + default = Some(NonNull::new_unchecked(*args.offset(num_args + i))); +- } else if arg == typeref::OPTION { ++ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 { + if unlikely!(optsptr.is_some()) { + return raise_packb_exception( + "packb() got multiple values for argument: 'option'", +diff --git a/src/serialize/datetime.rs b/src/serialize/datetime.rs +index 63212d6..5ac2b2b 100644 +--- a/src/serialize/datetime.rs ++++ b/src/serialize/datetime.rs +@@ -61,9 +61,14 @@ pub struct Time { + + impl Time { + pub fn new(ptr: *mut pyo3::ffi::PyObject, opts: Opt) -> Result { ++ #[cfg(not(GraalPy))] + if unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_Time)).hastzinfo != 0 } { + return Err(TimeError::HasTimezone); + } ++ #[cfg(GraalPy)] ++ if unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(ptr) != crate::typeref::NONE } { ++ return Err(TimeError::HasTimezone); ++ } + Ok(Time { + ptr: ptr, + opts: opts, +@@ -114,23 +119,28 @@ impl std::fmt::Display for DateTimeError { + } + + fn utcoffset(ptr: *mut pyo3::ffi::PyObject) -> Result { ++ #[cfg(not(GraalPy))] + if !unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 } { + return Ok(Offset::default()); + } + + let tzinfo = ffi!(PyDateTime_DATE_GET_TZINFO(ptr)); ++ #[cfg(GraalPy)] ++ if unsafe { tzinfo == crate::typeref::NONE } { ++ return Ok(Offset::default()); ++ } + let py_offset: *mut pyo3::ffi::PyObject; + if ffi!(PyObject_HasAttr(tzinfo, CONVERT_METHOD_STR)) == 1 { + // pendulum +- py_offset = ffi!(PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR)); ++ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR) }; + } else if ffi!(PyObject_HasAttr(tzinfo, NORMALIZE_METHOD_STR)) == 1 { + // pytz +- let normalized = ffi!(PyObject_CallMethodOneArg(tzinfo, NORMALIZE_METHOD_STR, ptr)); +- py_offset = ffi!(PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR)); ++ let normalized = ffi!(PyObject_CallMethodObjArgs(tzinfo, NORMALIZE_METHOD_STR, ptr, std::ptr::null_mut::())); ++ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR) }; + ffi!(Py_DECREF(normalized)); + } else if ffi!(PyObject_HasAttr(tzinfo, DST_STR)) == 1 { + // dateutil/arrow, datetime.timezone.utc +- py_offset = ffi!(PyObject_CallMethodOneArg(tzinfo, UTCOFFSET_METHOD_STR, ptr)); ++ py_offset = ffi!(PyObject_CallMethodObjArgs(tzinfo, UTCOFFSET_METHOD_STR, ptr, std::ptr::null_mut::())); + } else { + return Err(DateTimeError::LibraryUnsupported); + } +@@ -193,7 +203,10 @@ impl TimeLike for DateTime { + + impl DateTimeLike for DateTime { + fn has_tz(&self) -> bool { +- unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 } ++ #[cfg(not(GraalPy))] ++ return unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 }; ++ #[cfg(GraalPy)] ++ return unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(self.ptr) != crate::typeref::NONE }; + } + + fn offset(&self) -> Offset { +diff --git a/src/serialize/numpy.rs b/src/serialize/numpy.rs +index afc5cdf..4d007bd 100644 +--- a/src/serialize/numpy.rs ++++ b/src/serialize/numpy.rs +@@ -392,8 +392,8 @@ impl NumpyDatetimeUnit { + fn from_pyobject(ptr: *mut PyObject) -> Self { + let dtype = ffi!(PyObject_GetAttr(ptr, DTYPE_STR)); + let descr = ffi!(PyObject_GetAttr(dtype, DESCR_STR)); +- let el0 = ffi!(PyList_GET_ITEM(descr, 0)); +- let descr_str = ffi!(PyTuple_GET_ITEM(el0, 1)); ++ let el0 = ffi!(PyList_GetItem(descr, 0)); ++ let descr_str = ffi!(PyTuple_GetItem(el0, 1)); + let uni = crate::unicode::unicode_to_str(descr_str).unwrap(); + if uni.len() < 5 { + return Self::NaT; +diff --git a/src/serialize/serializer.rs b/src/serialize/serializer.rs +index 309e6e1..6f7dec7 100644 +--- a/src/serialize/serializer.rs ++++ b/src/serialize/serializer.rs +@@ -864,7 +864,7 @@ impl Serialize for DictTupleKey { + let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize; + let mut seq = serializer.serialize_seq(Some(len)).unwrap(); + for i in 0..len { +- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize)); ++ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize)); + let value = DictKey::new(item, self.opts, self.recursion + 1); + seq.serialize_element(&value)?; + } +diff --git a/src/serialize/tuple.rs b/src/serialize/tuple.rs +index fa81cb6..9b66019 100644 +--- a/src/serialize/tuple.rs ++++ b/src/serialize/tuple.rs +@@ -41,7 +41,7 @@ impl Serialize for Tuple { + let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize; + let mut seq = serializer.serialize_seq(Some(len)).unwrap(); + for i in 0..len { +- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize)); ++ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize)); + let value = PyObject::new( + item, + self.opts, +diff --git a/src/serialize/writer.rs b/src/serialize/writer.rs +index a790bdd..35346d9 100644 +--- a/src/serialize/writer.rs ++++ b/src/serialize/writer.rs +@@ -27,7 +27,6 @@ impl BytesWriter { + pub fn finish(&mut self) -> NonNull { + unsafe { + std::ptr::write(self.buffer_ptr(), 0); +- (*self.bytes.cast::()).ob_size = self.len as Py_ssize_t; + self.resize(self.len); + NonNull::new_unchecked(self.bytes as *mut PyObject) + } +@@ -35,10 +34,14 @@ impl BytesWriter { + + fn buffer_ptr(&self) -> *mut u8 { + unsafe { +- std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!( ++ #[cfg(not(GraalPy))] ++ return std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!( + (*self.bytes).ob_sval + )) +- .add(self.len) ++ .add(self.len); ++ #[cfg(GraalPy)] ++ return std::mem::transmute::<*mut i8, *mut u8>(PyBytes_AsString(self.bytes.cast::())) ++ .add(self.len); + } + } + +diff --git a/src/unicode.rs b/src/unicode.rs +index 53aca09..552fa6c 100644 +--- a/src/unicode.rs ++++ b/src/unicode.rs +@@ -6,6 +6,7 @@ use pyo3::ffi::*; + + // see unicodeobject.h for documentation + ++#[cfg(not(GraalPy))] + pub fn unicode_from_str(buf: &str) -> *mut PyObject { + if buf.is_empty() { + ffi!(Py_INCREF(EMPTY_UNICODE)); +@@ -27,6 +28,13 @@ pub fn unicode_from_str(buf: &str) -> *mut PyObject { + } + } + ++#[cfg(GraalPy)] ++pub fn unicode_from_str(buf: &str) -> *mut PyObject { ++ unsafe { ++ PyUnicode_FromStringAndSize(buf.as_ptr() as *const i8, buf.len() as isize) ++ } ++} ++ + fn pyunicode_ascii(buf: &str) -> *mut PyObject { + unsafe { + let ptr = ffi!(PyUnicode_New(buf.len() as isize, 127)); +@@ -80,6 +88,7 @@ fn pyunicode_fourbyte(buf: &str, num_chars: usize) -> *mut PyObject { + + #[inline] + pub fn hash_str(op: *mut PyObject) -> Py_hash_t { ++ #[cfg(not(GraalPy))] + unsafe { + let data_ptr: *mut c_void = if (*op.cast::()).compact() == 1 + && (*op.cast::()).ascii() == 1 +@@ -92,7 +101,11 @@ pub fn hash_str(op: *mut PyObject) -> Py_hash_t { + (*(op as *mut PyASCIIObject)).length * ((*(op as *mut PyASCIIObject)).kind()) as isize; + let hash = _Py_HashBytes(data_ptr, num_bytes); + (*op.cast::()).hash = hash; +- hash ++ return hash; ++ } ++ #[cfg(GraalPy)] ++ unsafe { ++ return PyObject_Hash(op); + } + } + +@@ -109,19 +122,24 @@ pub fn unicode_to_str_via_ffi(op: *mut PyObject) -> Option<&'static str> { + + #[inline] + pub fn unicode_to_str(op: *mut PyObject) -> Option<&'static str> { ++ #[cfg(not(GraalPy))] + unsafe { + if unlikely!((*op.cast::()).compact() == 0) { +- unicode_to_str_via_ffi(op) ++ return unicode_to_str_via_ffi(op); + } else if (*op.cast::()).ascii() == 1 { + let ptr = op.cast::().offset(1) as *const u8; + let len = (*op.cast::()).length as usize; +- Some(str_from_slice!(ptr, len)) ++ return Some(str_from_slice!(ptr, len)); + } else if (*op.cast::()).utf8_length != 0 { + let ptr = (*op.cast::()).utf8 as *const u8; + let len = (*op.cast::()).utf8_length as usize; +- Some(str_from_slice!(ptr, len)) ++ return Some(str_from_slice!(ptr, len)); + } else { +- unicode_to_str_via_ffi(op) ++ return unicode_to_str_via_ffi(op); + } + } ++ #[cfg(GraalPy)] ++ unsafe { ++ return unicode_to_str_via_ffi(op); ++ } + } +diff --git a/src/util.rs b/src/util.rs +index 2bcc32d..89faf1a 100644 +--- a/src/util.rs ++++ b/src/util.rs +@@ -8,7 +8,7 @@ macro_rules! py_is { + + macro_rules! ob_type { + ($obj:expr) => { +- unsafe { (*($obj as *mut pyo3::ffi::PyObject)).ob_type } ++ unsafe { pyo3::ffi::Py_TYPE($obj as *mut pyo3::ffi::PyObject) } + }; + } + +-- +2.43.0 + From b50b6bc525f7ced037aaf3941286be9c9724477c Mon Sep 17 00:00:00 2001 From: Michael Simacek Date: Tue, 6 May 2025 12:54:14 +0200 Subject: [PATCH 34/36] Add patch for pythran 0.16+ Related #501 --- .../lib-graalpython/patches/metadata.toml | 7 +- .../patches/pythran-0.16.patch | 70 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 graalpython/lib-graalpython/patches/pythran-0.16.patch diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index 3c331d1657..7be5bef267 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -564,10 +564,15 @@ patch = 'pythran-0.13.patch' license = 'BSD-3-Clause' [[pythran.rules]] -version = '>= 0.14' +version = '>= 0.14, < 0.16' patch = 'pythran-0.15.patch' license = 'BSD-3-Clause' +[[pythran.rules]] +version = '>= 0.16' +patch = 'pythran-0.16.patch' +license = 'BSD-3-Clause' + [[pyzmq.rules]] # 26+ needs Cython 3 version = '< 26' diff --git a/graalpython/lib-graalpython/patches/pythran-0.16.patch b/graalpython/lib-graalpython/patches/pythran-0.16.patch new file mode 100644 index 0000000000..3fda5ec7ab --- /dev/null +++ b/graalpython/lib-graalpython/patches/pythran-0.16.patch @@ -0,0 +1,70 @@ +diff --git a/pythran/pythonic/python/core.hpp b/pythran/pythonic/python/core.hpp +index 4cbe3e0..24340b0 100644 +--- a/pythran/pythonic/python/core.hpp ++++ b/pythran/pythonic/python/core.hpp +@@ -53,7 +53,14 @@ namespace python + { + + #ifndef PyString_AS_STRING +-#define PyString_AS_STRING (char *)_PyUnicode_COMPACT_DATA ++ static inline const char* PyString_AS_STRING(PyObject* obj) { ++ const char* str = PyUnicode_AsUTF8(obj); ++ if (!str) { ++ PyErr_Clear(); ++ str = ""; ++ } ++ return str; ++ } + #endif + + inline void PyObject_TypePrettyPrinter(std::ostream &oss, PyObject *obj) +diff --git a/pythran/pythonic/types/str.hpp b/pythran/pythonic/types/str.hpp +index e5dbe60..41d1658 100644 +--- a/pythran/pythonic/types/str.hpp ++++ b/pythran/pythonic/types/str.hpp +@@ -741,10 +741,17 @@ namespace std + #define PyString_FromStringAndSize PyUnicode_FromStringAndSize + + #ifndef PyString_Check +-#define PyString_Check(x) PyUnicode_Check(x) && PyUnicode_IS_COMPACT_ASCII(x) ++#define PyString_Check(x) PyUnicode_Check(x) + #endif + #ifndef PyString_AS_STRING +-#define PyString_AS_STRING (char *)_PyUnicode_COMPACT_DATA ++ static inline const char* PyString_AS_STRING(PyObject* obj) { ++ const char* str = PyUnicode_AsUTF8(obj); ++ if (!str) { ++ PyErr_Clear(); ++ str = ""; ++ } ++ return str; ++ } + #endif + #ifndef PyString_GET_SIZE + #define PyString_GET_SIZE PyUnicode_GET_LENGTH +diff --git a/pythran/tables.py b/pythran/tables.py +index d62abe1..4ba279d 100644 +--- a/pythran/tables.py ++++ b/pythran/tables.py +@@ -4617,7 +4617,10 @@ def save_arguments(module_name, elements): + # some function are actually forward function, detect those + # and accept to use our description instead. + if looks_like_a_forward_function(spec): +- assert signature.args.args, "{} require an explicit description".format(elem) ++ # GraalPy change: we have signatures for more builtins than ++ # CPython and this trips up on type constructors like `dict` or ++ # `BaseException`. ++ # assert signature.args.args, "{} require an explicit description".format(elem) + continue + + args = [ast.Name(arg, ast.Param(), None, None) +@@ -4630,7 +4633,8 @@ def save_arguments(module_name, elements): + defaults = list(spec.defaults or []) + args += [ast.Name(arg, ast.Param(), None, None) + for arg in spec.kwonlyargs] +- defaults += [spec.kwonlydefaults[kw] for kw in spec.kwonlyargs] ++ if spec.kwonlydefaults: ++ defaults += [spec.kwonlydefaults[kw] for kw in spec.kwonlyargs] + + # Check if we already have a pythran description for that object + if signature.args.args: From 0ba7a7f2384cbfb68415d972e422284eb73cc854 Mon Sep 17 00:00:00 2001 From: Michael Simacek Date: Wed, 21 May 2025 17:54:34 +0200 Subject: [PATCH 35/36] Work around missing AttributeError kwargs --- .../lib-graalpython/patches/metadata.toml | 8 +- .../lib-graalpython/patches/numpy-2.2.4.patch | 182 ++++++++++++++++++ 2 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 graalpython/lib-graalpython/patches/numpy-2.2.4.patch diff --git a/graalpython/lib-graalpython/patches/metadata.toml b/graalpython/lib-graalpython/patches/metadata.toml index 7be5bef267..b9d99a732b 100644 --- a/graalpython/lib-graalpython/patches/metadata.toml +++ b/graalpython/lib-graalpython/patches/metadata.toml @@ -296,7 +296,13 @@ patch = 'numba-0.59.1.patch' license = 'BSD-2-Clause' [[numpy.rules]] -version = '>= 2.0.0rc1, < 2.3' +version = '== 2.2.4' +patch = 'numpy-2.2.4.patch' +license = 'BSD-3-Clause' +dist-type = 'sdist' + +[[numpy.rules]] +version = '>= 2.0.0rc1, < 2.1' patch = 'numpy-2.0.0.patch' license = 'BSD-3-Clause' dist-type = 'sdist' diff --git a/graalpython/lib-graalpython/patches/numpy-2.2.4.patch b/graalpython/lib-graalpython/patches/numpy-2.2.4.patch new file mode 100644 index 0000000000..49760fcb51 --- /dev/null +++ b/graalpython/lib-graalpython/patches/numpy-2.2.4.patch @@ -0,0 +1,182 @@ +diff --git a/numpy/__init__.py b/numpy/__init__.py +index 2a4fd03..4df4f2d 100644 +--- a/numpy/__init__.py ++++ b/numpy/__init__.py +@@ -371,7 +371,7 @@ def __getattr__(attr): + return char + elif attr == "array_api": + raise AttributeError("`numpy.array_api` is not available from " +- "numpy 2.0 onwards", name=None) ++ "numpy 2.0 onwards") + elif attr == "core": + import numpy.core as core + return core +@@ -384,7 +384,7 @@ def __getattr__(attr): + return distutils + else: + raise AttributeError("`numpy.distutils` is not available from " +- "Python 3.12 onwards", name=None) ++ "Python 3.12 onwards") + + if attr in __future_scalars__: + # And future warnings for those that will change, but also give +@@ -394,13 +394,12 @@ def __getattr__(attr): + "corresponding NumPy scalar.", FutureWarning, stacklevel=2) + + if attr in __former_attrs__: +- raise AttributeError(__former_attrs__[attr], name=None) ++ raise AttributeError(__former_attrs__[attr]) + + if attr in __expired_attributes__: + raise AttributeError( + f"`np.{attr}` was removed in the NumPy 2.0 release. " + f"{__expired_attributes__[attr]}", +- name=None + ) + + if attr == "chararray": +diff --git a/numpy/_core/include/numpy/ndarrayobject.h b/numpy/_core/include/numpy/ndarrayobject.h +index 0462625..3625e34 100644 +--- a/numpy/_core/include/numpy/ndarrayobject.h ++++ b/numpy/_core/include/numpy/ndarrayobject.h +@@ -220,7 +220,7 @@ NPY_TITLE_KEY_check(PyObject *key, PyObject *value) + if (key == title) { + return 1; + } +-#ifdef PYPY_VERSION ++#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON) + /* + * On PyPy, dictionary keys do not always preserve object identity. + * Fall back to comparison by value. +diff --git a/numpy/_core/src/multiarray/compiled_base.c b/numpy/_core/src/multiarray/compiled_base.c +index e3af951..48a7030 100644 +--- a/numpy/_core/src/multiarray/compiled_base.c ++++ b/numpy/_core/src/multiarray/compiled_base.c +@@ -1465,6 +1465,7 @@ fail: + NPY_NO_EXPORT PyObject * + arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *const *args, Py_ssize_t len_args) + { ++#if 0 // GraalPy change + PyObject *obj; + PyObject *str; + const char *docstr; +@@ -1569,6 +1570,7 @@ arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *const *args, Py_ssize_t + } + + #undef _ADDDOC ++#endif // GraalPy change + + Py_RETURN_NONE; + } +diff --git a/numpy/_core/src/multiarray/shape.c b/numpy/_core/src/multiarray/shape.c +index 340fe72..8f13674 100644 +--- a/numpy/_core/src/multiarray/shape.c ++++ b/numpy/_core/src/multiarray/shape.c +@@ -97,6 +97,11 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck, + "cannot resize an array with refcheck=True on PyPy.\n" + "Use the np.resize function or refcheck=False"); + return NULL; ++#elif defined(GRAALVM_PYTHON) ++ PyErr_SetString(PyExc_ValueError, ++ "cannot resize an array with refcheck=True on GraalPy.\n" ++ "Use the np.resize function or refcheck=False"); ++ return NULL; + #else + refcnt = Py_REFCNT(self); + #endif /* PYPY_VERSION */ +diff --git a/numpy/_core/src/multiarray/stringdtype/dtype.c b/numpy/_core/src/multiarray/stringdtype/dtype.c +index 0350375..8b254cb 100644 +--- a/numpy/_core/src/multiarray/stringdtype/dtype.c ++++ b/numpy/_core/src/multiarray/stringdtype/dtype.c +@@ -841,7 +841,7 @@ init_string_dtype(void) + }; + + /* Loaded dynamically, so needs to be set here: */ +- Py_TYPE(((PyObject *)&PyArray_StringDType)) = &PyArrayDTypeMeta_Type; ++ Py_SET_TYPE(((PyObject *)&PyArray_StringDType), &PyArrayDTypeMeta_Type); + ((PyTypeObject *)&PyArray_StringDType)->tp_base = &PyArrayDescr_Type; + if (PyType_Ready((PyTypeObject *)&PyArray_StringDType) < 0) { + return -1; +diff --git a/numpy/_core/src/multiarray/temp_elide.c b/numpy/_core/src/multiarray/temp_elide.c +index 662a2fa..791ede8 100644 +--- a/numpy/_core/src/multiarray/temp_elide.c ++++ b/numpy/_core/src/multiarray/temp_elide.c +@@ -58,7 +58,7 @@ + * supported too by using the appropriate Windows APIs. + */ + +-#if defined HAVE_BACKTRACE && defined HAVE_DLFCN_H && ! defined PYPY_VERSION ++#if defined HAVE_BACKTRACE && defined HAVE_DLFCN_H && ! defined PYPY_VERSION && !defined(GRAALVM_PYTHON) + + #include + +diff --git a/numpy/_core/src/npymath/ieee754.c.src b/numpy/_core/src/npymath/ieee754.c.src +index 8fccc9a..3bb9cf0 100644 +--- a/numpy/_core/src/npymath/ieee754.c.src ++++ b/numpy/_core/src/npymath/ieee754.c.src +@@ -362,6 +362,11 @@ int npy_get_floatstatus_barrier(char* param) + * By using a volatile, the compiler cannot reorder this call + */ + if (param != NULL) { ++ // GraalPy change: the pointer needs to be dereferenced to establish ++ // a data dependency to to ensure the compiler won't reorder the call ++ if (points_to_py_handle_space(param)) { ++ param = (char*)pointer_to_stub(param); ++ } + volatile char NPY_UNUSED(c) = *(char*)param; + } + +diff --git a/numpy/_core/src/npymath/ieee754.cpp b/numpy/_core/src/npymath/ieee754.cpp +index 1c59bf3..519fabc 100644 +--- a/numpy/_core/src/npymath/ieee754.cpp ++++ b/numpy/_core/src/npymath/ieee754.cpp +@@ -428,6 +428,11 @@ npy_get_floatstatus_barrier(char *param) + * By using a volatile, the compiler cannot reorder this call + */ + if (param != NULL) { ++ // GraalPy change: the pointer needs to be dereferenced to establish ++ // a data dependency to to ensure the compiler won't reorder the call ++ if (points_to_py_handle_space(param)) { ++ param = (char*)pointer_to_stub(param); ++ } + volatile char NPY_UNUSED(c) = *(char *)param; + } + +diff --git a/numpy/lib/__init__.py b/numpy/lib/__init__.py +index 928121c..bbe6a7e 100644 +--- a/numpy/lib/__init__.py ++++ b/numpy/lib/__init__.py +@@ -70,7 +70,6 @@ def __getattr__(attr): + "numpy.lib.emath was an alias for emath module that was removed " + "in NumPy 2.0. Replace usages of numpy.lib.emath with " + "numpy.emath.", +- name=None + ) + elif attr in ( + "histograms", "type_check", "nanfunctions", "function_base", +@@ -81,13 +80,11 @@ def __getattr__(attr): + f"numpy.lib.{attr} is now private. If you are using a public " + "function, it should be available in the main numpy namespace, " + "otherwise check the NumPy 2.0 migration guide.", +- name=None + ) + elif attr == "arrayterator": + raise AttributeError( + "numpy.lib.arrayterator submodule is now private. To access " + "Arrayterator class use numpy.lib.Arrayterator.", +- name=None + ) + else: + raise AttributeError("module {!r} has no attribute " +diff --git a/vendored-meson/meson/mesonbuild/utils/universal.py b/vendored-meson/meson/mesonbuild/utils/universal.py +index 6aee268..539be8b 100644 +--- a/vendored-meson/meson/mesonbuild/utils/universal.py ++++ b/vendored-meson/meson/mesonbuild/utils/universal.py +@@ -728,6 +728,7 @@ def windows_detect_native_arch() -> str: + """ + if sys.platform != 'win32': + return '' ++ return 'amd64' # Workaround for GraalPy bug on Windows with kernel32.GetCurrentProcess() + try: + import ctypes + process_arch = ctypes.c_ushort() From 6c98b10d65acfa01cfdc112a669e492ce642d21d Mon Sep 17 00:00:00 2001 From: Michael Simacek Date: Tue, 20 May 2025 15:05:20 +0200 Subject: [PATCH 36/36] Fix torch 2.4.1 patch --- .../lib-graalpython/patches/torch-2.4.1.patch | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/graalpython/lib-graalpython/patches/torch-2.4.1.patch b/graalpython/lib-graalpython/patches/torch-2.4.1.patch index caebd3aa86..3dc4d354e3 100644 --- a/graalpython/lib-graalpython/patches/torch-2.4.1.patch +++ b/graalpython/lib-graalpython/patches/torch-2.4.1.patch @@ -178,6 +178,19 @@ index f5fdbf155..d76176cb6 100644 class TestWrapperSubclassAliasing(TestCase): +diff --git a/third_party/fbgemm/CMakeLists.txt b/third_party/fbgemm/CMakeLists.txt +index 134523e7d..a00538e3c 100644 +--- a/third_party/fbgemm/CMakeLists.txt ++++ b/third_party/fbgemm/CMakeLists.txt +@@ -10,6 +10,8 @@ + + cmake_minimum_required(VERSION 3.16 FATAL_ERROR) + ++add_compile_options(-Wno-error=maybe-uninitialized -Wno-error=uninitialized -Wno-error=restrict) ++ + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") + + # Define function to extract filelists from defs.bzl file diff --git a/third_party/pybind11/include/pybind11/detail/common.h b/third_party/pybind11/include/pybind11/detail/common.h index 454e6061b..7feafc7d7 100644 --- a/third_party/pybind11/include/pybind11/detail/common.h @@ -537,20 +550,6 @@ index c301da982..a2668be20 100644 +const int THP_PyOpcode_Caches_size = 0; + +#endif // GraalPy change -diff --git a/torch/csrc/dynamo/extra_state.c b/torch/csrc/dynamo/extra_state.c -index cbe9ab37a..18740a0d8 100644 ---- a/torch/csrc/dynamo/extra_state.c -+++ b/torch/csrc/dynamo/extra_state.c -@@ -100,9 +100,6 @@ void destroy_extra_state(void* obj) { - } - - void set_extra_state(PyCodeObject* code, ExtraState* extra_state) { -- ExtraState* old_extra_state = get_extra_state(code); -- CHECK(extra_state == nullptr || old_extra_state != extra_state); -- _PyCode_SetExtra((PyObject*)code, extra_index, extra_state); - } - - ExtraState* init_and_set_extra_state(PyCodeObject* code) { diff --git a/torch/csrc/dynamo/eval_frame.c b/torch/csrc/dynamo/eval_frame.c index cbe9ab37a..18740a0d8 100644 --- a/torch/csrc/dynamo/eval_frame.c @@ -628,6 +627,24 @@ index cbe9ab37a..18740a0d8 100644 return module; } +diff --git a/torch/csrc/dynamo/extra_state.cpp b/torch/csrc/dynamo/extra_state.cpp +index 7c9b4be00..b8edbcfda 100644 +--- a/torch/csrc/dynamo/extra_state.cpp ++++ b/torch/csrc/dynamo/extra_state.cpp +@@ -65,11 +65,13 @@ void destroy_extra_state(void* obj) { + } + + void set_extra_state(PyCodeObject* code, ExtraState* extra_state) { ++#if 0 // GraalPy change + ExtraState* old_extra_state = get_extra_state(code); + CHECK( + old_extra_state == nullptr || old_extra_state == SKIP_CODE || + old_extra_state != extra_state); + _PyCode_SetExtra((PyObject*)code, extra_index, extra_state); ++#endif // GraalPy change + } + + ExtraState* init_and_set_extra_state(PyCodeObject* code) { diff --git a/torch/csrc/jit/python/python_tracer.cpp b/torch/csrc/jit/python/python_tracer.cpp index 92e6e2d3a..4d2ec0bfe 100644 --- a/torch/csrc/jit/python/python_tracer.cpp pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy