Skip to content

Commit 38c69a5

Browse files
eregonansalond
authored andcommitted
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 95b0760)
1 parent 05ec2d7 commit 38c69a5

File tree

3 files changed

+19
-63
lines changed

3 files changed

+19
-63
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_interop.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -471,11 +471,20 @@ def test_java_import_from_jar(self):
471471
os.unlink(tempname)
472472

473473
def test_java_class(self):
474-
from java.lang import Integer, Number, NumberFormatException
475-
self.assertEqual(type(Integer).mro(), [polyglot.ForeignClass, polyglot.ForeignAbstractClass, polyglot.ForeignInstantiable, polyglot.ForeignObject, object])
474+
from java.lang import Number, NumberFormatException
475+
from java.util import ArrayList
476+
self.assertEqual(type(ArrayList).mro(), [polyglot.ForeignClass, polyglot.ForeignAbstractClass, polyglot.ForeignInstantiable, polyglot.ForeignObject, object])
476477
self.assertEqual(type(Number).mro(), [polyglot.ForeignAbstractClass, polyglot.ForeignObject, object])
477478
self.assertEqual(type(NumberFormatException).mro(), [polyglot.ForeignClass, polyglot.ForeignAbstractClass, polyglot.ForeignInstantiable, polyglot.ForeignObject, object])
478479

480+
from java.util import ArrayList
481+
l = ArrayList()
482+
assert isinstance(l, ArrayList)
483+
self.assertEqual(getattr(ArrayList, 'class'), l.getClass())
484+
485+
with self.assertRaisesRegex(TypeError, "ForeignInstantiable.__call__\(\) got an unexpected keyword argument 'kwarg'"):
486+
ArrayList(kwarg=42)
487+
479488
def test_java_exceptions(self):
480489
# TODO: more tests
481490

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignExecutableBuiltins.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,11 @@
3535
import com.oracle.graal.python.builtins.CoreFunctions;
3636
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
3737
import com.oracle.graal.python.builtins.PythonBuiltins;
38-
import com.oracle.graal.python.builtins.objects.function.PKeyword;
3938
import com.oracle.graal.python.nodes.ErrorMessages;
4039
import com.oracle.graal.python.nodes.PRaiseNode;
4140
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
4241
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
4342
import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
44-
import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
4543
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
4644
import com.oracle.graal.python.runtime.GilNode;
4745
import com.oracle.graal.python.runtime.IndirectCallData;
@@ -50,7 +48,6 @@
5048
import com.oracle.truffle.api.CompilerDirectives;
5149
import com.oracle.truffle.api.dsl.Bind;
5250
import com.oracle.truffle.api.dsl.Cached;
53-
import com.oracle.truffle.api.dsl.Fallback;
5451
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5552
import com.oracle.truffle.api.dsl.NodeFactory;
5653
import com.oracle.truffle.api.dsl.Specialization;
@@ -69,14 +66,13 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
6966
return ForeignExecutableBuiltinsFactory.getFactories();
7067
}
7168

72-
@Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
69+
@Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true)
7370
@GenerateNodeFactory
7471
public abstract static class CallNode extends PythonBuiltinNode {
75-
@Specialization(guards = {"isForeignObjectNode.execute(inliningTarget, callee)", "!isNoValue(callee)", "keywords.length == 0"}, limit = "1")
76-
static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
72+
@Specialization
73+
static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments,
7774
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
7875
@Cached("createFor(this)") IndirectCallData indirectCallData,
79-
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
8076
@CachedLibrary(limit = "4") InteropLibrary lib,
8177
@Cached PForeignToPTypeNode toPTypeNode,
8278
@Cached GilNode gil,
@@ -98,13 +94,6 @@ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] argument
9894
throw CompilerDirectives.shouldNotReachHere(e);
9995
}
10096
}
101-
102-
@Fallback
103-
@SuppressWarnings("unused")
104-
static Object doGeneric(Object callee, Object arguments, Object keywords,
105-
@Cached PRaiseNode raiseNode) {
106-
throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
107-
}
10897
}
10998

