Skip to content

Commit 8c77c1d

Browse files
Set support: remove method (pyccel#1766)
Add support for the `remove()` method of Python sets to the semantic stage. Add handling of that method to the Python printer. This fixes pyccel#1750.
1 parent 0aca4e1 commit 8c77c1d

File tree

7 files changed

+86
-6
lines changed

7 files changed

+86
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ All notable changes to this project will be documented in this file.
66
### Added
77
- #1720 : Add support for `Ellipsis` as the only index for an array.
88
- #1694 : Add Python support for list method `extend()`.
9-
- #1739 : Add Python support for set method `clear()`.
9+
- #1693 : Add Python support for list method `remove()`.
1010
- #1739 : Add abstract class `SetMethod` to handle calls to various set methods.
11+
- #1739 : Add Python support for set method `clear()`.
1112
- #1740 : Add Python support for set method `copy()`.
12-
- #1693 : Add Python support for list method `remove()`.
13+
- #1750 : Add Python support for set method `remove()`.
1314

1415
### Fixed
1516

pyccel/ast/builtin_methods/set_methods.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
"""
1212
from pyccel.ast.datatypes import VoidType
1313
from pyccel.ast.internals import PyccelInternalFunction
14+
from pyccel.ast.basic import TypedAstNode
1415

15-
__all__ = ('SetAdd', 'SetClear', 'SetMethod', 'SetCopy', 'SetPop')
16+
__all__ = ('SetAdd', 'SetClear', 'SetMethod', 'SetCopy', 'SetPop', 'SetRemove')
1617

1718

1819
class SetMethod(PyccelInternalFunction):
@@ -124,7 +125,6 @@ def __init__(self, set_variable):
124125
self._class_type = set_variable._class_type
125126
super().__init__(set_variable)
126127

127-
128128
class SetPop(SetMethod):
129129
"""
130130
Represents a call to the .pop() method.
@@ -149,3 +149,37 @@ class SetPop(SetMethod):
149149
def __init__(self, set_variable):
150150
self._class_type = set_variable.class_type.element_type
151151
super().__init__(set_variable)
152+
153+
class SetRemove(SetMethod):
154+
"""
155+
Represents a call to the .remove() method.
156+
157+
The remove() method removes the specified item from
158+
the set and updates the set. It doesn't return any value.
159+
160+
Parameters
161+
----------
162+
set_variable : TypedAstNode
163+
The set on which the method will operate.
164+
165+
item : TypedAstNode
166+
The item to search for, and remove.
167+
"""
168+
__slots__ = ()
169+
_shape = None
170+
_order = None
171+
_rank = 0
172+
_class_type = VoidType()
173+
name = 'remove'
174+
175+
def __init__(self, set_variable, item) -> None:
176+
if not isinstance(item, TypedAstNode):
177+
raise TypeError(f"It is not possible to look for a {type(item).__name__} object in a set of {set_variable.dtype}")
178+
expected_type = set_variable.class_type.element_type
179+
is_homogeneous = (
180+
expected_type == item.class_type and
181+
set_variable.rank - 1 == item.rank
182+
)
183+
if not is_homogeneous:
184+
raise TypeError(f"Can't remove an element of type {item.dtype} from a set of {set_variable.dtype}")
185+
super().__init__(set_variable, item)

pyccel/ast/class_defs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
This module contains all types which define a python class which is automatically recognised by pyccel
77
"""
88

9-
from pyccel.ast.builtin_methods.set_methods import SetAdd, SetClear, SetCopy, SetPop
9+
from pyccel.ast.builtin_methods.set_methods import SetAdd, SetClear, SetCopy, SetPop, SetRemove
1010
from pyccel.ast.builtin_methods.list_methods import (ListAppend, ListInsert, ListPop,
1111
ListClear, ListExtend, ListRemove)
1212

13-
1413
from .builtins import PythonImag, PythonReal, PythonConjugate
1514
from .core import ClassDef, PyccelFunctionDef
1615
from .datatypes import (PythonNativeBool, PythonNativeInt, PythonNativeFloat,
@@ -157,6 +156,7 @@
157156
PyccelFunctionDef('clear', func_class = SetClear),
158157
PyccelFunctionDef('copy', func_class = SetCopy),
159158
PyccelFunctionDef('pop', func_class = SetPop),
159+
PyccelFunctionDef('remove', func_class = SetRemove),
160160
])
161161

162162
#=======================================================================================

tests/epyccel/test_epyccel_sets.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,33 @@ def Pop_complex():
144144
python_result = Pop_complex()
145145
assert python_result == pyccel_result
146146

147+
def test_remove_complex(language):
148+
def remove_complex():
149+
se = {1j, 3j, 8j}
150+
se.remove(3j)
151+
return se
152+
epyccel_remove = epyccel(remove_complex, language = language)
153+
pyccel_result = epyccel_remove()
154+
python_result = remove_complex()
155+
assert python_result == pyccel_result
156+
157+
def test_remove_int(language):
158+
def remove_int():
159+
se = {2, 4, 9}
160+
se.remove(4)
161+
return se
162+
epyccel_remove = epyccel(remove_int, language = language)
163+
pyccel_result = epyccel_remove()
164+
python_result = remove_int()
165+
assert python_result == pyccel_result
166+
167+
def test_remove_float(language):
168+
def remove_float():
169+
se = {5.7, 2.4, 8.1}
170+
se.remove(8.1)
171+
return se
172+
epyccel_remove = epyccel(remove_float, language = language)
173+
pyccel_result = epyccel_remove()
174+
python_result = remove_float()
175+
assert python_result == pyccel_result
176+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# pylint: disable=missing-function-docstring, missing-module-docstring
2+
3+
a = {6, 5, 2}
4+
b = 5j
5+
a.remove(b)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# pylint: disable=missing-function-docstring, missing-module-docstring
2+
3+
a = {3j, 9j, 1j}
4+
b = 3.6
5+
a.remove(b)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# pylint: disable=missing-function-docstring, missing-module-docstring
2+
3+
se = {1, 2, 3}
4+
5+
se.remove(range(3,4))

0 commit comments

Comments
 (0)