Checking for NULL on pyjnius imported object

98 views
Skip to first unread message

Mike Deskevich

unread,
Mar 10, 2022, 11:38:56 AM3/10/22
to Kivy users support
Hi - I hope I'm not being dumb here, but I can't find in the docs how to check for a Java null object on the python side.

For example, I have a callback in python that the Java side populates with an object

def callback(obj):
  print(obj)

The java code may sometimes pass null in as the obj, I'd like to check on the python side for the null.  This doesn't work

def callback(obj):
  if (obj is None):
     #handle null

I presume that's because the object really does exist on the python side and that it just points to a null object on the java side.  I did see some state in the python class that did have an 0x0 in it, so I know that python knows it's a null object on Java.  I just can't figure out how to do the check correctly on the python side.

Thanks!


Robert

unread,
Mar 10, 2022, 12:15:46 PM3/10/22
to Kivy users support
As far as I am aware  None == null
Is self missing? (this would depend on the approach used for Java calling Python)

def callback(self,obj):
  if (obj is None):
     #handle null


Mike Deskevich

unread,
Mar 10, 2022, 12:59:31 PM3/10/22
to Kivy users support
The call back isn't existing in a class.  Here's a more realistic example.  This is they python code:

def Evaluate(sol):
  print(sol)
  print(sol is None)

sol is a Java object that's constructed on the Java side and passed into Evaluate. The first iteration sol is a valid object, on the second iteration sol is null.

<com/company/MyJavaClass at 0x22b75ad1768 jclass=com/company/MyJavaClass jself=<LocalRef obj=0x74d0cb30 at 0x22b75ac9330>>
False
<com/company/MyJavaClass at 0x22b75ad1ca8 jclass=com/company/MyJavaClass jself=<LocalRef obj=0x0 at 0x22b75ac93f0>>
False

I can see that the localref obj=0x0 in the second one means that someone knows that the object is null.

Robert

unread,
Mar 10, 2022, 2:45:29 PM3/10/22
to Kivy users support
OK I see what you are saying. I thought Pyjnius handled that.
How are you calling Evaluate from Java?

Elliot Garbus

unread,
Mar 10, 2022, 3:02:35 PM3/10/22
to kivy-...@googlegroups.com

It looks like the type is not a NoneType.

>>> type(None)

<class 'NoneType'>

>>> type(0x0)

<class 'int'>

 

Print out the type of the returned object.  

type(sol)

 

If it is sufficient you could check for a value of 0 or ‘truthiness”.

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/404dbcb4-e017-49cb-a766-124505a19a1fn%40googlegroups.com.

 

Mike Deskevich

unread,
Mar 10, 2022, 3:30:01 PM3/10/22
to Kivy users support
Robert - It's a bit convoluted on how I get the callback executed.  I have to fit into some legacy Java code, so it's not pretty.

On the Java side I have an interface

public interface SpecialPythonEvaluator {
  void Evaluate(MyJavaClass sol);
}

And then there's a special class that inherits from the framework I'm using

public class SpecialPythonClass extends LegacyClass {
  SpecialPythonEvaluator evaluator;

  public SpecialPythonClass(SpecialPythonEvaluator evaluator) {
    this.evaluator = evaluator;
  }

  public void Evaluate(MyJavaClass sol){
    evaluator.Evaluate(sol);
  }
}

On the Python side I have the python implementation of that interface

    class PythonEvaluator(PythonJavaClass):
        __javainterfaces__ = ['com/company/SpecialPythonEvaluator']

        def __init__(self, Evaluate=None):
            self.CBEvaluate = Evaluate

        @java_method('(Lcom/company/MyJavaClass;)V')
        def Evaluate(self, sol):
            if (self.CBEvaluate is not None):
                self.CBEvaluate(sol)


Then I construct the python class that implements the Java interface and pass it into my framework so that it gets called

myEvaluator=PythonEvaluator(Evaluate)
myMainObject=SpecialPythonClass(myEvaluator)

When the original (Java) LegacyClass calls it's Evaluate method, that gets overridden by (Java) SpecialPythonClass which has a handle to an interface (Java) SpecialPythonEvaluator.

There's a (Python) implementation of Python Evaluator that then forwards the call to a first-class (Python) function Evaluate.

It's not pretty, but it does work passing the right object around.  I just need to handle a special branch for when sol is (Java) null.  I have an idea of how to do it if pyjnius doesn't give me access to that, I was just hoping to make it pretty.


ElliotG -

For both of the null and not-null cases, I get this when I print my type

  print('Type=',type(sol))

Elliot Garbus

unread,
Mar 10, 2022, 4:25:49 PM3/10/22
to kivy-...@googlegroups.com

It the returned type is not NoneType, then sol is None will never be True.

Just test for zero

 

If not sol:

    # handle the case where zero is returned.

Robert

unread,
Mar 10, 2022, 4:31:12 PM3/10/22
to Kivy users support
It looks like you are doing the same thing as this https://github.com/Android-for-Python/Android-for-Python-Users#calling-python-from-java  which takes a convoluted brain to figure out!

But perhaps doesn't work in the argument null case?

How about move the test:

public void Evaluate(MyJavaClass sol){
    if (sol != null) {
         evaluator.Evaluate(sol);
    }
  }

Mike Deskevich

unread,
Mar 10, 2022, 5:12:54 PM3/10/22
to Kivy users support
Yeah, I tried the "if not" test from ElliotG, that also doesn't work. 

I'll do something similar to moving the test.  I do need to have a flag because I do have to implement different behavior on the null, but I'll just catch it early and send another flag.  Thanks for your help!

Mike Deskevich

unread,
Mar 10, 2022, 5:43:58 PM3/10/22
to Kivy users support
Just to wrap this up in case someone else has this issue.  It feels dirty to me, but it works. 

 I did this on the java end:

     public void Evaluate(MyJavaClass sol){
    if (sol == null) {
      evaluator.NullEvaluate();
    } else {
      evaluator.Evaluate(sol);
    }
  }   


and this on the python end:

        @java_method('(Lcom/company/MyJavaClass;)V')
        def Evaluate(self, sol):
            if (self.CBEvaluate is not None):
                self.CBEvaluate(sol)

        @java_method('()V')
        def NullEvaluate(self):
            if (self.CBEvaluate is not None):
                self.CBEvaluate(None)
Reply all
Reply to author
Forward
0 new messages