11099
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignInstantiableBuiltins.java

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,11 @@
3636
import com.oracle.graal.python.builtins.CoreFunctions;
3737
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
3838
import com.oracle.graal.python.builtins.PythonBuiltins;
39-
import com.oracle.graal.python.builtins.objects.function.PKeyword;
4039
import com.oracle.graal.python.nodes.ErrorMessages;
4140
import com.oracle.graal.python.nodes.PRaiseNode;
4241
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
4342
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
4443
import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
45-
import com.oracle.graal.python.nodes.object.IsForeignObjectNode;
4644
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
4745
import com.oracle.graal.python.runtime.GilNode;
4846
import com.oracle.graal.python.runtime.IndirectCallData;
@@ -51,7 +49,6 @@
5149
import com.oracle.truffle.api.CompilerDirectives;
5250
import com.oracle.truffle.api.dsl.Bind;
5351
import com.oracle.truffle.api.dsl.Cached;
54-
import com.oracle.truffle.api.dsl.Fallback;
5552
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5653
import com.oracle.truffle.api.dsl.NodeFactory;
5754
import com.oracle.truffle.api.dsl.Specialization;
@@ -70,46 +67,14 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
7067
return ForeignInstantiableBuiltinsFactory.getFactories();
7168
}
7269

73-
@Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
74-
@GenerateNodeFactory
75-
abstract static class NewNode extends PythonBuiltinNode {
76-
@Specialization(guards = {"isForeignObjectNode.execute(inliningTarget, callee)", "!isNoValue(callee)", "keywords.length == 0"}, limit = "1")
77-
static Object doInteropCall(Object callee, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
78-
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
79-
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
80-
@CachedLibrary(limit = "3") InteropLibrary lib,
81-
@Cached PForeignToPTypeNode toPTypeNode,
82-
@Cached GilNode gil,
83-
@Cached PRaiseNode.Lazy raiseNode) {
84-
gil.release(true);
85-
try {
86-
Object res = lib.instantiate(callee, arguments);
87-
return toPTypeNode.executeConvert(res);
88-
} catch (ArityException | UnsupportedTypeException e) {
89-
throw raiseNode.get(inliningTarget).raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
90-
} catch (UnsupportedMessageException e) {
91-
throw CompilerDirectives.shouldNotReachHere(e);
92-
} finally {
93-
gil.acquire();
94-
}
95-
}
96-
97-
@Fallback
98-
@SuppressWarnings("unused")
99-
static Object doGeneric(Object callee, Object arguments, Object keywords,
100-
@Cached PRaiseNode raiseNode) {
101-
throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
102-
}
103-
}
104-
105-
@Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
70+
@Builtin(name = J___NEW__, minNumOfPositionalArgs = 1, takesVarArgs = true)
71+
@Builtin(name = J___CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true)
10672
@GenerateNodeFactory
10773
public abstract static class CallNode extends PythonBuiltinNode {
108-
@Specialization(guards = {"isForeignObjectNode.execute(inliningTarget, callee)", "!isNoValue(callee)", "keywords.length == 0"}, limit = "1")
109-
static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments, @SuppressWarnings("unused") PKeyword[] keywords,
74+
@Specialization
75+
static Object doInteropCall(VirtualFrame frame, Object callee, Object[] arguments,
11076
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
11177
@Cached("createFor(this)") IndirectCallData indirectCallData,
112-
@SuppressWarnings("unused") @Cached IsForeignObjectNode isForeignObjectNode,
11378
@CachedLibrary(limit = "4") InteropLibrary lib,
11479
@Cached PForeignToPTypeNode toPTypeNode,
11580
@Cached GilNode gil,
@@ -131,13 +96,6 @@ static Object doInteropCall(VirtualFrame frame, Object callee, Object[] argument
13196
throw CompilerDirectives.shouldNotReachHere(e);
13297
}
13398
}
134-
135-
@Fallback
136-
@SuppressWarnings("unused")
137-
static Object doGeneric(Object callee, Object arguments, Object keywords,
138-
@Cached PRaiseNode raiseNode) {
139-
throw raiseNode.raise(PythonErrorType.TypeError, ErrorMessages.INVALID_INSTANTIATION_OF_FOREIGN_OBJ);
140-
}
14199
}
142100

143101
}

0 commit comments

Comments
 (0)