Repository: pyccel/pyccel
Pull request #2170 (2025-01-21 10:37:41)

Add support for set initialisation from other objects
Add support for set initialisation from other objects via the `set` function. The support is added via `_build_PythonSetFunction`. This removes the need for `PythonSetFunction.__new__`.

While fixing this some bugs were found and fixed. The first bug is relative to temporaries used as arguments to `union` or `intersection`. Temporary objects are now created to store these temporaries.

The second bug is related to the use of `merge` to represent `union` in Fortran. This is not the correct function. In fact `merge` empties the set passed as argument. Instead `insert(a%begin(), a%end())` should be used.

**Commit Summary**
- Remove unnecessary `PythonSetFunction.__new__` function.
- Modify `init_stc_container` to pass `lhs` instead of `Assign`.
- Add implementation of `PythonSet` in `CCodePrinter` in case temporary set literals are used.
- Implement `_print_Allocate` for `PyCodePrinter` in order to handle `reserve` allocations.
- Allow calling `union` on a temporary object.
- Allow calling `intersection` on a temporary object.
- Add `_build_PythonSetFunction`.
- Activate relevant tests.
- Group all `union` tests together.
- Group all `intersection` tests together.
- Add new test `test_set_union_temporaries`.
- Add new test `test_set_intersection_int_temporaries`.
- Fix printing of `set` in Python.
- Fix `union` implementation in Fortran.

pyccel-bot[bot]: Hello again! Thank you for this new pull request :star_struck:.

Please begin by requesting your checklist using the command `/bot checklist`

EmilyBourne: /bot checklist
pyccel-bot[bot]: Unfortunately your PR is not passing the tests so it is not quite ready for review yet. Let me know when it is fixed with `/bot mark as ready`.

pyccel-bot[bot]: Unfortunately your PR is not passing the tests so it is not quite ready for review yet. Let me know when it is fixed with `/bot mark as ready`.

EmilyBourne: /bot run coverage
EmilyBourne: /bot run pr_tests
pyccel-bot[bot]: Hey @pyccel/pyccel-dev ! @EmilyBourne has just created this great new pull request! Check it out and let me know what you think!

pyccel-bot[bot]: Hey @pyccel/pyccel-dev ! @EmilyBourne has just created this great new pull request! Check it out and let me know what you think!

pyccel-bot[bot]: Hey @yguclu, @EmilyBourne, this PR is looking pretty good. @EmilyBourne and @jalalium think it is ready to merge. Could you add your expertise to confirm that this follows all the coding conventions and fits in Pyccel's future plans? Thanks :smile:

EmilyBourne: /bot run pr_tests
EmilyBourne: /bot run pr_tests
pyccel-bot[bot]: Hey @yguclu, @EmilyBourne, this PR is looking pretty good. @EmilyBourne and @jalalium think it is ready to merge. Could you add your expertise to confirm that this follows all the coding conventions and fits in Pyccel's future plans? Thanks :smile:

pyccel-bot[bot]: Hey @yguclu, @EmilyBourne, this PR is looking pretty good. @EmilyBourne and @jalalium think it is ready to merge. Could you add your expertise to confirm that this follows all the coding conventions and fits in Pyccel's future plans? Thanks :smile:


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fdc3ac92..2a5d236b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,7 +11,6 @@ All notable changes to this project will be documented in this file.
 -   #1700 : Add Python support for list method `sort()`.
 -   #1696 : Add Python support for list method `copy()`.
 -   #1693 : Add Python support for list method `remove()`.
--   #1893 : Add Python support for set initialisation with `set()`.
 -   #1895 : Add Python support for dict initialisation with `{}`.
 -   #1895 : Add Python support for dict initialisation with `dict()`.
 -   #1881 : Add Python support for dict method `copy()`.
@@ -36,6 +35,7 @@ All notable changes to this project will be documented in this file.
 -   #1663 : Add C support for sets as arguments.
 -   #1664 : Add C and Fortran support for returning sets from functions.
 -   #2023 : Add support for iterating over a `set`.
