oracle / graalpython

A Python 3 implementation built on GraalVM
Other
1.2k stars 103 forks source link

`InteropLibrary.isNull(foreignObject)` isn't identical to `foreignObject is None` #345

Closed JaroslavTulach closed 11 months ago

JaroslavTulach commented 1 year ago

While investigating Enso/Python interop in https://github.com/enso-org/enso/issues/7387 I realized that I cannot call datetime.datetime via org.graalvm.polyglot.Value as dt.execute(2023, 7, 26, 5, 55, 57, 440, null):

Exception in thread "main" TypeError: tzinfo argument must be None or of a tzinfo subclass
    at <python> _check_tzinfo_arg(bin/graalvm-ee-java17-21.3.0/languages/python/lib-python/3/datetime.py:443:16056-16126)
    at <python> __new__(bin/graalvm-ee-java17-21.3.0/languages/python/lib-python/3/datetime.py:1587:53507-53531)
    at org.graalvm.sdk/org.graalvm.polyglot.Value.execute(Value.java:841)

After some investigation it turned out that the problem is in Java null not passing the a is None check. Following program demonstrates the issue:

import org.graalvm.polyglot.Context;

class t {
  public static void main(String... args) throws Exception {
    var ctx = Context.newBuilder().allowAllAccess(true).build();
    var dt = ctx.eval("python", """
    def x(n, a=None):
      print("Value is {} but is it really None? {} in testcase {}".format(a, a is None, n))
    x
    """);
    dt.execute("Implicit argument");
    dt.execute("Explicitly specified null", null);
  }
}

put the above code into t.java and run as graalvm/bin/java t.java and its going to yield:

Value is None but is it really None? True in testcase Implicit argument
Value is None but is it really None? False in testcase Explicitly specified null

After a lengthy slack discussion it seems the consensus is to guarantee that every foreign object that is InteropLibrary.isNull(...) should pass the a is None check.