diff -r 316d634a5986 jython/src/templates/object.derived --- a/jython/src/templates/object.derived Sun May 18 22:58:27 2008 -0400 +++ b/jython/src/templates/object.derived Sun May 18 23:24:21 2008 -0400 @@ -84,17 +84,23 @@ rest: } public int __cmp__(PyObject other) { - PyType self_type = getType(); - PyObject impl = self_type.lookup("__cmp__"); - if (impl != null) { - PyObject res = impl.__get__(this,self_type).__call__(other); - if (res instanceof PyInteger) { - int v = ((PyInteger)res).getValue(); - return v < 0 ? -1 : v > 0 ? 1 : 0; - } - throw Py.TypeError("__cmp__ should return a int"); + PyType self_type=getType(); + PyType[] where_type = new PyType[1]; + PyObject impl = self_type.lookup_where("__cmp__", where_type); + // Full Compatibility with CPython __cmp__: + // If the derived type don't override __cmp__, the + // *internal* super().__cmp__ should be called, not the + // exposed one. The difference is that the exposed __cmp__ + // throws a TypeError if the argument is an instance of the same type. + if (impl == null || where_type[0] == TYPE) { + return super.__cmp__(other); } - return super.__cmp__(other); + PyObject res = impl.__get__(this,self_type).__call__(other); + if (res instanceof PyInteger) { + int v=((PyInteger)res).getValue(); + return v < 0 ? -1 : v > 0 ? 1 : 0; + } + throw Py.TypeError("__cmp__ should return a int"); } public boolean __nonzero__() {