Skip to content

Commit 0aca4e1

Browse files
List support: remove method (pyccel#1790)
Add support for the `remove()` method of Python lists to the semantic stage and Python codegen. This fixes pyccel#1693. **Commit Summary** - Add a `ListRemove` subclass of `ListMethod`, representing the `remove()` method. The constructor checks for compatibility between the type of the `remove()` argument and the type of the list, and raises an error if they are not homogeneous. - Add success and error tests for the `remove()` method involving many scenarios where the function could be used.
1 parent 667b2fc commit 0aca4e1

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
99
- #1739 : Add Python support for set method `clear()`.
1010
- #1739 : Add abstract class `SetMethod` to handle calls to various set methods.
1111
- #1740 : Add Python support for set method `copy()`.
12+
- #1693 : Add Python support for list method `remove()`.
1213

1314
### Fixed
1415

pyccel/ast/builtin_methods/list_methods.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
'ListInsert',
2020
'ListMethod',
2121
'ListPop',
22+
'ListRemove',
2223
)
2324

2425
#==============================================================================
@@ -229,3 +230,43 @@ class ListExtend(ListMethod):
229230

230231
def __init__(self, list_obj, iterable) -> None:
231232
super().__init__(list_obj, iterable)
233+
234+
#==============================================================================
235+
class ListRemove(ListMethod) :
236+
"""
237+
Represents a call to the .remove() method.
238+
239+
Represents a call to the .remove() method which removes the first
240+
occurrence of a given element from the list.
241+
Note that the .remove() method doesn't return any value.
242+
243+
>>> a = [[1, 2], [3, 4]]
244+
>>> a.remove([1, 2])
245+
>>> print(a)
246+
[[3, 4]]
247+
248+
Parameters
249+
----------
250+
list_obj : TypedAstNode
251+
The list object which the method is called from.
252+
253+
removed_obj : TypedAstNode
254+
The object to be removed from the list.
255+
"""
256+
__slots__ = ()
257+
_shape = None
258+
_order = None
259+
_rank = 0
260+
_class_type = VoidType()
261+
name = 'remove'
262+
263+
def __init__(self, list_obj, removed_obj) -> None:
264+
expected_type = list_obj.class_type.element_type
265+
is_homogeneous = (
266+
removed_obj.class_type == expected_type and
267+
list_obj.rank - 1 == removed_obj.rank
268+
)
269+
if not is_homogeneous:
270+
raise TypeError(f"Can't remove an element of type {removed_obj.class_type} from {list_obj.class_type}")
271+
super().__init__(list_obj, removed_obj)
272+

pyccel/ast/class_defs.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"""
88

99
from pyccel.ast.builtin_methods.set_methods import SetAdd, SetClear, SetCopy, SetPop
10-
from pyccel.ast.builtin_methods.list_methods import ListAppend, ListInsert, ListPop, ListClear, ListExtend
10+
from pyccel.ast.builtin_methods.list_methods import (ListAppend, ListInsert, ListPop,
11+
ListClear, ListExtend, ListRemove)
1112

1213

1314
from .builtins import PythonImag, PythonReal, PythonConjugate
@@ -145,6 +146,7 @@
145146
PyccelFunctionDef('extend', func_class = ListExtend),
146147
PyccelFunctionDef('insert', func_class = ListInsert),
147148
PyccelFunctionDef('pop', func_class = ListPop),
149+
PyccelFunctionDef('remove', func_class = ListRemove),
148150
])
149151

150152
#=======================================================================================

tests/epyccel/test_epyccel_lists.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,38 @@ def test_extend_user_defined_objects(language):
528528
for python_elem, accelerated_elem in zip(python_list, accelerated_list):
529529
assert python_elem.x == accelerated_elem.x
530530

531+
def test_remove_basic(language):
532+
def f():
533+
lst = [1, 2, 3, 4]
534+
lst.remove(3)
535+
return lst
536+
epyc_f = epyccel(f, language=language)
537+
assert f() == epyc_f()
538+
539+
def test_remove_float(language):
540+
def f():
541+
lst = [1.4, 2.3, 3.2, 4.4]
542+
lst.remove(3.2)
543+
return lst
544+
epyc_f = epyccel(f, language=language)
545+
assert f() == epyc_f()
546+
547+
def test_remove_complex(language):
548+
def f():
549+
lst = [1j, 3j, 8j]
550+
lst.remove(3j)
551+
return lst
552+
epyc_f = epyccel(f, language=language)
553+
assert f() == epyc_f()
554+
555+
def test_remove_list_from_list(language):
556+
def f():
557+
lst = [[True, False, True], [False, True]]
558+
lst.remove([False, True])
559+
return lst
560+
epyc_f = epyccel(f, language=language)
561+
assert f() == epyc_f()
562+
531563
def test_extend_list_class_attribute(language):
532564
import modules.list_class_attr as mod
533565

0 commit comments

Comments
 (0)