Skip to content

Regression in PyArray.pyset() for Boolean output setter #411

@mahee96

Description

@mahee96

Jython 2.7.4 breaks old (proper) behavior exhibited by 2.5.2 and below for java receiver type expecting boolean[] array causing regression.

Jython 2.7.4 impl: (broken)

BOOLEAN("z", "boolean", Boolean.TYPE, 1, 0) {
@Override
void set(PyArray a, int i, PyObject value) {
Array.setBoolean(a.data, i, value.__nonzero__());
}

Jython 2.5.2 impl: (works)

}
}
Object o = Py.tojava(value, type);
if(o == Py.NoConversion) {
throw Py.TypeError("Type not compatible with array type");
}
Array.set(data, i, o);
}

In jython 2.5.2, for boolean array java receiver type, ex: someFunc(boolean[] array), the input value whatever it was ie primitive-java/object-java/python type was being converted to java type using Py.tojava(value, type).

But in jython 2.7.4, for the same receiver type, the input value matters if it is java-primitive/java-object/python type since not all of the java-Object types implement nonzero() and PyBoolean type is for python boolean values, currently the incoming java-object values all default to PyObject base impl for __nonzero() which just returns true always.

public boolean __nonzero__() {
return true;
}

This causes the inputs to the java-receiver function be all true, irrespective of what input was supplied from python script.
ex:

public class UnitUnderTest{
    public void someFunc(boolean[] array){
        if (array == null) {
            System.out.println("null");
            return;
        }

        System.out.print("[");
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[I]);
            if (i < (array.length-1)){
                System.out.print(", ");
            }
        }
        System.out.print("]");
    }
}
import java.lang.Boolean as Boolean
import java.lang.Boolean as Integer

a = [Boolean(0), Boolean(1), Boolean(0)]         # java-object [<java.lang.Boolean>, <java.lang.Boolean>, <java.lang.Boolean>]
b = [0, 1, 0]                                    # python         [<integer>, <integer>, <integer>]
c = [Integer(0), Integer(1), Integer(0)]         # java-object [<java.lang.Integer>, <java.lang.Integer>, <java.lang.Integer>]
# d = [boolean(0)]                                 # INVALID - because python doesnt have a boolean keyword and cannot be imported as object unlike java.lang.Boolean.        

import UnitUnderTest as uut

uut.someFunc(a)             # prints all values as true ?!
uut.someFunc(b)             # prints properly due to int values being python type (PyInteger) and all python types implement non-zero()
uut.someFunc(c)             # prints all values as true ?! 
######## jython 2.5.2 output #######
[false, true, false]                                # WORKS
[false, true, false]                                # WORKS
ERROR: Arg Integer can't be coerced into boolean.   # WORKS! by throwing error
######## jython 2.7.4 output #######
[true, true, true]      # FAIL!
[false, true, false]    # WORKS
[true, true, true]      # FAIL!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions