Issue2216

classification
Title: BigInteger(10L) > 100 returns True
Type: rfe Severity: normal
Components: Core Versions: Jython 2.7
Milestone:
process
Status: open Resolution: accepted
Dependencies: Superseder:
Assigned To: Nosy List: jeff.allen, santa4nt, zyasoft
Priority: normal Keywords:

Created on 2014-10-09.18:56:38 by santa4nt, last changed 2018-03-06.20:21:03 by jeff.allen.

Messages
msg9124 (view) Author: Santoso Wijaya (santa4nt) Date: 2014-10-09.18:56:37
Observe:

Jython 2.7b3+ (default:2c45f75a5406, Oct 7 2014, 17:21:51) 
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.7.0_67
Type "help", "copyright", "credits" or "license" for more information.
>>> from java.math import BigInteger
>>> a = BigInteger('10')
>>> type(a)
<type 'java.math.BigInteger'>
>>> a > 100
True

----------

The errant return value comes from this injected method in PyJavaType.java:

(lines 904-921)

    private static abstract class ComparableMethod extends PyBuiltinMethodNarrow {
        protected ComparableMethod(String name, int numArgs) {
            super(name, numArgs);
        }
        @Override
        public PyObject __call__(PyObject arg) {
            Object asjava = arg.__tojava__(Object.class);
            int compare;
            try {
                compare = ((Comparable<Object>)self.getJavaProxy()).compareTo(asjava);
            } catch(ClassCastException classCast) {
                return Py.NotImplemented;
            }
            return getResult(compare) ? Py.True : Py.False;
        }

        protected abstract boolean getResult(int comparison);
    }

In particular, a ClassCastException was thrown.

Which, when reduced, come to this simplified Java snippet:

import java.math.BigInteger;

public class BigCompare {

    public static void main(String[] args) {
        Object bi = (Object) new BigInteger("10");
        Object i = (Object) new Integer(100);
        System.out.println("" + ((Comparable<Object>)bi).compareTo(i));
    }   
}

$ java BigCompare 
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.math.BigInteger
        at java.math.BigInteger.compareTo(BigInteger.java:99)
        at BigCompare.main(BigCompare.java:8)
msg9125 (view) Author: Santoso Wijaya (santa4nt) Date: 2014-10-09.19:02:22
There's a dance inside Jython where Integer and BigInteger are tried to be coerced to each other for comparison, but all attempts failed. Hence, the non-conformant result.
msg9126 (view) Author: Jim Baker (zyasoft) Date: 2014-10-09.21:57:07
Need to fix this coercion so that it does something reasonable for comparing BigInteger and int for example. The default mechanism that ultimately uses class, then IdentityHashCode to determine ordering needs to be retained for 2.7, but can be pulled out for 3.x.
msg9133 (view) Author: Jeff Allen (jeff.allen) Date: 2014-10-13.08:23:42
This is apparently in response to http://permalink.gmane.org/gmane.comp.lang.jython.user/10467, but I think it does not answer the underlying problem. The underlying problem is a bug in our JSR-223 implementation probably also identified in #2090 and #1494. The mistake is to test this at the REPL prompt, when the problem is in the *different* interpreter used by the script engine. This seems to be why #1494 was closed, in error I think.

You could say the observed behaviour is correct, under the arcane Python 2 rules. BigInteger is not a special Java class to the interpreter, so it is not numerically comparable to int. Alternatively, having Jython treat java.lang.BigInteger as a number *may* be a good idea. (How about BigDecimal too? Or java.lang.Number in general, in the same way that Comparable gets special treatment?) It would be a new feature, not a bug-fix.
msg9913 (view) Author: Jim Baker (zyasoft) Date: 2015-04-20.21:00:48
Agreed, but a potentially nice new feature. Less important that what we did for Map, List, or Set however.
msg11755 (view) Author: Jeff Allen (jeff.allen) Date: 2018-03-06.20:21:03
I think we're saying that a more forgiving set of coercion rules should be in force for mathematical integers of various actual classes. I agree, but  don't see it as a *essential* for 2.7.2.
History
Date User Action Args
2018-03-06 20:21:03jeff.allensettype: behaviour -> rfe
messages: + msg11755
milestone: Jython 2.7.2 ->
2015-12-29 23:54:16zyasoftsetmilestone: Jython 2.7.1 -> Jython 2.7.2
2015-04-20 21:00:48zyasoftsetmessages: + msg9913
2015-04-15 20:43:36zyasoftsetassignee: zyasoft ->
milestone: Jython 2.7.1
2015-01-07 07:25:22zyasoftsetassignee: zyasoft
2014-10-13 08:23:43jeff.allensetnosy: + jeff.allen
messages: + msg9133
2014-10-09 21:57:07zyasoftsetpriority: normal
resolution: accepted
messages: + msg9126
nosy: + zyasoft
2014-10-09 19:02:22santa4ntsetmessages: + msg9125
2014-10-09 18:56:38santa4ntcreate