Updike, Clark wrote:
> In the process of working on a unit test for the forthcoming
> "PyList implements List", I've come across a test that fails
> (even in jython 2.1) which AFAICT, should pass. I'm using
> Arrays.equals(Object[], Object[]) to compare an object array
> returned via java.util.List.toArray() with Object arrays that I
> build manually using reflection or jarray (either way, the
> behavior is the same).
>
> Arrays.equals() fails when it should otherwise pass. Here's
> the demonstration:
>
> ----------------------------------------------------------------
> from java.util import Arrays, ArrayList
> from java.lang.reflect import Array
> from java.lang import Object
>
> def testArrayEquals(arr1, arr2):
> """test 2 Object arrays to see if they are equals"""
>
> print "Arrays.equals(arr1, arr2): ", (
> Arrays.equals(arr1, arr2)
> and "PASSED" or "FAILED")
>
>
> print "element-by-element test: ",
> try:
> for (i,j) in zip(arr1, arr2):
> assert i == j
> except: print "FAILED"
> else: print "PASSED"
>
>
> # make the java.util.List
> arrayList = ArrayList()
> [arrayList.add(i) for i in range(4)]
>
> # make an Object array using reflection
> objArray = Array.newInstance(Object, arrayList.size())
> for i in range(4):
> objArray[i] = i
>
> print "Testing ArrayList.toArray() against Object array (reflection)"
> testArrayEquals(arrayList.toArray(), objArray)
>
> import jarray
> objArray = jarray.array(range(4), Object)
>
> print "Testing ArrayList.toArray() against Object array (jarray)"
> testArrayEquals(arrayList.toArray(), objArray)
>
> print "Testing ArrayList.toArray(Object[]) against Object array
> (jarray)"
> print "Arrays.equals(arrayList.toArray(objArray), objArray),: ", (
> Arrays.equals(arrayList.toArray(objArray), objArray)
> and "PASSED" or "FAILED")
> ------------------------------------------------------------------
>
> Running this produces:
>
> Jython 2.1 on java1.3.1_01 (JIT: null)
> Type "copyright", "credits" or "license" for more information.
>
>>>>execfile('/temp/ToArrayEquals.py')
>
> Testing ArrayList.toArray() against Object array (reflection)
> Arrays.equals(arr1, arr2): FAILED
> element-by-element test: PASSED
> Testing ArrayList.toArray() against Object array (jarray)
> Arrays.equals(arr1, arr2): FAILED
> element-by-element test: PASSED
> Testing ArrayList.toArray(Object[]) against Object array (jarray)
> Arrays.equals(arrayList.toArray(objArray), objArray),: PASSED
>
>
> In looking at the source for Arrays.equals(Object[], Object[]),
> it looks like it basically is doing the same
> arr1[i].equals(arr2[i].equals) that I'm doing on the
> element-by-element i == j test. So I don't see why
> there is any difference. Also, if I try the same thing using
> arrayList.toArray(objArray), which specifies the type of
> array to convert to, then Arrays.equals() works as expected.
>
> I wasn't able to debug down inside Arrays.equals() so I'm
> hoping someone has a clue.
>
I more than fear than dispatching is picking up the unbound
Object.equals through Arrays.equals as match, so you are really invoking
Object.equals(arr1,arr2)
One of those corner cases at some point we need to look at.
If you grab Arrays.equals with Class.getMethod and the right signature
and then you invoke it you get what expected.
|