Skip to content

Commit 7760b1e

Browse files
committed
fix identity comparison for foreign types
1 parent 9535e62 commit 7760b1e

File tree

2 files changed

+51
-4
lines changed
  • graalpython

2 files changed

+51
-4
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,13 @@ def test_super(self):
720720
super(list, l).remove(0) # ArrayList#remove(int index)
721721
assert l == [6]
722722

723+
def test_issubclass_isinstance(self):
724+
from java.util import ArrayList, List
725+
assert issubclass(ArrayList, List)
726+
assert issubclass(ArrayList, ArrayList)
727+
assert isinstance(ArrayList(), List)
728+
assert isinstance(ArrayList(), ArrayList)
729+
723730
def test_java_array(self):
724731
import java
725732
il = java.type("int[]")(20)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
import com.oracle.graal.python.builtins.modules.WeakRefModuleBuiltinsFactory;
110110
import com.oracle.graal.python.builtins.modules.cext.PythonCextTypeBuiltins.GraalPyPrivate_Type_AddMember;
111111
import com.oracle.graal.python.builtins.objects.PNone;
112+
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
112113
import com.oracle.graal.python.builtins.objects.cell.PCell;
113114
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
114115
import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
@@ -222,6 +223,7 @@
222223
import com.oracle.truffle.api.CompilerDirectives.ValueType;
223224
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
224225
import com.oracle.truffle.api.RootCallTarget;
226+
import com.oracle.truffle.api.TruffleLanguage.Env;
225227
import com.oracle.truffle.api.dsl.Bind;
226228
import com.oracle.truffle.api.dsl.Cached;
227229
import com.oracle.truffle.api.dsl.Cached.Exclusive;
@@ -237,6 +239,8 @@
237239
import com.oracle.truffle.api.frame.Frame;
238240
import com.oracle.truffle.api.frame.VirtualFrame;
239241
import com.oracle.truffle.api.interop.InteropLibrary;
242+
import com.oracle.truffle.api.interop.UnknownIdentifierException;
243+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
240244
import com.oracle.truffle.api.library.CachedLibrary;
241245
import com.oracle.truffle.api.nodes.ControlFlowException;
242246
import com.oracle.truffle.api.nodes.Node;
@@ -1482,23 +1486,23 @@ static boolean doManaged(PythonManagedClass left, PythonManagedClass right) {
14821486
}
14831487

14841488
@Specialization
1485-
static boolean doManaged(PythonBuiltinClassType left, PythonBuiltinClassType right) {
1489+
static boolean doTypeType(PythonBuiltinClassType left, PythonBuiltinClassType right) {
14861490
return left == right;
14871491
}
14881492

14891493
@Specialization
1490-
static boolean doManaged(PythonBuiltinClassType left, PythonBuiltinClass right) {
1494+
static boolean doTypeClass(PythonBuiltinClassType left, PythonBuiltinClass right) {
14911495
return left == right.getType();
14921496
}
14931497

14941498
@Specialization
1495-
static boolean doManaged(PythonBuiltinClass left, PythonBuiltinClassType right) {
1499+
static boolean doClassType(PythonBuiltinClass left, PythonBuiltinClassType right) {
14961500
return left.getType() == right;
14971501
}
14981502

14991503
@Specialization
15001504
@InliningCutoff
1501-
static boolean doNativeSingleContext(PythonAbstractNativeObject left, PythonAbstractNativeObject right,
1505+
static boolean doNative(PythonAbstractNativeObject left, PythonAbstractNativeObject right,
15021506
@CachedLibrary(limit = "1") InteropLibrary lib) {
15031507
if (left == right) {
15041508
return true;
@@ -1509,6 +1513,42 @@ static boolean doNativeSingleContext(PythonAbstractNativeObject left, PythonAbst
15091513
return lib.isIdentical(left.getPtr(), right.getPtr(), lib);
15101514
}
15111515

1516+
@Specialization(guards = {"!isAnyPythonObject(left)", "!isAnyPythonObject(right)"})
1517+
@InliningCutoff
1518+
static boolean doOther(Object left, Object right,
1519+
@Bind PythonContext context,
1520+
@CachedLibrary(limit = "2") InteropLibrary lib) {
1521+
if (left == right) {
1522+
return true;
1523+
}
1524+
if (lib.isMetaObject(left) && lib.isMetaObject(right)) {
1525+
// *sigh*... Host classes have split personality with a "static" and a "class"
1526+
// side, and that affects identity comparisons. And they report their "class" sides
1527+
// as bases, but importing from Java gives you the "static" side.
1528+
Env env = context.getEnv();
1529+
if (env.isHostObject(left) && env.isHostObject(right)) {
1530+
// the activation of isMemberReadable and later readMember serves as branch
1531+
// profile
1532+
boolean leftIsStatic = lib.isMemberReadable(left, "class");
1533+
if (leftIsStatic != lib.isMemberReadable(right, "class")) {
1534+
try {
1535+
if (leftIsStatic) {
1536+
left = lib.readMember(left, "class");
1537+
} else {
1538+
right = lib.readMember(right, "class");
1539+
}
1540+
} catch (UnsupportedMessageException | UnknownIdentifierException e) {
1541+
throw CompilerDirectives.shouldNotReachHere(e);
1542+
}
1543+
}
1544+
}
1545+
if (lib.isIdentical(left, right, lib)) {
1546+
return true;
1547+
}
1548+
}
1549+
return false;
1550+
}
1551+
15121552
@Fallback
15131553
static boolean doOther(@SuppressWarnings("unused") Object left, @SuppressWarnings("unused") Object right) {
15141554
return false;

0 commit comments

Comments
 (0)