+-   #1893 : Add support for set initialisation with `set()`.
 -   #1877 : Add C and Fortran Support for set method `pop()`.
 -   #1917 : Add C and Fortran support for set method `add()`.
 -   #1918 : Add support for set method `clear()`.
diff --git a/docs/builtin-functions.md b/docs/builtin-functions.md
index a6d11971..8033e2ed 100644
--- a/docs/builtin-functions.md
+++ b/docs/builtin-functions.md
@@ -60,7 +60,7 @@ Python contains a limited number of builtin functions defined [here](https://doc
 | `repr` | No |
 | `reversed` | No |
 | **`round`** | **Yes** |
-| *`set`* | Python-only |
+| **`set`** | **Yes** |
 | `setattr` | No  |
 | `slice` | No |
 | `sorted` | No |
diff --git a/pyccel/ast/builtins.py b/pyccel/ast/builtins.py
index 16665d1f..dfb78a7e 100644
--- a/pyccel/ast/builtins.py
+++ b/pyccel/ast/builtins.py
@@ -783,7 +783,7 @@ class PythonList(TypedAstNode):
 
     def __str__(self):
         args = ', '.join(str(a) for a in self)
-        return f'({args})'
+        return f'[{args}]'
 
     def __repr__(self):
         args = ', '.join(str(a) for a in self)
@@ -914,6 +914,14 @@ class PythonSet(TypedAstNode):
         """
         return True
 
+    def __str__(self):
+        args = ', '.join(str(a) for a in self)
+        return f'{{{args}}}'
+
+    def __repr__(self):
+        args = ', '.join(str(a) for a in self)
+        return f'PythonSet({args})'
+
 
 class PythonSetFunction(PyccelFunction):
     """
@@ -931,13 +939,6 @@ class PythonSetFunction(PyccelFunction):
 
     __slots__ = ('_shape', '_class_type')
     name = 'set'
-    def __new__(cls, arg = None):
-        if arg is None:
-            return PythonSet()
-        elif isinstance(arg, (PythonList, PythonSet, PythonTuple)):
-            return PythonSet(*arg)
-        else:
-            return super().__new__(cls)
 
     def __init__(self, copied_obj):
         self._class_type = copied_obj.class_type
diff --git a/pyccel/codegen/printing/ccode.py b/pyccel/codegen/printing/ccode.py
index 48cc9ada..7ea56269 100644
--- a/pyccel/codegen/printing/ccode.py
+++ b/pyccel/codegen/printing/ccode.py
@@ -669,9 +669,8 @@ class CCodePrinter(CodePrinter):
         expr : TypedAstNode
             The object representing the container being printed (e.g., PythonList, PythonSet).
 
-        assignment_var : Assign
-            The assignment node where the Python container (rhs) is being initialized
-            and saved into a variable (lhs).
+        assignment_var : Variable
+            The variable that the Python container is being assigned to.
 
         Returns
         -------
@@ -679,14 +678,14 @@ class CCodePrinter(CodePrinter):
             The generated C code for the container initialization.
         """
 
-        class_type = assignment_var.lhs.class_type
+        class_type = assignment_var.class_type
         dtype = self.get_c_type(class_type)
         if isinstance(expr, PythonDict):
             dict_item_strs = [(self._print(k), self._print(v)) for k,v in zip(expr.keys, expr.values)]
             keyraw = '{' + ', '.join(f'{{{k}, {v}}}' for k,v in dict_item_strs) + '}'
         else:
             keyraw = '{' + ', '.join(self._print(a) for a in expr.args) + '}'
-        container_name = self._print(assignment_var.lhs)
+        container_name = self._print(assignment_var)
         init = f'{container_name} = c_init({dtype}, {keyraw});\n'
         return init
 
@@ -2392,7 +2391,7 @@ class CCodePrinter(CodePrinter):
             return self.arrayFill(expr)
         lhs_code = self._print(lhs)
         if isinstance(rhs, (PythonList, PythonSet, PythonDict)):
-            return self.init_stc_container(rhs, expr)
+            return self.init_stc_container(rhs, expr.lhs)
         rhs_code = self._print(rhs)
         if isinstance(rhs, LiteralString):
             rhs_code = f'cstr_lit({rhs_code})'
@@ -2830,6 +2829,12 @@ class CCodePrinter(CodePrinter):
         arg_val = self._print(expr.args[0])
         return f'{var_type}_erase({set_var}, {arg_val});\n'
 
+    def _print_PythonSet(self, expr):
+        tmp_var = self.scope.get_temporary_variable(expr.class_type, shape = expr.shape,
+                    memory_handling='heap')
+        self._additional_code += self.init_stc_container(expr, tmp_var)
+        return self._print(tmp_var)
+
     #================== Dict methods ==================
 
     def _print_DictClear(self, expr):
diff --git a/pyccel/codegen/printing/fcode.py b/pyccel/codegen/printing/fcode.py
index ac9ea0a3..9c218fa2 100644
--- a/pyccel/codegen/printing/fcode.py
+++ b/pyccel/codegen/printing/fcode.py
@@ -1417,9 +1417,16 @@ class FCodePrinter(CodePrinter):
         self.add_import(self._build_gFTL_extension_module(expr_type))
         args_insert = []
         for arg in expr.args:
-            a = self._print(arg)
             if arg.class_type == expr_type:
-                args_insert.append(f'call {result} % merge({a})\n')
+                # Create a temporary variable to be able to call begin()/end()
+                if not isinstance(arg, Variable):
+                    var = self.scope.get_temporary_variable(arg.class_type)
+                    self._additional_code += self._print(Assign(var, arg)) + '\n'
+                    a = self._print(var)
+                else:
+                    a = self._print(arg)
+
+                args_insert.append(f'call {result} % insert({a} % begin(), {a} % end())\n')
             else:
                 errors.report(PYCCEL_RESTRICTION_TODO, severity = 'error', symbol = expr)
         code = f'{result} = {type_name}({var_code})\n' + ''.join(args_insert)
diff --git a/pyccel/codegen/printing/pycode.py b/pyccel/codegen/printing/pycode.py
index 0faddee7..29016ef3 100644
--- a/pyccel/codegen/printing/pycode.py
+++ b/pyccel/codegen/printing/pycode.py
@@ -11,7 +11,8 @@ from pyccel.ast.builtins   import PythonMin, PythonMax, PythonType, PythonBool,
 from pyccel.ast.builtins   import PythonComplex, DtypePrecisionToCastFunction
 from pyccel.ast.core       import CodeBlock, Import, Assign, FunctionCall, For, AsName, FunctionAddress
 from pyccel.ast.core       import IfSection, FunctionDef, Module, PyccelFunctionDef
-from pyccel.ast.datatypes  import HomogeneousTupleType, VoidType
+from pyccel.ast.datatypes  import HomogeneousTupleType, HomogeneousListType, HomogeneousSetType
+from pyccel.ast.datatypes  import VoidType, DictType
 from pyccel.ast.functionalexpr import FunctionalFor
 from pyccel.ast.literals   import LiteralTrue, LiteralString, LiteralInteger
 from pyccel.ast.numpyext   import numpy_target_swap
@@ -718,6 +719,16 @@ class PythonCodePrinter(CodePrinter):
         return f'range({start}, {stop}, {step})'
 
     def _print_Allocate(self, expr):
+        class_type = expr.variable.class_type
+        if expr.alloc_type == 'reserve':
+            var = self._print(expr.variable)
+            if isinstance(class_type, HomogeneousSetType):
+                return f'{var} = set()\n'
+            elif isinstance(class_type, HomogeneousListType):
+                return f'{var} = list()\n'
+            elif isinstance(class_type, DictType):
+                return f'{var} = dict()\n'
+
         return ''
 
     def _print_Deallocate(self, expr):
diff --git a/pyccel/parser/semantic.py b/pyccel/parser/semantic.py
index eca554d4..84963772 100644
--- a/pyccel/parser/semantic.py
+++ b/pyccel/parser/semantic.py
@@ -64,7 +64,7 @@ from pyccel.ast.core import PyccelFunctionDef
 from pyccel.ast.core import Assert
 from pyccel.ast.core import AllDeclaration
 
-from pyccel.ast.class_defs import get_cls_base
+from pyccel.ast.class_defs import get_cls_base, SetClass
 
 from pyccel.ast.datatypes import CustomDataType, PyccelType, TupleType, VoidType, GenericType
 from pyccel.ast.datatypes import PrimitiveIntegerType, StringType, SymbolicType
@@ -1450,7 +1450,8 @@ class SemanticParser(BasicParser):
         rhs : Variable / expression
             The representation of the rhs provided by the SemanticParser.
             This is necessary in order to set the rhs 'is_target' property
-            if necessary.
+            if necessary. It is also used to determine the type of allocation
+            (init/resize/reserve).
 
         new_expressions : list
             A list which allows collection of any additional expressions
@@ -3434,7 +3435,7 @@ class SemanticParser(BasicParser):
             errors.report("Cannot assign a datatype to a variable.",
                     symbol=expr, severity='error')
 
-        # Checking for the result of _visit_ListExtend
+        # Checking for the result of _build_ListExtend or _build_PythonSetFunction
         if isinstance(rhs, (For, CodeBlock, ConstructorCall)):
             return rhs
 
@@ -5485,7 +5486,7 @@ class SemanticParser(BasicParser):
         set_obj = self._visit(syntactic_set_obj)
         class_type = set_obj.class_type
         if all(a.class_type == class_type for a in args):
-            return SetUnion(set_obj, *args)
+            return SetUnion(set_obj, *args[1:])
         else:
             element_type = class_type.element_type
             if any(a.class_type.element_type != element_type for a in args):
@@ -5535,7 +5536,10 @@ class SemanticParser(BasicParser):
         else:
             syntactic_lhs = self.scope.get_new_name()
         d_var = self._infer_type(start_set)
-        rhs = SetCopy(start_set)
+        if isinstance(start_set, PythonSet):
+            rhs = start_set
+        else:
+            rhs = SetCopy(start_set)
         body = []
         lhs = self._assign_lhs_variable(syntactic_lhs, d_var, rhs, body)
         body.append(Assign(lhs, rhs, python_ast = expr.python_ast))
@@ -5589,3 +5593,59 @@ class SemanticParser(BasicParser):
         else:
             raise errors.report(f"__len__ not implemented for type {class_type}",
                     severity='fatal', symbol=expr)
+
+    def _build_PythonSetFunction(self, expr, function_call_args):
+        """
+        Method to visit a PythonSetFunction node.
+
+        The purpose of this `_build` method is to construct a node representing
+        a set which is built from another object. A build function is required
+        as sets of unknown length must be built by calling the add function
+        repeatedly. This means that the entire assignment statement must be used.
+
+        Parameters
+        ----------
+        expr : FunctionCall
+            The syntactic node that represent the call to `PythonSetFunction`.
+
+        function_call_args : iterable[FunctionCallArgument]
+            The semantic arguments passed to the function.
+
+        Returns
+        -------
+        TypedAstNode | CodeBlock
+            The node representing an object which allows the set to be created.
+        """
+        if len(function_call_args) == 0:
+            return PythonSet()
+
+        arg = function_call_args[0].value
+        class_type = arg.class_type
+        if isinstance(arg, (PythonList, PythonSet, PythonTuple)):
+            return PythonSet(*arg)
+        elif isinstance(class_type, HomogeneousSetType):
+            return SetCopy(arg)
+        else:
+            assigns = expr.get_direct_user_nodes(lambda a: isinstance(a, Assign))
+            if not assigns:
+                lhs = self.scope.get_new_name()
+            else:
+                assert len(assigns) == 1
+                lhs = assigns[0].lhs
+            d_var = {
+                    'class_type' : HomogeneousSetType(class_type.element_type),
+                    'shape' : arg.shape,
+                    'cls_base' : SetClass,
+                    'memory_handling' : 'heap'
+                    }
+            body = []
+            lhs_semantic_var = self._assign_lhs_variable(lhs, d_var, PythonSetFunction(arg), body)
+            scope = self.create_new_loop_scope()
+            targets, iterable = self._get_for_iterators(arg, self.scope.get_new_name(), body)
+            self.exit_loop_scope()
+            body.append(For(targets, iterable, [SetAdd(lhs_semantic_var, targets[0])], scope=scope))
+            if assigns:
+                return CodeBlock(body)
+            else:
+                self._additional_exprs[-1].extend(body)
+                return lhs_semantic_var


Test patch:
diff --git a/tests/epyccel/test_epyccel_sets.py b/tests/epyccel/test_epyccel_sets.py
index 76909066..361483ae 100644
--- a/tests/epyccel/test_epyccel_sets.py
+++ b/tests/epyccel/test_epyccel_sets.py
@@ -5,10 +5,10 @@ from pyccel.decorators import template
 
 @pytest.fixture( params=[
         pytest.param("fortran", marks = [
-            pytest.mark.skip(reason="set methods not implemented in fortran"),
+            pytest.mark.skip(reason="set method not implemented in fortran"),
             pytest.mark.fortran]),
         pytest.param("c", marks = [
-            pytest.mark.skip(reason="set methods not implemented in c"),
+            pytest.mark.skip(reason="set method not implemented in c"),
             pytest.mark.c]),
         pytest.param("python", marks = pytest.mark.python)
     ],
@@ -278,37 +278,37 @@ def test_update_tuple_as_arg(language):
     assert python_result[0] == pyccel_result[0]
     assert set(python_result[1:]) == set(pyccel_result[1:])
 
-def test_set_with_list(python_only_language):
+def test_set_with_list(language):
     def set_With_list():
         a = [1.6, 6.3, 7.2]
         b = set(a)
         return b
 
-    epyc_set_With_list = epyccel(set_With_list, language = python_only_language)
+    epyc_set_With_list = epyccel(set_With_list, language = language)
     pyccel_result = epyc_set_With_list()
     python_result = set_With_list()
     assert isinstance(python_result, type(pyccel_result))
     assert python_result == pyccel_result
 
-def test_set_with_tuple(python_only_language):
+def test_set_with_tuple(language):
     def set_With_tuple():
         a = (1j, 6j, 7j)
         b = set(a)
         return b
 
-    epyc_set_With_tuple = epyccel(set_With_tuple, language = python_only_language)
+    epyc_set_With_tuple = epyccel(set_With_tuple, language = language)
     pyccel_result = epyc_set_With_tuple()
     python_result = set_With_tuple()
     assert isinstance(python_result, type(pyccel_result))
     assert python_result == pyccel_result
 
-def test_set_with_set(python_only_language):
+def test_set_with_set(language):
     def set_With_set():
         a = {True, False, True}  #pylint: disable=duplicate-value
         b = set(a)
         return b
 
-    epyc_set_With_set = epyccel(set_With_set, language = python_only_language)
+    epyc_set_With_set = epyccel(set_With_set, language = language)
     pyccel_result = epyc_set_With_set()
     python_result = set_With_set()
     assert isinstance(python_result, type(pyccel_result))
@@ -350,12 +350,12 @@ def test_set_copy_from_arg1(python_only_language):
     assert isinstance(python_result, type(pyccel_result))
     assert python_result == pyccel_result
 
-def test_set_copy_from_arg2(python_only_language):
+def test_set_copy_from_arg2(stc_language):
     def copy_from_arg2(a : 'set[float]'):
         b = set(a)
         return b
     a = {2.5, 1.4, 9.2}
-    epyc_copy_from_arg = epyccel(copy_from_arg2, language = python_only_language)
+    epyc_copy_from_arg = epyccel(copy_from_arg2, language = stc_language)
     pyccel_result = epyc_copy_from_arg(a)
     python_result = copy_from_arg2(a)
     assert isinstance(python_result, type(pyccel_result))
@@ -403,13 +403,12 @@ def test_set_union_int(language):
         a = {1,2,3,4}
         b = {5,6,7,2}
         c = a.union(b)
-        return len(c), c.pop(), c.pop(), c.pop(), c.pop(), c.pop(), c.pop(), c.pop()
+        return a, b, c
 
     epyccel_func = epyccel(union_int, language = language)
     pyccel_result = epyccel_func()
     python_result = union_int()
-    assert python_result[0] == pyccel_result[0]
-    assert set(python_result[1:]) == set(pyccel_result[1:])
+    assert python_result == pyccel_result
 
 def test_set_union_no_args(language):
     def union_int():
@@ -438,43 +437,14 @@ def test_set_union_2_args(language):
     assert python_result[0] == pyccel_result[0]
     assert set(python_result[1:]) == set(pyccel_result[1:])
 
-def test_set_intersection_int(language):
-    def intersection_int():
-        a = {1,2,3}
-        b = {2,3,4}
-        c = a.intersection(b)
-        return len(c), c.pop(), c.pop()
-
-    epyccel_func = epyccel(intersection_int, language = language)
-    pyccel_result = epyccel_func()
-    python_result = intersection_int()
-    assert python_result[0] == pyccel_result[0]
-    assert set(python_result[1:]) == set(pyccel_result[1:])
-
-def test_set_intersection_no_args(language):
-    def intersection_int():
-        a = {1,2,3,4}
-        c = a.intersection()
-        a.add(5)
-        return len(c), c.pop(), c.pop(), c.pop(), c.pop()
-
-    epyccel_func = epyccel(intersection_int, language = language)
-    pyccel_result = epyccel_func()
-    python_result = intersection_int()
-    assert python_result[0] == pyccel_result[0]
-    assert set(python_result[1:]) == set(pyccel_result[1:])
-
-def test_set_intersection_2_args(language):
-    def intersection_int():
-        a = {1,2,3,4}
-        b = {5,6,7,2,1,3}
-        c = {7,6,10,4,2,3,1}
-        d = a.intersection(b, c)
-        return len(d), d.pop(), d.pop(), d.pop()
+def test_set_union_temporaries(language):
+    def union_int():
+        c = {1,2,3,4}.union({5,6,7,2})
+        return len(c), c.pop(), c.pop(), c.pop(), c.pop(), c.pop(), c.pop(), c.pop()
 
-    epyccel_func = epyccel(intersection_int, language = language)
+    epyccel_func = epyccel(union_int, language = language)
     pyccel_result = epyccel_func()
-    python_result = intersection_int()
+    python_result = union_int()
     assert python_result[0] == pyccel_result[0]
     assert set(python_result[1:]) == set(pyccel_result[1:])
 
@@ -499,6 +469,18 @@ def test_temporary_set_union(language):
     python_result = union_int()
     assert python_result == pyccel_result
 
+def test_temporary_set_union_2(language):
+    def union_int():
+        a = [1,2]
+        b = {2}
+        d = set(a).union(b)
+        return d
+
+    epyccel_func = epyccel(union_int, language = language)
+    pyccel_result = epyccel_func()
+    python_result = union_int()
+    assert python_result == pyccel_result
+
 def test_set_union_list(language):
     def union_list():
         a = {1.2, 2.3}
@@ -538,6 +520,70 @@ def test_set_union_operator(language):
     assert python_result[0] == pyccel_result[0]
     assert set(python_result[1:]) == set(pyccel_result[1:])
 
+def test_set_union_augoperator(language):
+    def union_int():
+        a = {1,2,3,4}
+        b = {5,6,7,2}
+        a |= b
+        return len(a), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop()
+
+    epyccel_func = epyccel(union_int, language = language)
+    pyccel_result = epyccel_func()
+    python_result = union_int()
+    assert python_result[0] == pyccel_result[0]
+    assert set(python_result[1:]) == set(pyccel_result[1:])
+
+def test_set_intersection_int(language):
+    def intersection_int():
+        a = {1,2,3}
+        b = {2,3,4}
+        c = a.intersection(b)
+        return len(c), c.pop(), c.pop()
+
+    epyccel_func = epyccel(intersection_int, language = language)
+    pyccel_result = epyccel_func()
+    python_result = intersection_int()
+    assert python_result[0] == pyccel_result[0]
+    assert set(python_result[1:]) == set(pyccel_result[1:])
+
+def test_set_intersection_no_args(language):
+    def intersection_int():
+        a = {1,2,3,4}
+        c = a.intersection()
+        a.add(5)
+        return len(c), c.pop(), c.pop(), c.pop(), c.pop()
+
+    epyccel_func = epyccel(intersection_int, language = language)
+    pyccel_result = epyccel_func()
+    python_result = intersection_int()
+    assert python_result[0] == pyccel_result[0]
+    assert set(python_result[1:]) == set(pyccel_result[1:])
+
+def test_set_intersection_2_args(language):
+    def intersection_int():
+        a = {1,2,3,4}
+        b = {5,6,7,2,1,3}
+        c = {7,6,10,4,2,3,1}
+        d = a.intersection(b, c)
+        return len(d), d.pop(), d.pop(), d.pop()
+
+    epyccel_func = epyccel(intersection_int, language = language)
+    pyccel_result = epyccel_func()
+    python_result = intersection_int()
+    assert python_result[0] == pyccel_result[0]
+    assert set(python_result[1:]) == set(pyccel_result[1:])
+
+def test_set_intersection_int_temporaries(language):
+    def intersection_int():
+        c = {1,2,3}.intersection({2,3,4})
+        return len(c), c.pop(), c.pop()
+
+    epyccel_func = epyccel(intersection_int, language = language)
+    pyccel_result = epyccel_func()
+    python_result = intersection_int()
+    assert python_result[0] == pyccel_result[0]
+    assert set(python_result[1:]) == set(pyccel_result[1:])
+
 def test_temporary_set_intersection(language):
     def intersection_int():
         a = {1,2}
@@ -590,16 +636,16 @@ def test_set_intersection_multiple_update(language):
     assert python_result[0] == pyccel_result[0]
     assert set(python_result[1:]) == set(pyccel_result[1:])
 
-def test_set_union_augoperator(language):
-    def union_int():
+def test_set_intersection_augoperator(language):
+    def intersection_int():
         a = {1,2,3,4}
-        b = {5,6,7,2}
-        a |= b
-        return len(a), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop()
+        b = {2,3,4}
+        a &= b
+        return len(a), a.pop(), a.pop(), a.pop()
 
-    epyccel_func = epyccel(union_int, language = language)
+    epyccel_func = epyccel(intersection_int, language = language)
     pyccel_result = epyccel_func()
-    python_result = union_int()
+    python_result = intersection_int()
     assert python_result[0] == pyccel_result[0]
     assert set(python_result[1:]) == set(pyccel_result[1:])
 
@@ -614,19 +660,6 @@ def test_set_contains(language):
     python_result = union_int()
     assert python_result == pyccel_result
 
-def test_set_intersection_augoperator(language):
-    def intersection_int():
-        a = {1,2,3,4}
-        b = {2,3,4}
-        a &= b
-        return len(a), a.pop(), a.pop(), a.pop()
-
-    epyccel_func = epyccel(intersection_int, language = language)
-    pyccel_result = epyccel_func()
-    python_result = intersection_int()
-    assert python_result[0] == pyccel_result[0]
-    assert set(python_result[1:]) == set(pyccel_result[1:])
-
 def test_set_ptr(language):
     def set_ptr():
         a = {1,2,3,4,5,6,7,8}