From d55626587537c74e74670b1a18657d7ea5d191ad Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Tue, 24 Jul 2018 12:02:57 +0200 Subject: [PATCH 01/11] [WIP] Do not use comparison methods defined on Str --- python/common/org/python/types/Object.java | 23 +++++++++++++++ tests/benchmarks.py | 34 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index ff7f82260d..e3bbb50b9e 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -1108,11 +1108,33 @@ public static org.python.Object __cmp__(org.python.Object v, org.python.Object w } } + private static org.python.Object resolveComparison(int cmpResult, String methodName) { + switch(methodName) { + case "__eq__": + return org.python.types.Bool.getBool(cmpResult == 0); + case "__lt__": + return org.python.types.Bool.getBool(cmpResult < 0); + case "__le__": + return org.python.types.Bool.getBool(cmpResult <= 0); + case "__gt__": + return org.python.types.Bool.getBool(cmpResult > 0); + case "__ge__": + return org.python.types.Bool.getBool(cmpResult >= 0); + default: + return org.python.types.NotImplementedType.NOT_IMPLEMENTED; + } + } + private static org.python.Object invokeComparison(org.python.Object x, org.python.Object y, String methodName) { if (methodName == null) { return org.python.types.NotImplementedType.NOT_IMPLEMENTED; } + if (x instanceof org.python.types.Str && y instanceof org.python.types.Str) { + int res = ((org.python.types.Str) x).value.compareTo(((org.python.types.Str) y).value); + return resolveComparison(res, methodName); + } + org.python.Object comparator = x.__getattribute_null(methodName); if (comparator == null || !(comparator instanceof org.python.types.Method)) { return org.python.types.NotImplementedType.NOT_IMPLEMENTED; @@ -1121,6 +1143,7 @@ private static org.python.Object invokeComparison(org.python.Object x, org.pytho org.python.Object[] args = new org.python.Object[1]; args[0] = y; return (org.python.Object) ((org.python.types.Method) comparator).invoke(args, null); + } public static boolean isSequence(org.python.Object other) { diff --git a/tests/benchmarks.py b/tests/benchmarks.py index f5655d660e..5811cdd2b6 100644 --- a/tests/benchmarks.py +++ b/tests/benchmarks.py @@ -138,6 +138,39 @@ def yarn(n): main(i) """), timed=True) +def test_str_comp(test_case): + print("Running", "string comparison") + test_case.runAsJava(adjust(""" + s = "mary had a little lamb" + t = "humpty dumpty sat on a wall" + + for i in range(1000): + for j in range(100): + print(s < t) + print(s <= t) + print(s == t) + print(s >= t) + print(s > t) + + print(s < t) + print(s <= t) + print(s == t) + print(s >= t) + print(s > t) + + print(s < t) + print(s <= t) + print(s == t) + print(s >= t) + print(s > t) + + print(s < t) + print(s <= t) + print(s == t) + print(s >= t) + print(s > t) + """), timed=True) + def main(): test_case = TranspileTestCase() test_case.setUpClass() @@ -147,6 +180,7 @@ def main(): test_class_var_load(test_case) test_function_var_load(test_case) test_code(test_case) + test_str_comp(test_case) if __name__== "__main__": main() From 6d9f61a3948d98cfa2500f0ce0fd66ef152850c7 Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Wed, 25 Jul 2018 17:02:13 +0200 Subject: [PATCH 02/11] special Ints as well --- python/common/org/python/types/Object.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index e3bbb50b9e..3d2c451c80 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -1120,6 +1120,8 @@ private static org.python.Object resolveComparison(int cmpResult, String methodN return org.python.types.Bool.getBool(cmpResult > 0); case "__ge__": return org.python.types.Bool.getBool(cmpResult >= 0); + case "__ne__": + return org.python.types.Bool.getBool(cmpResult != 0); default: return org.python.types.NotImplementedType.NOT_IMPLEMENTED; } @@ -1135,6 +1137,13 @@ private static org.python.Object invokeComparison(org.python.Object x, org.pytho return resolveComparison(res, methodName); } + if (x instanceof org.python.types.Int && y instanceof org.python.types.Int) { + Long x_long = Long.valueOf(((org.python.types.Int) x).value); + Long y_long = Long.valueOf(((org.python.types.Int) y).value); + int res = x_long.compareTo(y_long); + return resolveComparison(res, methodName); + } + org.python.Object comparator = x.__getattribute_null(methodName); if (comparator == null || !(comparator instanceof org.python.types.Method)) { return org.python.types.NotImplementedType.NOT_IMPLEMENTED; From eca199eb4bf78b6b4534d5e82d2590131e579c2e Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Thu, 26 Jul 2018 11:50:24 +0200 Subject: [PATCH 03/11] split out each comparison case --- python/common/org/Python.java | 10 +- python/common/org/python/types/List.java | 44 ++- python/common/org/python/types/Object.java | 357 ++++++++++++++++----- python/common/org/python/types/Super.java | 2 +- python/common/org/python/types/Tuple.java | 28 +- voc/python/ast.py | 124 +++---- 6 files changed, 382 insertions(+), 183 deletions(-) diff --git a/python/common/org/Python.java b/python/common/org/Python.java index 472178dc20..500976c880 100644 --- a/python/common/org/Python.java +++ b/python/common/org/Python.java @@ -1066,11 +1066,7 @@ public static org.python.Object max(org.python.types.Tuple args, org.python.Obje } private static boolean compareKeys(org.python.Object first, org.python.Object second) { - return org.python.types.Object.__cmp__( - first, - second, - org.python.types.Object.CMP_OP.GT - ).toBoolean(); + return org.python.types.Object.__gt__(first, second).toBoolean(); } @org.python.Method( @@ -1584,11 +1580,11 @@ public __SortedObjectComparator(boolean reverse) { public int compare(org.python.Object o1, org.python.Object o2) { o1 = applyKey(o1, key); o2 = applyKey(o2, key); - org.python.Object result = org.python.types.Object.__cmp_bool__(o1, o2, org.python.types.Object.CMP_OP.LT); + org.python.Object result = org.python.types.Object.__lt__(o1, o2); if (result.toBoolean()) { return reverse ? 1 : -1; } - result = org.python.types.Object.__cmp_bool__(o2, o1, org.python.types.Object.CMP_OP.LT); + result = org.python.types.Object.__lt__(o2, o1); if (result.toBoolean()) { return reverse ? -1 : 1; } diff --git a/python/common/org/python/types/List.java b/python/common/org/python/types/List.java index 094fdd83bb..8d854ff6f7 100644 --- a/python/common/org/python/types/List.java +++ b/python/common/org/python/types/List.java @@ -198,8 +198,8 @@ public org.python.Object __lt__(org.python.Object other) { // check how many items are identical on the lists int i = 0; for (i = 0; i < count; i++) { - org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_bool__( - this.value.get(i), otherList.value.get(i), org.python.types.Object.CMP_OP.EQ); + org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_eq__( + this.value.get(i), otherList.value.get(i)); if (!result.value) { break; } @@ -207,8 +207,7 @@ public org.python.Object __lt__(org.python.Object other) { // not all items were identical, result is that of the first non-identical item if (i < count) { - return org.python.types.Object.__cmp_bool__(this.value.get(i), otherList.value.get(i), - org.python.types.Object.CMP_OP.LT); + return org.python.types.Object.__lt__(this.value.get(i), otherList.value.get(i)); } // all items were identical, break tie by size @@ -232,8 +231,8 @@ public org.python.Object __le__(org.python.Object other) { // check how many items are identical on the lists int i = 0; for (i = 0; i < count; i++) { - org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_bool__( - this.value.get(i), otherList.value.get(i), org.python.types.Object.CMP_OP.EQ); + org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_eq__( + this.value.get(i), otherList.value.get(i)); if (!result.value) { break; } @@ -241,8 +240,7 @@ public org.python.Object __le__(org.python.Object other) { // not all items were identical, result is that of the first non-identical item if (i < count) { - return org.python.types.Object.__cmp_bool__(this.value.get(i), otherList.value.get(i), - org.python.types.Object.CMP_OP.LE); + return org.python.types.Object.__le__(this.value.get(i), otherList.value.get(i)); } // all items were identical, break tie by size @@ -278,8 +276,8 @@ public org.python.Object __gt__(org.python.Object other) { // check how many items are identical on the lists int i = 0; for (i = 0; i < count; i++) { - org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_bool__( - this.value.get(i), otherList.value.get(i), org.python.types.Object.CMP_OP.EQ); + org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_eq__( + this.value.get(i), otherList.value.get(i)); if (!result.value) { break; } @@ -287,8 +285,7 @@ public org.python.Object __gt__(org.python.Object other) { // not all items were identical, result is that of the first non-identical item if (i < count) { - return org.python.types.Object.__cmp_bool__(this.value.get(i), otherList.value.get(i), - org.python.types.Object.CMP_OP.GT); + return org.python.types.Object.__gt__(this.value.get(i), otherList.value.get(i)); } // all items were identical, break tie by size @@ -312,8 +309,8 @@ public org.python.Object __ge__(org.python.Object other) { // check how many items are identical on the lists int i = 0; for (i = 0; i < count; i++) { - org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_bool__( - this.value.get(i), otherList.value.get(i), org.python.types.Object.CMP_OP.EQ); + org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_eq__( + this.value.get(i), otherList.value.get(i)); if (!result.value) { break; } @@ -321,8 +318,7 @@ public org.python.Object __ge__(org.python.Object other) { // not all items were identical, result is that of the first non-identical item if (i < count) { - return org.python.types.Object.__cmp_bool__(this.value.get(i), otherList.value.get(i), - org.python.types.Object.CMP_OP.GE); + return org.python.types.Object.__ge__(this.value.get(i), otherList.value.get(i)); } // all items were identical, break tie by size @@ -553,8 +549,8 @@ public org.python.Object __reversed__() { public org.python.Object __contains__(org.python.Object item) { boolean found = false; for (int i = 0; i < this.value.size(); i++) { - if (((org.python.types.Bool) org.python.types.Object.__cmp_bool__( - item, this.value.get(i), org.python.types.Object.CMP_OP.EQ)).value) { + if (((org.python.types.Bool) org.python.types.Object.__cmp_eq__( + item, this.value.get(i))).value) { found = true; break; } @@ -664,8 +660,8 @@ public org.python.Object copy() { public org.python.Object count(org.python.Object other) { int count = 0; for (int i = 0; i < this.value.size(); i++) { - if (((org.python.types.Bool) org.python.types.Object.__cmp_bool__( - other, this.value.get(i), org.python.types.Object.CMP_OP.EQ)).value) { + if (((org.python.types.Bool) org.python.types.Object.__cmp_eq__( + other, this.value.get(i))).value) { count++; } } @@ -763,8 +759,8 @@ public org.python.Object index(org.python.Object item, org.python.Object start, } for (int i = iStart; i < Math.min(iEnd, this.value.size()); i++) { - if (((org.python.types.Bool) org.python.types.Object.__cmp_bool__( - item, this.value.get(i), org.python.types.Object.CMP_OP.EQ)).value) { + if (((org.python.types.Bool) org.python.types.Object.__cmp_eq__( + item, this.value.get(i))).value) { return org.python.types.Int.getInt(i); } } @@ -818,8 +814,8 @@ public org.python.Object pop(org.python.Object item) { ) public org.python.Object remove(org.python.Object item) { for (int i = 0; i < this.value.size(); i++) { - if (((org.python.types.Bool) org.python.types.Object.__cmp_bool__( - item, this.value.get(i), org.python.types.Object.CMP_OP.EQ)).value) { + if (((org.python.types.Bool) org.python.types.Object.__cmp_eq__( + item, this.value.get(i))).value) { this.value.remove(i); return org.python.types.NoneType.NONE; } diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index 3d2c451c80..60c0979cd8 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -105,7 +105,7 @@ public Object(org.python.Object[] args, java.util.Map=", "__ge__", "__le__"), - GT(">", "__gt__", "__lt__"), - EQ("==", "__eq__", "__eq__"), - NE("!=", "__ne__", "__ne__"), - LE("<=", "__le__", "__ge__"), - LT("<", "__lt__", "__gt__"); + /* This method is used from standard library container datatypes */ // FIXME provide more useful comment? + public static org.python.Object __cmp_eq__(org.python.Object v, org.python.Object w) { + // identity implies equality + if (v == w) { + return org.python.types.Bool.TRUE; + } + org.python.Object result = __eq__(v, w); + return (result instanceof org.python.types.Bool) ? result : result.__bool__(); + } - public final String oper; - public final String operMethod; - public final String reflOperMethod; - CMP_OP(java.lang.String oper, java.lang.String operMethod, java.lang.String reflOperMethod) { - this.oper = oper; - this.operMethod = operMethod; - this.reflOperMethod = reflOperMethod; + /* This method is used from standard library container datatypes */ + public static org.python.Object __cmp_ne__(org.python.Object v, org.python.Object w) { + // identity implies equality + if (v != w) { + return org.python.types.Bool.TRUE; } + org.python.Object result = __ne__(v, w); + return (result instanceof org.python.types.Bool) ? result : result.__bool__(); } - /* This method is used from standard library datatypes, etc */ - public static org.python.Object __cmp__(org.python.Object v, org.python.Object w, - org.python.types.Object.CMP_OP op) { - return __cmp__(v, w, op.oper, op.operMethod, op.reflOperMethod); + public static org.python.Object __lt__(org.python.Object v, org.python.Object w) { + org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; + boolean reflectedChecked = v.type() != w.type() + && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + + // Reflective case + if (reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__gt__(v); + } else { + result = invokeComparison(w, v, "__gt__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + + // Normal case + if (v instanceof org.python.types.Str) { // TODO all builtin types + result = v.__lt__(w); + } else { + result = invokeComparison(v, w, "__lt__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + + // Error case + if (org.Python.VERSION < 0x03060000) { + throw new org.python.exceptions.TypeError(String.format( + "unorderable types: %s() %s %s()", v.typeName(), "<", w.typeName())); + } else { + throw new org.python.exceptions.TypeError(String.format( + "'%s' not supported between instances of '%s' and '%s'", "<", v.typeName(), w.typeName())); + } } - /* This method is used from standard library container datatypes */ - public static org.python.Object __cmp_bool__(org.python.Object v, org.python.Object w, - org.python.types.Object.CMP_OP op) { - // identity implies equality - if (v == w) { - if (op == org.python.types.Object.CMP_OP.EQ) { - return org.python.types.Bool.TRUE; - } else if (op == org.python.types.Object.CMP_OP.NE) { - return org.python.types.Bool.FALSE; + public static org.python.Object __le__(org.python.Object v, org.python.Object w) { + org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; + boolean reflectedChecked = v.type() != w.type() + && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + + // Reflective case + if (reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__ge__(v); + } else { + result = invokeComparison(w, v, "__ge__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; } } - org.python.Object result = __cmp__(v, w, op.oper, op.operMethod, op.reflOperMethod); - if (result instanceof org.python.types.Bool) { + + // Normal case + if (v instanceof org.python.types.Str) { // TODO all builtin types + result = v.__le__(w); + } else { + result = invokeComparison(v, w, "__le__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { return result; + } + + // Error case + if (org.Python.VERSION < 0x03060000) { + throw new org.python.exceptions.TypeError(String.format( + "unorderable types: %s() %s %s()", v.typeName(), "<=", w.typeName())); + } else { + throw new org.python.exceptions.TypeError(String.format( + "'%s' not supported between instances of '%s' and '%s'", "<=", v.typeName(), w.typeName())); + } + } + + public static org.python.Object __eq__(org.python.Object v, org.python.Object w) { + org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; + boolean reflectedChecked = v.type() != w.type() + && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + + // Reflective case + if (reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__eq__(v); + } else { + result = invokeComparison(w, v, "__eq__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + + // Normal case + if (v instanceof org.python.types.Str) { // TODO all builtin types + result = v.__eq__(w); + } else { + result = invokeComparison(v, w, "__eq__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + + return org.python.types.Bool.getBool(v == w); + } + + public static org.python.Object __ne__(org.python.Object v, org.python.Object w) { + org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; + boolean reflectedChecked = v.type() != w.type() + && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + + // Reflective case + if (reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__ne__(v); + } else { + result = invokeComparison(w, v, "__ne__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + + // Normal case + if (v instanceof org.python.types.Str) { // TODO all builtin types + result = v.__ne__(w); } else { - return result.__bool__(); + result = invokeComparison(v, w, "__ne__"); } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + + return org.python.types.Bool.getBool(v != w); } - /* This method is invoked from the AST for Compare nodes */ - public static org.python.Object __cmp__(org.python.Object v, org.python.Object w, java.lang.String oper, - java.lang.String operMethod, java.lang.String reflOperMethod) { + public static org.python.Object __gt__(org.python.Object v, org.python.Object w) { org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; boolean reflectedChecked = v.type() != w.type() && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + // Reflective case if (reflectedChecked) { - result = invokeComparison(w, v, reflOperMethod); + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__lt__(v); + } else { + result = invokeComparison(w, v, "__lt__"); + } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } - result = invokeComparison(v, w, operMethod); + // Normal case + if (v instanceof org.python.types.Str) { // TODO all builtin types + result = v.__gt__(w); + } else { + result = invokeComparison(v, w, "__gt__"); + } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { return result; } - if (!reflectedChecked) { - result = invokeComparison(w, v, reflOperMethod); + // Error case + if (org.Python.VERSION < 0x03060000) { + throw new org.python.exceptions.TypeError(String.format( + "unorderable types: %s() %s %s()", v.typeName(), ">", w.typeName())); + } else { + throw new org.python.exceptions.TypeError(String.format( + "'%s' not supported between instances of '%s' and '%s'", ">", v.typeName(), w.typeName())); + } + } + + public static org.python.Object __ge__(org.python.Object v, org.python.Object w) { + org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; + boolean reflectedChecked = v.type() != w.type() + && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + + // Reflective case + if (reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__le__(v); + } else { + result = invokeComparison(w, v, "__le__"); + } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } - if (oper.equals("==")) { - return org.python.types.Bool.getBool(v == w); - } else if (oper.equals("!=")) { - return org.python.types.Bool.getBool(v != w); + // Normal case + if (v instanceof org.python.types.Str) { // TODO all builtin types + result = v.__ge__(w); + } else { + result = invokeComparison(v, w, "__ge__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; } + // Error case if (org.Python.VERSION < 0x03060000) { throw new org.python.exceptions.TypeError(String.format( - "unorderable types: %s() %s %s()", v.typeName(), oper, w.typeName())); + "unorderable types: %s() %s %s()", v.typeName(), ">=", w.typeName())); } else { throw new org.python.exceptions.TypeError(String.format( - "'%s' not supported between instances of '%s' and '%s'", oper, v.typeName(), w.typeName())); + "'%s' not supported between instances of '%s' and '%s'", ">=", v.typeName(), w.typeName())); } } - private static org.python.Object resolveComparison(int cmpResult, String methodName) { - switch(methodName) { - case "__eq__": - return org.python.types.Bool.getBool(cmpResult == 0); - case "__lt__": - return org.python.types.Bool.getBool(cmpResult < 0); - case "__le__": - return org.python.types.Bool.getBool(cmpResult <= 0); - case "__gt__": - return org.python.types.Bool.getBool(cmpResult > 0); - case "__ge__": - return org.python.types.Bool.getBool(cmpResult >= 0); - case "__ne__": - return org.python.types.Bool.getBool(cmpResult != 0); - default: - return org.python.types.NotImplementedType.NOT_IMPLEMENTED; + // FIXME how can __contains__/in be reflective? + public static org.python.Object __contains__(org.python.Object v, org.python.Object w) { + org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; + boolean reflectedChecked = v.type() != w.type() + && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + + // Reflective case + if (reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__contains__(v); + } else { + result = invokeComparison(w, v, "__contains__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + + // Normal case + if (v instanceof org.python.types.Str) { // TODO all builtin types + result = v.__contains__(w); + } else { + result = invokeComparison(v, w, "__contains__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + + // Error case + if (org.Python.VERSION < 0x03060000) { + throw new org.python.exceptions.TypeError(String.format( + "unorderable types: %s() %s %s()", v.typeName(), "in", w.typeName())); + } else { + throw new org.python.exceptions.TypeError(String.format( + "'%s' not supported between instances of '%s' and '%s'", "in", v.typeName(), w.typeName())); } } - private static org.python.Object invokeComparison(org.python.Object x, org.python.Object y, String methodName) { - if (methodName == null) { - return org.python.types.NotImplementedType.NOT_IMPLEMENTED; + public static org.python.Object __not_contains__(org.python.Object v, org.python.Object w) { + org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; + boolean reflectedChecked = v.type() != w.type() + && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + + // Reflective case + if (reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__not_contains__(v); + } else { + result = invokeComparison(w, v, "__not_contains__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } } - if (x instanceof org.python.types.Str && y instanceof org.python.types.Str) { - int res = ((org.python.types.Str) x).value.compareTo(((org.python.types.Str) y).value); - return resolveComparison(res, methodName); + // Normal case + if (v instanceof org.python.types.Str) { // TODO all builtin types + result = v.__not_contains__(w); + } else { + result = invokeComparison(v, w, "__not_contains__"); } - if (x instanceof org.python.types.Int && y instanceof org.python.types.Int) { - Long x_long = Long.valueOf(((org.python.types.Int) x).value); - Long y_long = Long.valueOf(((org.python.types.Int) y).value); - int res = x_long.compareTo(y_long); - return resolveComparison(res, methodName); + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + + // Error case + if (org.Python.VERSION < 0x03060000) { + throw new org.python.exceptions.TypeError(String.format( + "unorderable types: %s() %s %s()", v.typeName(), "not in", w.typeName())); + } else { + throw new org.python.exceptions.TypeError(String.format( + "'%s' not supported between instances of '%s' and '%s'", "not in", v.typeName(), w.typeName())); + } + } + + private static org.python.Object invokeComparison(org.python.Object x, org.python.Object y, String methodName) { + if (methodName == null) { + return org.python.types.NotImplementedType.NOT_IMPLEMENTED; } org.python.Object comparator = x.__getattribute_null(methodName); @@ -1152,7 +1350,6 @@ private static org.python.Object invokeComparison(org.python.Object x, org.pytho org.python.Object[] args = new org.python.Object[1]; args[0] = y; return (org.python.Object) ((org.python.types.Method) comparator).invoke(args, null); - } public static boolean isSequence(org.python.Object other) { diff --git a/python/common/org/python/types/Super.java b/python/common/org/python/types/Super.java index f1b6eba02f..ff0d6a777d 100644 --- a/python/common/org/python/types/Super.java +++ b/python/common/org/python/types/Super.java @@ -60,7 +60,7 @@ public Super(org.python.Object klass, org.python.Object instance) { */ public boolean equals(java.lang.Object other) { if (other instanceof org.python.Object) { - org.python.Object result = org.python.types.Object.__cmp_bool__(this, (org.python.Object) other, org.python.types.Object.CMP_OP.EQ); + org.python.Object result = org.python.types.Object.__eq__(this, (org.python.Object) other); return ((org.python.types.Bool) result).value; } else { throw new org.python.exceptions.RuntimeError("Can't compare a Python object with non-Python object."); diff --git a/python/common/org/python/types/Tuple.java b/python/common/org/python/types/Tuple.java index 7f2c5652fc..ac97f061ef 100644 --- a/python/common/org/python/types/Tuple.java +++ b/python/common/org/python/types/Tuple.java @@ -119,8 +119,8 @@ public org.python.Object __lt__(org.python.Object other) { // check how many items are identical on the lists int i = 0; for (i = 0; i < count; i++) { - org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_bool__( - this.value.get(i), otherTuple.value.get(i), org.python.types.Object.CMP_OP.EQ); + org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_eq__( + this.value.get(i), otherTuple.value.get(i)); if (!result.value) { break; } @@ -128,8 +128,7 @@ public org.python.Object __lt__(org.python.Object other) { // not all items were identical, result is that of the first non-identical item if (i < count) { - return org.python.types.Object.__cmp_bool__(this.value.get(i), otherTuple.value.get(i), - org.python.types.Object.CMP_OP.LT); + return org.python.types.Object.__lt__(this.value.get(i), otherTuple.value.get(i)); } // all items were identical, break tie by size @@ -153,8 +152,8 @@ public org.python.Object __le__(org.python.Object other) { // check how many items are identical on the lists int i = 0; for (i = 0; i < count; i++) { - org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_bool__( - this.value.get(i), otherTuple.value.get(i), org.python.types.Object.CMP_OP.EQ); + org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_eq__( + this.value.get(i), otherTuple.value.get(i)); if (!result.value) { break; } @@ -162,8 +161,7 @@ public org.python.Object __le__(org.python.Object other) { // not all items were identical, result is that of the first non-identical item if (i < count) { - return org.python.types.Object.__cmp_bool__(this.value.get(i), otherTuple.value.get(i), - org.python.types.Object.CMP_OP.LE); + return org.python.types.Object.__le__(this.value.get(i), otherTuple.value.get(i)); } // all items were identical, break tie by size @@ -199,8 +197,8 @@ public org.python.Object __gt__(org.python.Object other) { // check how many items are identical on the lists int i = 0; for (i = 0; i < count; i++) { - org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_bool__( - this.value.get(i), otherTuple.value.get(i), org.python.types.Object.CMP_OP.EQ); + org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_eq__( + this.value.get(i), otherTuple.value.get(i)); if (!result.value) { break; } @@ -208,8 +206,7 @@ public org.python.Object __gt__(org.python.Object other) { // not all items were identical, result is that of the first non-identical item if (i < count) { - return org.python.types.Object.__cmp_bool__(this.value.get(i), otherTuple.value.get(i), - org.python.types.Object.CMP_OP.GT); + return org.python.types.Object.__gt__(this.value.get(i), otherTuple.value.get(i)); } // all items were identical, break tie by size @@ -233,8 +230,8 @@ public org.python.Object __ge__(org.python.Object other) { // check how many items are identical on the lists int i = 0; for (i = 0; i < count; i++) { - org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_bool__( - this.value.get(i), otherTuple.value.get(i), org.python.types.Object.CMP_OP.EQ); + org.python.types.Bool result = (org.python.types.Bool) org.python.types.Object.__cmp_eq__( + this.value.get(i), otherTuple.value.get(i)); if (!result.value) { break; } @@ -242,8 +239,7 @@ public org.python.Object __ge__(org.python.Object other) { // not all items were identical, result is that of the first non-identical item if (i < count) { - return org.python.types.Object.__cmp_bool__(this.value.get(i), otherTuple.value.get(i), - org.python.types.Object.CMP_OP.GE); + return org.python.types.Object.__ge__(this.value.get(i), otherTuple.value.get(i)); } // all items were identical, break tie by size diff --git a/voc/python/ast.py b/voc/python/ast.py index ca4f3f9cfb..3fb019cc22 100644 --- a/voc/python/ast.py +++ b/voc/python/ast.py @@ -1884,65 +1884,79 @@ def compare_to(arg): ) else: - if isinstance(arg, (ast.In, ast.NotIn)): + if isinstance(arg, (ast.Eq, ast.Is)): self.context.add_opcodes( - JavaOpcodes.SWAP() + JavaOpcodes.INVOKESTATIC( + 'org/python/types/Object', + '__eq__', + args=['Lorg/python/Object;', 'Lorg/python/Object;'], + returns='Lorg/python/Object;'), ) - oper = { - ast.Eq: '__eq__', - ast.Gt: '__gt__', - ast.GtE: '__ge__', - ast.Lt: '__lt__', - ast.LtE: '__le__', - ast.In: '__contains__', - ast.Is: '__eq__', - ast.IsNot: '__ne__', - ast.NotEq: '__ne__', - ast.NotIn: '__not_contains__', - }[type(arg)] - oper_symbol = { - ast.Eq: '==', - ast.Gt: '>', - ast.GtE: '>=', - ast.Lt: '<', - ast.LtE: '<=', - ast.In: 'in', - ast.Is: 'is', - ast.IsNot: 'is not', - ast.NotEq: '!=', - ast.NotIn: 'not in', - }[type(arg)] - reflect_oper = { - ast.Eq: '__eq__', - ast.Gt: '__lt__', - ast.GtE: '__le__', - ast.Lt: '__gt__', - ast.LtE: '__ge__', - ast.In: '__contains__', - ast.Is: '__eq__', - ast.IsNot: '__ne__', - ast.NotEq: '__ne__', - ast.NotIn: '__not_contains__', - }[type(arg)] + if isinstance(arg, (ast.NotEq, ast.IsNot)): + self.context.add_opcodes( + JavaOpcodes.INVOKESTATIC( + 'org/python/types/Object', + '__eq__', + args=['Lorg/python/Object;', 'Lorg/python/Object;'], + returns='Lorg/python/Object;'), + ) - self.context.add_opcodes( - JavaOpcodes.LDC_W(oper_symbol), - JavaOpcodes.LDC_W(oper), - JavaOpcodes.LDC_W(reflect_oper), - JavaOpcodes.INVOKESTATIC( - 'org/python/types/Object', - '__cmp__', - args=[ - 'Lorg/python/Object;', - 'Lorg/python/Object;', - 'Ljava/lang/String;', - 'Ljava/lang/String;', - 'Ljava/lang/String;', - ], - returns='Lorg/python/Object;', - ), - ) + if isinstance(arg, ast.Lt): + self.context.add_opcodes( + JavaOpcodes.INVOKESTATIC( + 'org/python/types/Object', + '__lt__', + args=['Lorg/python/Object;', 'Lorg/python/Object;'], + returns='Lorg/python/Object;'), + ) + + if isinstance(arg, ast.LtE): + self.context.add_opcodes( + JavaOpcodes.INVOKESTATIC( + 'org/python/types/Object', + '__le__', + args=['Lorg/python/Object;', 'Lorg/python/Object;'], + returns='Lorg/python/Object;'), + ) + + if isinstance(arg, ast.Gt): + self.context.add_opcodes( + JavaOpcodes.INVOKESTATIC( + 'org/python/types/Object', + '__gt__', + args=['Lorg/python/Object;', 'Lorg/python/Object;'], + returns='Lorg/python/Object;'), + ) + + if isinstance(arg, ast.GtE): + self.context.add_opcodes( + JavaOpcodes.INVOKESTATIC( + 'org/python/types/Object', + '__ge__', + args=['Lorg/python/Object;', 'Lorg/python/Object;'], + returns='Lorg/python/Object;'), + ) + + if isinstance(arg, ast.In): + self.context.add_opcodes( + JavaOpcodes.SWAP(), + JavaOpcodes.INVOKESTATIC( + 'org/python/types/Object', + '__contains__', + args=['Lorg/python/Object;', 'Lorg/python/Object;'], + returns='Lorg/python/Object;'), + ) + + if isinstance(arg, ast.NotIn): + self.context.add_opcodes( + JavaOpcodes.SWAP(), + JavaOpcodes.INVOKESTATIC( + 'org/python/types/Object', + '__not_contains__', + args=['Lorg/python/Object;', 'Lorg/python/Object;'], + returns='Lorg/python/Object;'), + ) self.visit(node.left) left = node.left From 65ac0d0865f0bbf4be48b71d85aa1013a3228987 Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Thu, 26 Jul 2018 13:22:02 +0200 Subject: [PATCH 04/11] fix java style and add missing reflective checks --- python/common/org/python/types/Int.java | 1 + python/common/org/python/types/Object.java | 120 +++++++++++++++++++-- 2 files changed, 113 insertions(+), 8 deletions(-) diff --git a/python/common/org/python/types/Int.java b/python/common/org/python/types/Int.java index d13a19fca3..f43d3680ae 100644 --- a/python/common/org/python/types/Int.java +++ b/python/common/org/python/types/Int.java @@ -198,6 +198,7 @@ public org.python.Object __eq__(org.python.Object other) { } return org.python.types.Bool.FALSE; } + return org.python.types.NotImplementedType.NOT_IMPLEMENTED; } diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index 60c0979cd8..1d19347aea 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -1052,7 +1052,7 @@ public static org.python.Object __lt__(org.python.Object v, org.python.Object w) } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } @@ -1067,6 +1067,19 @@ public static org.python.Object __lt__(org.python.Object v, org.python.Object w) return result; } + // Now check reflection + if (!reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__gt__(v); + } else { + result = invokeComparison(w, v, "__gt__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + // Error case if (org.Python.VERSION < 0x03060000) { throw new org.python.exceptions.TypeError(String.format( @@ -1091,7 +1104,7 @@ public static org.python.Object __le__(org.python.Object v, org.python.Object w) } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } @@ -1102,6 +1115,19 @@ public static org.python.Object __le__(org.python.Object v, org.python.Object w) result = invokeComparison(v, w, "__le__"); } + // Now check reflection + if (!reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__ge__(v); + } else { + result = invokeComparison(w, v, "__ge__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { return result; } @@ -1130,7 +1156,7 @@ public static org.python.Object __eq__(org.python.Object v, org.python.Object w) } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } @@ -1145,6 +1171,19 @@ public static org.python.Object __eq__(org.python.Object v, org.python.Object w) return result; } + // Now check reflection + if (!reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__eq__(v); + } else { + result = invokeComparison(w, v, "__eq__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + return org.python.types.Bool.getBool(v == w); } @@ -1162,7 +1201,7 @@ public static org.python.Object __ne__(org.python.Object v, org.python.Object w) } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } @@ -1177,6 +1216,19 @@ public static org.python.Object __ne__(org.python.Object v, org.python.Object w) return result; } + // Now check reflection + if (!reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__ne__(v); + } else { + result = invokeComparison(w, v, "__ne__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + return org.python.types.Bool.getBool(v != w); } @@ -1194,7 +1246,7 @@ public static org.python.Object __gt__(org.python.Object v, org.python.Object w) } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } @@ -1209,6 +1261,19 @@ public static org.python.Object __gt__(org.python.Object v, org.python.Object w) return result; } + // Now check reflection + if (!reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__lt__(v); + } else { + result = invokeComparison(w, v, "__lt__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + // Error case if (org.Python.VERSION < 0x03060000) { throw new org.python.exceptions.TypeError(String.format( @@ -1233,7 +1298,7 @@ public static org.python.Object __ge__(org.python.Object v, org.python.Object w) } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } @@ -1248,6 +1313,19 @@ public static org.python.Object __ge__(org.python.Object v, org.python.Object w) return result; } + // Now check reflection + if (!reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__le__(v); + } else { + result = invokeComparison(w, v, "__le"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + // Error case if (org.Python.VERSION < 0x03060000) { throw new org.python.exceptions.TypeError(String.format( @@ -1273,7 +1351,7 @@ public static org.python.Object __contains__(org.python.Object v, org.python.Obj } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } @@ -1288,6 +1366,19 @@ public static org.python.Object __contains__(org.python.Object v, org.python.Obj return result; } + // Now check reflection + if (!reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__contains__(v); + } else { + result = invokeComparison(w, v, "__contains__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + // Error case if (org.Python.VERSION < 0x03060000) { throw new org.python.exceptions.TypeError(String.format( @@ -1312,7 +1403,7 @@ public static org.python.Object __not_contains__(org.python.Object v, org.python } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; + return result; } } @@ -1327,6 +1418,19 @@ public static org.python.Object __not_contains__(org.python.Object v, org.python return result; } + // Now check reflection + if (!reflectedChecked) { + if (w instanceof org.python.types.Str) { // TODO all builtin types + result = w.__not_contains__(v); + } else { + result = invokeComparison(w, v, "__not_contains__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } + } + // Error case if (org.Python.VERSION < 0x03060000) { throw new org.python.exceptions.TypeError(String.format( From 9a73a971eedfcfdbeeb4e47c87fa4d6e1df625be Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Thu, 26 Jul 2018 13:37:04 +0200 Subject: [PATCH 05/11] fix more java checkstyle issues --- python/common/org/python/types/Int.java | 1 - 1 file changed, 1 deletion(-) diff --git a/python/common/org/python/types/Int.java b/python/common/org/python/types/Int.java index f43d3680ae..d13a19fca3 100644 --- a/python/common/org/python/types/Int.java +++ b/python/common/org/python/types/Int.java @@ -198,7 +198,6 @@ public org.python.Object __eq__(org.python.Object other) { } return org.python.types.Bool.FALSE; } - return org.python.types.NotImplementedType.NOT_IMPLEMENTED; } From 160c266019e71d5df8854cd90b3e93ec4418cab2 Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Thu, 26 Jul 2018 14:39:30 +0200 Subject: [PATCH 06/11] fix typo and handle builtin types --- python/common/org/python/types/Object.java | 87 ++++++++++++++-------- voc/python/ast.py | 2 +- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index 1d19347aea..8cb86a15a2 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -1038,14 +1038,27 @@ public static org.python.Object __cmp_ne__(org.python.Object v, org.python.Objec return (result instanceof org.python.types.Bool) ? result : result.__bool__(); } + private static boolean isBuiltin(org.python.Object obj) { + return obj instanceof org.python.types.Int || obj instanceof org.python.types.Str || + obj instanceof org.python.types.Bool || obj instanceof org.python.types.Float || + obj instanceof org.python.types.List || obj instanceof org.python.types.Dict || + obj instanceof org.python.types.Tuple || obj instanceof org.python.types.Set || + obj instanceof org.python.types.Range || obj instanceof org.python.types.Slice || + obj instanceof org.python.types.Bytes || obj instanceof org.python.types.Complex || + obj instanceof org.python.types.ByteArray || obj instanceof org.python.types.FrozenSet || + obj instanceof org.python.types.MemoryView; + } + public static org.python.Object __lt__(org.python.Object v, org.python.Object w) { org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; boolean reflectedChecked = v.type() != w.type() && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + boolean v_builtin = isBuiltin(v); + boolean w_builtin = isBuiltin(w); // Reflective case if (reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__gt__(v); } else { result = invokeComparison(w, v, "__gt__"); @@ -1057,19 +1070,18 @@ public static org.python.Object __lt__(org.python.Object v, org.python.Object w) } // Normal case - if (v instanceof org.python.types.Str) { // TODO all builtin types + if (v_builtin) { result = v.__lt__(w); } else { result = invokeComparison(v, w, "__lt__"); } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { return result; } // Now check reflection if (!reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__gt__(v); } else { result = invokeComparison(w, v, "__gt__"); @@ -1095,9 +1107,13 @@ public static org.python.Object __le__(org.python.Object v, org.python.Object w) boolean reflectedChecked = v.type() != w.type() && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + boolean v_builtin = isBuiltin(v); + boolean w_builtin = isBuiltin(w); + + // Reflective case if (reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__ge__(v); } else { result = invokeComparison(w, v, "__ge__"); @@ -1109,15 +1125,18 @@ public static org.python.Object __le__(org.python.Object v, org.python.Object w) } // Normal case - if (v instanceof org.python.types.Str) { // TODO all builtin types + if (v_builtin) { result = v.__le__(w); } else { result = invokeComparison(v, w, "__le__"); } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } // Now check reflection if (!reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__ge__(v); } else { result = invokeComparison(w, v, "__ge__"); @@ -1128,10 +1147,6 @@ public static org.python.Object __le__(org.python.Object v, org.python.Object w) } } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } - // Error case if (org.Python.VERSION < 0x03060000) { throw new org.python.exceptions.TypeError(String.format( @@ -1147,9 +1162,12 @@ public static org.python.Object __eq__(org.python.Object v, org.python.Object w) boolean reflectedChecked = v.type() != w.type() && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + boolean v_builtin = isBuiltin(v); + boolean w_builtin = isBuiltin(w); + // Reflective case if (reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__eq__(v); } else { result = invokeComparison(w, v, "__eq__"); @@ -1161,19 +1179,18 @@ public static org.python.Object __eq__(org.python.Object v, org.python.Object w) } // Normal case - if (v instanceof org.python.types.Str) { // TODO all builtin types + if (v_builtin) { result = v.__eq__(w); } else { result = invokeComparison(v, w, "__eq__"); } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { return result; } // Now check reflection if (!reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__eq__(v); } else { result = invokeComparison(w, v, "__eq__"); @@ -1191,10 +1208,12 @@ public static org.python.Object __ne__(org.python.Object v, org.python.Object w) org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; boolean reflectedChecked = v.type() != w.type() && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + boolean v_builtin = isBuiltin(v); + boolean w_builtin = isBuiltin(w); // Reflective case if (reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__ne__(v); } else { result = invokeComparison(w, v, "__ne__"); @@ -1206,7 +1225,7 @@ public static org.python.Object __ne__(org.python.Object v, org.python.Object w) } // Normal case - if (v instanceof org.python.types.Str) { // TODO all builtin types + if (v_builtin) { result = v.__ne__(w); } else { result = invokeComparison(v, w, "__ne__"); @@ -1218,7 +1237,7 @@ public static org.python.Object __ne__(org.python.Object v, org.python.Object w) // Now check reflection if (!reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__ne__(v); } else { result = invokeComparison(w, v, "__ne__"); @@ -1236,10 +1255,12 @@ public static org.python.Object __gt__(org.python.Object v, org.python.Object w) org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; boolean reflectedChecked = v.type() != w.type() && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + boolean v_builtin = isBuiltin(v); + boolean w_builtin = isBuiltin(w); // Reflective case if (reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__lt__(v); } else { result = invokeComparison(w, v, "__lt__"); @@ -1251,7 +1272,7 @@ public static org.python.Object __gt__(org.python.Object v, org.python.Object w) } // Normal case - if (v instanceof org.python.types.Str) { // TODO all builtin types + if (v_builtin) { result = v.__gt__(w); } else { result = invokeComparison(v, w, "__gt__"); @@ -1263,7 +1284,7 @@ public static org.python.Object __gt__(org.python.Object v, org.python.Object w) // Now check reflection if (!reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__lt__(v); } else { result = invokeComparison(w, v, "__lt__"); @@ -1288,10 +1309,12 @@ public static org.python.Object __ge__(org.python.Object v, org.python.Object w) org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; boolean reflectedChecked = v.type() != w.type() && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + boolean v_builtin = isBuiltin(v); + boolean w_builtin = isBuiltin(w); // Reflective case if (reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__le__(v); } else { result = invokeComparison(w, v, "__le__"); @@ -1303,7 +1326,7 @@ public static org.python.Object __ge__(org.python.Object v, org.python.Object w) } // Normal case - if (v instanceof org.python.types.Str) { // TODO all builtin types + if (v_builtin) { result = v.__ge__(w); } else { result = invokeComparison(v, w, "__ge__"); @@ -1315,7 +1338,7 @@ public static org.python.Object __ge__(org.python.Object v, org.python.Object w) // Now check reflection if (!reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__le__(v); } else { result = invokeComparison(w, v, "__le"); @@ -1341,10 +1364,12 @@ public static org.python.Object __contains__(org.python.Object v, org.python.Obj org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; boolean reflectedChecked = v.type() != w.type() && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + boolean v_builtin = isBuiltin(v); + boolean w_builtin = isBuiltin(w); // Reflective case if (reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__contains__(v); } else { result = invokeComparison(w, v, "__contains__"); @@ -1356,7 +1381,7 @@ public static org.python.Object __contains__(org.python.Object v, org.python.Obj } // Normal case - if (v instanceof org.python.types.Str) { // TODO all builtin types + if (v_builtin) { result = v.__contains__(w); } else { result = invokeComparison(v, w, "__contains__"); @@ -1368,7 +1393,7 @@ public static org.python.Object __contains__(org.python.Object v, org.python.Obj // Now check reflection if (!reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__contains__(v); } else { result = invokeComparison(w, v, "__contains__"); @@ -1393,10 +1418,12 @@ public static org.python.Object __not_contains__(org.python.Object v, org.python org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; boolean reflectedChecked = v.type() != w.type() && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; + boolean v_builtin = isBuiltin(v); + boolean w_builtin = isBuiltin(w); // Reflective case if (reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__not_contains__(v); } else { result = invokeComparison(w, v, "__not_contains__"); @@ -1408,7 +1435,7 @@ public static org.python.Object __not_contains__(org.python.Object v, org.python } // Normal case - if (v instanceof org.python.types.Str) { // TODO all builtin types + if (v_builtin) { result = v.__not_contains__(w); } else { result = invokeComparison(v, w, "__not_contains__"); @@ -1420,7 +1447,7 @@ public static org.python.Object __not_contains__(org.python.Object v, org.python // Now check reflection if (!reflectedChecked) { - if (w instanceof org.python.types.Str) { // TODO all builtin types + if (w_builtin) { result = w.__not_contains__(v); } else { result = invokeComparison(w, v, "__not_contains__"); diff --git a/voc/python/ast.py b/voc/python/ast.py index 3fb019cc22..7bd5f1d9fe 100644 --- a/voc/python/ast.py +++ b/voc/python/ast.py @@ -1897,7 +1897,7 @@ def compare_to(arg): self.context.add_opcodes( JavaOpcodes.INVOKESTATIC( 'org/python/types/Object', - '__eq__', + '__ne__', args=['Lorg/python/Object;', 'Lorg/python/Object;'], returns='Lorg/python/Object;'), ) From 8c201263d96db0beb1a9dd96457b58d95d286cfa Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Thu, 26 Jul 2018 14:57:03 +0200 Subject: [PATCH 07/11] fix checkstyle and update benchmarking test --- python/common/org/python/types/Object.java | 2 +- tests/benchmarks.py | 50 +++++++++++----------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index 8cb86a15a2..9b11993df9 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -1043,7 +1043,7 @@ private static boolean isBuiltin(org.python.Object obj) { obj instanceof org.python.types.Bool || obj instanceof org.python.types.Float || obj instanceof org.python.types.List || obj instanceof org.python.types.Dict || obj instanceof org.python.types.Tuple || obj instanceof org.python.types.Set || - obj instanceof org.python.types.Range || obj instanceof org.python.types.Slice || + obj instanceof org.python.types.Range || obj instanceof org.python.types.Slice || obj instanceof org.python.types.Bytes || obj instanceof org.python.types.Complex || obj instanceof org.python.types.ByteArray || obj instanceof org.python.types.FrozenSet || obj instanceof org.python.types.MemoryView; diff --git a/tests/benchmarks.py b/tests/benchmarks.py index 5811cdd2b6..3c3032724b 100644 --- a/tests/benchmarks.py +++ b/tests/benchmarks.py @@ -138,37 +138,35 @@ def yarn(n): main(i) """), timed=True) -def test_str_comp(test_case): +def test_cmp(test_case): print("Running", "string comparison") test_case.runAsJava(adjust(""" + x = None s = "mary had a little lamb" t = "humpty dumpty sat on a wall" for i in range(1000): - for j in range(100): - print(s < t) - print(s <= t) - print(s == t) - print(s >= t) - print(s > t) - - print(s < t) - print(s <= t) - print(s == t) - print(s >= t) - print(s > t) - - print(s < t) - print(s <= t) - print(s == t) - print(s >= t) - print(s > t) - - print(s < t) - print(s <= t) - print(s == t) - print(s >= t) - print(s > t) + for j in range(1000): + x = s < t + x = s <= t + x = s == t + x = s != t + x = s > t + x = s >= t + + x = 3 < 5 + x = 3 <= 5 + x = 3 == 5 + x = 3 != 5 + x = 3 > 5 + x = 3 >= 5 + + x = 3 < True + x = 3.0 <= 5 + x = None == 5 + x = [3] != 5.0 + x = [3] > [5] + x = [3.0] > [5.0] """), timed=True) def main(): @@ -180,7 +178,7 @@ def main(): test_class_var_load(test_case) test_function_var_load(test_case) test_code(test_case) - test_str_comp(test_case) + test_cmp(test_case) if __name__== "__main__": main() From ccae387c1cc1f1953fc4df4f0dbff4793b2b6d5f Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Thu, 26 Jul 2018 15:33:32 +0200 Subject: [PATCH 08/11] fix indentation and rename test --- python/common/org/python/types/Object.java | 128 ++++++++++----------- tests/benchmarks.py | 2 +- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index 9b11993df9..fe74c475b0 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -1081,15 +1081,15 @@ public static org.python.Object __lt__(org.python.Object v, org.python.Object w) // Now check reflection if (!reflectedChecked) { - if (w_builtin) { - result = w.__gt__(v); - } else { - result = invokeComparison(w, v, "__gt__"); - } + if (w_builtin) { + result = w.__gt__(v); + } else { + result = invokeComparison(w, v, "__gt__"); + } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } } // Error case @@ -1136,15 +1136,15 @@ public static org.python.Object __le__(org.python.Object v, org.python.Object w) // Now check reflection if (!reflectedChecked) { - if (w_builtin) { - result = w.__ge__(v); - } else { - result = invokeComparison(w, v, "__ge__"); - } + if (w_builtin) { + result = w.__ge__(v); + } else { + result = invokeComparison(w, v, "__ge__"); + } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } } // Error case @@ -1190,15 +1190,15 @@ public static org.python.Object __eq__(org.python.Object v, org.python.Object w) // Now check reflection if (!reflectedChecked) { - if (w_builtin) { - result = w.__eq__(v); - } else { - result = invokeComparison(w, v, "__eq__"); - } + if (w_builtin) { + result = w.__eq__(v); + } else { + result = invokeComparison(w, v, "__eq__"); + } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } } return org.python.types.Bool.getBool(v == w); @@ -1237,15 +1237,15 @@ public static org.python.Object __ne__(org.python.Object v, org.python.Object w) // Now check reflection if (!reflectedChecked) { - if (w_builtin) { - result = w.__ne__(v); - } else { - result = invokeComparison(w, v, "__ne__"); - } + if (w_builtin) { + result = w.__ne__(v); + } else { + result = invokeComparison(w, v, "__ne__"); + } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } } return org.python.types.Bool.getBool(v != w); @@ -1284,15 +1284,15 @@ public static org.python.Object __gt__(org.python.Object v, org.python.Object w) // Now check reflection if (!reflectedChecked) { - if (w_builtin) { - result = w.__lt__(v); - } else { + if (w_builtin) { + result = w.__lt__(v); + } else { result = invokeComparison(w, v, "__lt__"); - } + } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } } // Error case @@ -1338,15 +1338,15 @@ public static org.python.Object __ge__(org.python.Object v, org.python.Object w) // Now check reflection if (!reflectedChecked) { - if (w_builtin) { - result = w.__le__(v); - } else { - result = invokeComparison(w, v, "__le"); - } + if (w_builtin) { + result = w.__le__(v); + } else { + result = invokeComparison(w, v, "__le"); + } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } } // Error case @@ -1393,15 +1393,15 @@ public static org.python.Object __contains__(org.python.Object v, org.python.Obj // Now check reflection if (!reflectedChecked) { - if (w_builtin) { - result = w.__contains__(v); - } else { - result = invokeComparison(w, v, "__contains__"); - } + if (w_builtin) { + result = w.__contains__(v); + } else { + result = invokeComparison(w, v, "__contains__"); + } - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } } // Error case @@ -1447,15 +1447,15 @@ public static org.python.Object __not_contains__(org.python.Object v, org.python // Now check reflection if (!reflectedChecked) { - if (w_builtin) { - result = w.__not_contains__(v); - } else { - result = invokeComparison(w, v, "__not_contains__"); - } - - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } + if (w_builtin) { + result = w.__not_contains__(v); + } else { + result = invokeComparison(w, v, "__not_contains__"); + } + + if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { + return result; + } } // Error case diff --git a/tests/benchmarks.py b/tests/benchmarks.py index 3c3032724b..1f1a63762c 100644 --- a/tests/benchmarks.py +++ b/tests/benchmarks.py @@ -139,7 +139,7 @@ def yarn(n): """), timed=True) def test_cmp(test_case): - print("Running", "string comparison") + print("Running", "test_cmp") test_case.runAsJava(adjust(""" x = None s = "mary had a little lamb" From 85262979020a797bdd1c7bcfd30d383242f7b2e5 Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Thu, 26 Jul 2018 15:36:54 +0200 Subject: [PATCH 09/11] really fix indentation --- python/common/org/python/types/Object.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index fe74c475b0..d09edd083c 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -1287,7 +1287,7 @@ public static org.python.Object __gt__(org.python.Object v, org.python.Object w) if (w_builtin) { result = w.__lt__(v); } else { - result = invokeComparison(w, v, "__lt__"); + result = invokeComparison(w, v, "__lt__"); } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { From 47312ab96de15a05629392f6fccfde7c82e5788d Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Fri, 27 Jul 2018 08:46:08 +0200 Subject: [PATCH 10/11] fix typo --- python/common/org/python/types/Object.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index d09edd083c..1a3b2cf53c 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -1341,7 +1341,7 @@ public static org.python.Object __ge__(org.python.Object v, org.python.Object w) if (w_builtin) { result = w.__le__(v); } else { - result = invokeComparison(w, v, "__le"); + result = invokeComparison(w, v, "__le__"); } if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { From 812dbcb56387f0b71b6aebe2964d8cad8f58ed35 Mon Sep 17 00:00:00 2001 From: Patience Shyu Date: Fri, 27 Jul 2018 09:40:20 +0200 Subject: [PATCH 11/11] clean up contains and not_contains --- python/common/org/python/types/Object.java | 65 +--------------------- 1 file changed, 2 insertions(+), 63 deletions(-) diff --git a/python/common/org/python/types/Object.java b/python/common/org/python/types/Object.java index 1a3b2cf53c..33eaf3477d 100644 --- a/python/common/org/python/types/Object.java +++ b/python/common/org/python/types/Object.java @@ -1359,28 +1359,10 @@ public static org.python.Object __ge__(org.python.Object v, org.python.Object w) } } - // FIXME how can __contains__/in be reflective? public static org.python.Object __contains__(org.python.Object v, org.python.Object w) { - org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; - boolean reflectedChecked = v.type() != w.type() - && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; boolean v_builtin = isBuiltin(v); - boolean w_builtin = isBuiltin(w); - - // Reflective case - if (reflectedChecked) { - if (w_builtin) { - result = w.__contains__(v); - } else { - result = invokeComparison(w, v, "__contains__"); - } + org.python.Object result = null; - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } - } - - // Normal case if (v_builtin) { result = v.__contains__(w); } else { @@ -1391,19 +1373,6 @@ public static org.python.Object __contains__(org.python.Object v, org.python.Obj return result; } - // Now check reflection - if (!reflectedChecked) { - if (w_builtin) { - result = w.__contains__(v); - } else { - result = invokeComparison(w, v, "__contains__"); - } - - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } - } - // Error case if (org.Python.VERSION < 0x03060000) { throw new org.python.exceptions.TypeError(String.format( @@ -1415,25 +1384,8 @@ public static org.python.Object __contains__(org.python.Object v, org.python.Obj } public static org.python.Object __not_contains__(org.python.Object v, org.python.Object w) { - org.python.Object result = org.python.types.NotImplementedType.NOT_IMPLEMENTED; - boolean reflectedChecked = v.type() != w.type() - && ((org.python.types.Bool) org.Python.isinstance(w, v.type())).value; boolean v_builtin = isBuiltin(v); - boolean w_builtin = isBuiltin(w); - - // Reflective case - if (reflectedChecked) { - if (w_builtin) { - result = w.__not_contains__(v); - } else { - result = invokeComparison(w, v, "__not_contains__"); - } - - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } - } - + org.python.Object result = null; // Normal case if (v_builtin) { result = v.__not_contains__(w); @@ -1445,19 +1397,6 @@ public static org.python.Object __not_contains__(org.python.Object v, org.python return result; } - // Now check reflection - if (!reflectedChecked) { - if (w_builtin) { - result = w.__not_contains__(v); - } else { - result = invokeComparison(w, v, "__not_contains__"); - } - - if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) { - return result; - } - } - // Error case if (org.Python.VERSION < 0x03060000) { throw new org.python.exceptions.TypeError(String.format(