diff --git a/README.rst b/README.rst index f7bd564205..38429b1b2f 100644 --- a/README.rst +++ b/README.rst @@ -44,8 +44,6 @@ What it does: It *doesn't* currently support: -* Dict and Set constants - * Importing and using native Java APIs * Extending native java classes and interfaces. diff --git a/python/common/org/Python.java b/python/common/org/Python.java index 8204ffa043..25c1a8abcb 100644 --- a/python/common/org/Python.java +++ b/python/common/org/Python.java @@ -1359,8 +1359,17 @@ public static org.python.types.Set set( if (args == null || args.size() == 0) { return new org.python.types.Set(); } else if (args.size() == 1) { - // return new org.python.types.Set(args.get(0)); - throw new org.python.exceptions.NotImplementedError("Builtin function 'set' with iterator not implemented"); + try { + // If the object is iterable, the underlying value should be + // a Java Collection. + return new org.python.types.Set( + new java.util.HashSet( + (java.util.Collection) args.get(0).toValue() + ) + ); + } catch (java.lang.ClassCastException e) { + throw new org.python.exceptions.TypeError("'" + org.Python.typeName(args.get(0).getClass()) + "' object is not iterable"); + } } else { throw new org.python.exceptions.TypeError("set() expected at most 1 arguments ( got " + args.size() + ")"); } diff --git a/python/common/org/python/types/Set.java b/python/common/org/python/types/Set.java index 463b6f3fcf..0928c8f980 100644 --- a/python/common/org/python/types/Set.java +++ b/python/common/org/python/types/Set.java @@ -40,6 +40,11 @@ public Set(java.util.Set set) { // } public org.python.types.Str __repr__() { + // Representation of an empty set is different + if (this.value.size() == 0) { + return new org.python.types.Str("set()"); + } + java.lang.StringBuilder buffer = new java.lang.StringBuilder("{"); boolean first = true; for (org.python.Object obj: this.value) { @@ -106,8 +111,12 @@ public org.python.Iterable __iter__() { throw new org.python.exceptions.NotImplementedError("set.__iter__() has not been implemented"); } - public org.python.Object __contains__() { - throw new org.python.exceptions.NotImplementedError("set.__contains__() has not been implemented"); + public org.python.Object __contains__(org.python.Object item) { + return new org.python.types.Bool(this.value.contains(item)); + } + + public org.python.Object __not_contains__(org.python.Object item) { + return new org.python.types.Bool(!this.value.contains(item)); } public org.python.Object __sub__() { @@ -163,11 +172,19 @@ public org.python.Object add(java.util.List args, java.util.M } public org.python.Object clear(java.util.List args, java.util.Map kwargs) { - throw new org.python.exceptions.NotImplementedError("set.clear() has not been implemented."); + if (kwargs != null || kwargs.size() > 0) { + throw new org.python.exceptions.TypeError("clear() takes no keyword arguments"); + } + if (args != null || args.size() > 0) { + throw new org.python.exceptions.TypeError("clear() takes no arguments (" + args.size() + " given)"); + } + this.clear(); + return org.python.types.NoneType.NONE; } public org.python.Object clear() { - throw new org.python.exceptions.NotImplementedError("set.clear() has not been implemented."); + this.value.clear(); + return org.python.types.NoneType.NONE; } public org.python.Object copy(java.util.List args, java.util.Map kwargs) { diff --git a/tests/datatypes/test_NoneType.py b/tests/datatypes/test_NoneType.py index 9624857df1..8f315771ec 100644 --- a/tests/datatypes/test_NoneType.py +++ b/tests/datatypes/test_NoneType.py @@ -185,19 +185,7 @@ class BinaryNoneTypeOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_gt_list', 'test_ge_list', - 'test_add_set', - 'test_subtract_set', - 'test_multiply_set', - 'test_floor_divide_set', - 'test_true_divide_set', - 'test_modulo_set', - 'test_power_set', 'test_subscr_set', - 'test_lshift_set', - 'test_rshift_set', - 'test_and_set', - 'test_xor_set', - 'test_or_set', 'test_lt_set', 'test_le_set', 'test_eq_set', diff --git a/tests/datatypes/test_dict.py b/tests/datatypes/test_dict.py index 31176fb3a1..67bfe8ce24 100644 --- a/tests/datatypes/test_dict.py +++ b/tests/datatypes/test_dict.py @@ -197,19 +197,7 @@ class BinaryDictOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_gt_list', 'test_ge_list', - 'test_add_set', - 'test_subtract_set', - 'test_multiply_set', - 'test_floor_divide_set', - 'test_true_divide_set', - 'test_modulo_set', - 'test_power_set', 'test_subscr_set', - 'test_lshift_set', - 'test_rshift_set', - 'test_and_set', - 'test_xor_set', - 'test_or_set', 'test_lt_set', 'test_le_set', 'test_eq_set', diff --git a/tests/datatypes/test_float.py b/tests/datatypes/test_float.py index 49de9f42ec..7a164d13f2 100644 --- a/tests/datatypes/test_float.py +++ b/tests/datatypes/test_float.py @@ -187,16 +187,9 @@ class BinaryFloatOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_subtract_set', 'test_multiply_set', 'test_floor_divide_set', - 'test_true_divide_set', 'test_modulo_set', 'test_power_set', 'test_subscr_set', - 'test_lshift_set', - 'test_rshift_set', - 'test_and_set', - 'test_xor_set', - 'test_or_set', - 'test_lt_set', 'test_le_set', 'test_eq_set', 'test_ne_set', diff --git a/tests/datatypes/test_int.py b/tests/datatypes/test_int.py index c46107501b..513be41f76 100644 --- a/tests/datatypes/test_int.py +++ b/tests/datatypes/test_int.py @@ -184,25 +184,14 @@ class BinaryIntOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_eq_list', 'test_ne_list', - 'test_add_set', - 'test_subtract_set', - 'test_multiply_set', - 'test_floor_divide_set', - 'test_true_divide_set', - 'test_modulo_set', - 'test_power_set', 'test_subscr_set', 'test_lshift_set', 'test_rshift_set', 'test_and_set', 'test_xor_set', 'test_or_set', - 'test_lt_set', - 'test_le_set', 'test_eq_set', 'test_ne_set', - 'test_gt_set', - 'test_ge_set', 'test_subtract_str', 'test_subscr_str', diff --git a/tests/datatypes/test_list.py b/tests/datatypes/test_list.py index 099e886022..71bf2430f3 100644 --- a/tests/datatypes/test_list.py +++ b/tests/datatypes/test_list.py @@ -209,18 +209,6 @@ class BinaryListOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_ge_list', 'test_add_set', - 'test_subtract_set', - 'test_multiply_set', - 'test_floor_divide_set', - 'test_true_divide_set', - 'test_modulo_set', - 'test_power_set', - 'test_subscr_set', - 'test_lshift_set', - 'test_rshift_set', - 'test_and_set', - 'test_xor_set', - 'test_or_set', 'test_lt_set', 'test_le_set', 'test_eq_set', diff --git a/tests/datatypes/test_set.py b/tests/datatypes/test_set.py index 73f4891694..298b07a5af 100644 --- a/tests/datatypes/test_set.py +++ b/tests/datatypes/test_set.py @@ -1,6 +1,39 @@ from .. utils import TranspileTestCase, UnaryOperationTestCase, BinaryOperationTestCase, InplaceOperationTestCase +class SetTests(TranspileTestCase): + def test_creation(self): + # Empty dict + self.assertCodeExecution(""" + x = set() + print(x) + """) + + # Set constant + self.assertCodeExecution(""" + x = {'a'} + print(x) + """) + + self.assertCodeExecution(""" + x = set(['a']) + print(x) + """) + + def test_getitem(self): + # Simple existent key + self.assertCodeExecution(""" + x = {'a', 'b'} + print('a' in x) + """) + + # Simple non-existent key + self.assertCodeExecution(""" + x = {'a', 'b'} + print('c' in x) + """) + + class UnarySetOperationTests(UnaryOperationTestCase, TranspileTestCase): values = ["set()", "{1, 'value', 1.2345}"] @@ -16,19 +49,7 @@ class BinarySetOperationTests(BinaryOperationTestCase, TranspileTestCase): values = ["set()", "{1, 'value', 1.2345}"] not_implemented = [ - 'test_add_bool', - 'test_subtract_bool', - 'test_multiply_bool', - 'test_floor_divide_bool', - 'test_true_divide_bool', - 'test_modulo_bool', - 'test_power_bool', 'test_subscr_bool', - 'test_lshift_bool', - 'test_rshift_bool', - 'test_and_bool', - 'test_xor_bool', - 'test_or_bool', 'test_lt_bool', 'test_le_bool', 'test_eq_bool', @@ -136,19 +157,7 @@ class BinarySetOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_gt_dict', 'test_ge_dict', - 'test_add_float', - 'test_subtract_float', - 'test_multiply_float', - 'test_floor_divide_float', - 'test_true_divide_float', - 'test_modulo_float', - 'test_power_float', 'test_subscr_float', - 'test_lshift_float', - 'test_rshift_float', - 'test_and_float', - 'test_xor_float', - 'test_or_float', 'test_lt_float', 'test_le_float', 'test_eq_float', @@ -176,19 +185,7 @@ class BinarySetOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_gt_frozenset', 'test_ge_frozenset', - 'test_add_int', - 'test_subtract_int', - 'test_multiply_int', - 'test_floor_divide_int', - 'test_true_divide_int', - 'test_modulo_int', - 'test_power_int', 'test_subscr_int', - 'test_lshift_int', - 'test_rshift_int', - 'test_and_int', - 'test_xor_int', - 'test_or_int', 'test_lt_int', 'test_le_int', 'test_eq_int', @@ -196,19 +193,8 @@ class BinarySetOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_gt_int', 'test_ge_int', - 'test_add_list', - 'test_subtract_list', 'test_multiply_list', - 'test_floor_divide_list', - 'test_true_divide_list', - 'test_modulo_list', - 'test_power_list', 'test_subscr_list', - 'test_lshift_list', - 'test_rshift_list', - 'test_and_list', - 'test_xor_list', - 'test_or_list', 'test_lt_list', 'test_le_list', 'test_eq_list', @@ -216,16 +202,8 @@ class BinarySetOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_gt_list', 'test_ge_list', - 'test_add_set', 'test_subtract_set', - 'test_multiply_set', - 'test_floor_divide_set', - 'test_true_divide_set', - 'test_modulo_set', - 'test_power_set', 'test_subscr_set', - 'test_lshift_set', - 'test_rshift_set', 'test_and_set', 'test_xor_set', 'test_or_set', @@ -236,19 +214,8 @@ class BinarySetOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_gt_set', 'test_ge_set', - 'test_add_str', - 'test_subtract_str', 'test_multiply_str', - 'test_floor_divide_str', - 'test_true_divide_str', - 'test_modulo_str', - 'test_power_str', 'test_subscr_str', - 'test_lshift_str', - 'test_rshift_str', - 'test_and_str', - 'test_xor_str', - 'test_or_str', 'test_lt_str', 'test_le_str', 'test_eq_str', @@ -256,19 +223,8 @@ class BinarySetOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_gt_str', 'test_ge_str', - 'test_add_tuple', - 'test_subtract_tuple', 'test_multiply_tuple', - 'test_floor_divide_tuple', - 'test_true_divide_tuple', - 'test_modulo_tuple', - 'test_power_tuple', 'test_subscr_tuple', - 'test_lshift_tuple', - 'test_rshift_tuple', - 'test_and_tuple', - 'test_xor_tuple', - 'test_or_tuple', 'test_lt_tuple', 'test_le_tuple', 'test_eq_tuple', @@ -282,7 +238,6 @@ class InplaceSetOperationTests(InplaceOperationTestCase, TranspileTestCase): values = ["set()", "{1, 'value', 1.2345}"] not_implemented = [ - 'test_add_bool', 'test_subtract_bool', 'test_multiply_bool', 'test_floor_divide_bool', @@ -308,7 +263,6 @@ class InplaceSetOperationTests(InplaceOperationTestCase, TranspileTestCase): 'test_xor_bytearray', 'test_or_bytearray', - 'test_add_bytes', 'test_subtract_bytes', 'test_multiply_bytes', 'test_floor_divide_bytes', @@ -347,7 +301,6 @@ class InplaceSetOperationTests(InplaceOperationTestCase, TranspileTestCase): 'test_xor_complex', 'test_or_complex', - 'test_add_dict', 'test_subtract_dict', 'test_multiply_dict', 'test_floor_divide_dict', @@ -360,7 +313,6 @@ class InplaceSetOperationTests(InplaceOperationTestCase, TranspileTestCase): 'test_xor_dict', 'test_or_dict', - 'test_add_float', 'test_subtract_float', 'test_multiply_float', 'test_floor_divide_float', @@ -386,7 +338,6 @@ class InplaceSetOperationTests(InplaceOperationTestCase, TranspileTestCase): 'test_xor_frozenset', 'test_or_frozenset', - 'test_add_int', 'test_subtract_int', 'test_multiply_int', 'test_floor_divide_int', @@ -399,7 +350,6 @@ class InplaceSetOperationTests(InplaceOperationTestCase, TranspileTestCase): 'test_xor_int', 'test_or_int', - 'test_add_list', 'test_subtract_list', 'test_multiply_list', 'test_floor_divide_list', @@ -412,7 +362,6 @@ class InplaceSetOperationTests(InplaceOperationTestCase, TranspileTestCase): 'test_xor_list', 'test_or_list', - 'test_add_set', 'test_subtract_set', 'test_multiply_set', 'test_floor_divide_set', @@ -425,7 +374,6 @@ class InplaceSetOperationTests(InplaceOperationTestCase, TranspileTestCase): 'test_xor_set', 'test_or_set', - 'test_add_str', 'test_subtract_str', 'test_multiply_str', 'test_floor_divide_str', @@ -438,7 +386,6 @@ class InplaceSetOperationTests(InplaceOperationTestCase, TranspileTestCase): 'test_xor_str', 'test_or_str', - 'test_add_tuple', 'test_subtract_tuple', 'test_multiply_tuple', 'test_floor_divide_tuple', diff --git a/tests/datatypes/test_str.py b/tests/datatypes/test_str.py index 833b549f0e..688134e251 100644 --- a/tests/datatypes/test_str.py +++ b/tests/datatypes/test_str.py @@ -145,25 +145,9 @@ class BinaryStrOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_multiply_list', 'test_subscr_list', - 'test_add_set', - 'test_subtract_set', 'test_multiply_set', - 'test_floor_divide_set', - 'test_true_divide_set', 'test_modulo_set', - 'test_power_set', 'test_subscr_set', - 'test_lshift_set', - 'test_rshift_set', - 'test_and_set', - 'test_xor_set', - 'test_or_set', - 'test_lt_set', - 'test_le_set', - 'test_eq_set', - 'test_ne_set', - 'test_gt_set', - 'test_ge_set', 'test_multiply_str', 'test_modulo_str', diff --git a/tests/datatypes/test_tuple.py b/tests/datatypes/test_tuple.py index afa278a02e..89ccc248ce 100644 --- a/tests/datatypes/test_tuple.py +++ b/tests/datatypes/test_tuple.py @@ -224,18 +224,7 @@ class BinaryTupleOperationTests(BinaryOperationTestCase, TranspileTestCase): 'test_ge_list', 'test_add_set', - 'test_subtract_set', 'test_multiply_set', - 'test_floor_divide_set', - 'test_true_divide_set', - 'test_modulo_set', - 'test_power_set', - 'test_subscr_set', - 'test_lshift_set', - 'test_rshift_set', - 'test_and_set', - 'test_xor_set', - 'test_or_set', 'test_lt_set', 'test_le_set', 'test_eq_set', diff --git a/voc/python/opcodes.py b/voc/python/opcodes.py index 270d8a4094..0c198de37d 100644 --- a/voc/python/opcodes.py +++ b/voc/python/opcodes.py @@ -1778,9 +1778,32 @@ def consume_count(self): def product_count(self): return 1 - # def convert_opcode(self, context, arguments): - # code = [] - # return code + def convert(self, context, arguments): + context.next_resolve_list.append((self, 'start_op')) + context.add_opcodes( + JavaOpcodes.NEW('org/python/types/Set'), + JavaOpcodes.DUP(), + + JavaOpcodes.NEW('java/util/HashSet'), + JavaOpcodes.DUP(), + JavaOpcodes.INVOKESPECIAL('java/util/HashSet', '', '()V') + ) + + for argument in arguments: + context.add_opcodes( + JavaOpcodes.DUP(), + ) + + argument.operation.transpile(context, argument.arguments) + + context.add_opcodes( + JavaOpcodes.INVOKEINTERFACE('java/util/Set', 'add', '(Ljava/lang/Object;)Z'), + JavaOpcodes.POP(), + ) + + context.add_opcodes( + JavaOpcodes.INVOKESPECIAL('org/python/types/Set', '', '(Ljava/util/Set;)V') + ) class BUILD_MAP(Opcode):