Skip to content

Commit 6aefd21

Browse files
authored
Activate update tests (pyccel#2022)
All `update` tests seem to be working already as `update` is simply a multi-element version of `union`. This PR simply activates the existing tests and updates the documentation
1 parent bac6b28 commit 6aefd21

File tree

4 files changed

+46
-39
lines changed

4 files changed

+46
-39
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ All notable changes to this project will be documented in this file.
4545
- #1918 : Add support for set method `clear()`.
4646
- #1918 : Add support for set method `copy()`.
4747
- #1753 : Add support for set method `union()`.
48+
- #1754 : Add support for set method `update()`.
4849
- #1744 : Add Python support for set method `intersection()`.
4950
- #1884 : Add support for dict method `items()`.
5051
- #1936 : Add missing C output for inline decorator example in documentation

docs/builtin-functions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ Python contains a limited number of builtin functions defined [here](https://doc
111111
| `remove` | Python-only |
112112
| `symmetric_difference` | No |
113113
| `symmetric_difference_update` | No |
114-
| **`union`** | Yes |
115-
| `update` | Python-only |
114+
| **`union`** | **Yes** |
115+
| **`update`** | **Yes** |
116116

117117
## Dictionary methods
118118

pyccel/parser/semantic.py

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5323,36 +5323,42 @@ def _build_SetUpdate(self, expr, args):
53235323
CodeBlock or For containing SetAdd objects.
53245324
"""
53255325
if isinstance(expr, DottedName):
5326-
iterable = expr.name[1].args[0].value
5326+
iterable_args = [a.value for a in expr.name[1].args]
53275327
set_obj = expr.name[0]
53285328
elif isinstance(expr, AugAssign):
5329-
iterable = expr.rhs
5329+
iterable_args = [expr.rhs]
53305330
set_obj = expr.lhs
53315331
else:
53325332
raise NotImplementedError(f"Function doesn't handle {type(expr)}")
53335333

5334-
if isinstance(iterable, (PythonList, PythonSet, PythonTuple)):
5335-
list_variable = self._visit(set_obj)
5336-
added_list = self._visit(iterable)
5337-
try:
5338-
store = [SetAdd(list_variable, a) for a in added_list]
5339-
except TypeError as e:
5340-
msg = str(e)
5341-
errors.report(msg, symbol=expr, severity='fatal')
5342-
return CodeBlock(store)
5334+
code = []
5335+
for iterable in iterable_args:
5336+
if isinstance(iterable, (PythonList, PythonSet, PythonTuple)):
5337+
list_variable = self._visit(set_obj)
5338+
added_list = self._visit(iterable)
5339+
try:
5340+
code.extend(SetAdd(list_variable, a) for a in added_list)
5341+
except TypeError as e:
5342+
msg = str(e)
5343+
errors.report(msg, symbol=expr, severity='fatal')
5344+
else:
5345+
pyccel_stage.set_stage('syntactic')
5346+
for_target = self.scope.get_new_name()
5347+
arg = FunctionCallArgument(for_target)
5348+
func_call = FunctionCall('add', [arg])
5349+
dotted = DottedName(set_obj, func_call)
5350+
lhs = PyccelSymbol('_', is_temp=True)
5351+
assign = Assign(lhs, dotted)
5352+
assign.set_current_ast(expr.python_ast)
5353+
body = CodeBlock([assign])
5354+
for_obj = For(for_target, iterable, body)
5355+
pyccel_stage.set_stage('semantic')
5356+
code.append(self._visit(for_obj))
5357+
5358+
if len(code) == 1:
5359+
return code[0]
53435360
else:
5344-
pyccel_stage.set_stage('syntactic')
5345-
for_target = self.scope.get_new_name()
5346-
arg = FunctionCallArgument(for_target)
5347-
func_call = FunctionCall('add', [arg])
5348-
dotted = DottedName(set_obj, func_call)
5349-
lhs = PyccelSymbol('_', is_temp=True)
5350-
assign = Assign(lhs, dotted)
5351-
assign.set_current_ast(expr.python_ast)
5352-
body = CodeBlock([assign])
5353-
for_obj = For(for_target, iterable, body)
5354-
pyccel_stage.set_stage('semantic')
5355-
return self._visit(for_obj)
5361+
return CodeBlock(code)
53565362

53575363
def _build_SetUnion(self, expr, function_call_args):
53585364
"""

tests/epyccel/test_epyccel_sets.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,14 @@ def Discard_wrong_arg():
179179
python_result = Discard_wrong_arg()
180180
assert python_result == pyccel_result
181181

182-
def test_update_basic(python_only_language):
182+
def test_update_basic(language):
183183
def update_basic():
184184
a = {1, 2, 3}
185185
b = {4, 5, 6}
186186
a.update(b)
187187
return len(a), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop()
188188

189-
epyccel_update = epyccel(update_basic, language=python_only_language)
189+
epyccel_update = epyccel(update_basic, language=language)
190190
pyccel_result = epyccel_update()
191191
python_result = update_basic()
192192
assert python_result[0] == pyccel_result[0]
@@ -206,6 +206,18 @@ def update_multiple():
206206
assert python_result[0] == pyccel_result[0]
207207
assert set(python_result[1:]) == set(pyccel_result[1:])
208208

209+
def test_update_multiple_args(language):
210+
def update_multiple():
211+
a = {1, 2, 3}
212+
a.update({4, 5}, {6, 7, 8, 9}, {10})
213+
return len(a), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop(), a.pop()
214+
215+
epyccel_update = epyccel(update_multiple, language=language)
216+
pyccel_result = epyccel_update()
217+
python_result = update_multiple()
218+
assert python_result[0] == pyccel_result[0]
219+
assert set(python_result[1:]) == set(pyccel_result[1:])
220+
209221

210222
def test_update_boolean_tuple(language):
211223
def update_boolean_tuple():
@@ -577,18 +589,6 @@ def intersection_int():
577589
assert python_result[0] == pyccel_result[0]
578590
assert set(python_result[1:]) == set(pyccel_result[1:])
579591

580-
@pytest.mark.parametrize( 'language', (
581-
pytest.param("fortran", marks = [
582-
pytest.mark.xfail(reason="Update not fully implemented yet. See #2022"),
583-
pytest.mark.fortran]
584-
),
585-
pytest.param("c", marks = [
586-
pytest.mark.xfail(reason="Update not fully implemented yet. See #2022"),
587-
pytest.mark.c]
588-
),
589-
pytest.param("python", marks = pytest.mark.python)
590-
)
591-
)
592592
def test_set_union_augoperator(language):
593593
def union_int():
594594
a = {1,2,3,4}

0 commit comments

Comments
 (0)