Skip to content

Commit 046e93f

Browse files
List support: sort method (pyccel#1798)
Add support for the `sort()` method of Python lists to the semantic stage and Python codegen. This fixes pyccel#1700 . **Commit Summary** - Add a class representation for the `sort()` method, inheriting from `ListMethod`. The constructor checks the passing arguments, and raises an error if the method has an an optional argument. - Add success and error tests for the `sort()` method involving scenarios where the function could be used.
1 parent e8a2bf9 commit 046e93f

File tree

5 files changed

+75
-1
lines changed

5 files changed

+75
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ 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+
- #1700 : Add Python support for list method `sort()`.
910
- #1696 : Add Python support for list method `copy()`.
1011
- #1693 : Add Python support for list method `remove()`.
1112
- #1739 : Add abstract class `SetMethod` to handle calls to various set methods.

pyccel/ast/builtin_methods/list_methods.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
'ListMethod',
2222
'ListPop',
2323
'ListRemove',
24+
'ListSort',
2425
)
2526

2627
#==============================================================================
@@ -279,3 +280,42 @@ def __init__(self, list_obj) -> None:
279280
self._shape = list_obj.shape
280281
self._class_type = list_obj.class_type
281282
super().__init__(list_obj)
283+
284+
#==============================================================================
285+
class ListSort(ListMethod) :
286+
"""
287+
Represents a call to the .sort() method.
288+
289+
Represents a call to the `.sort()` method, which sorts the elements of the
290+
list in ascending order and modifies the original list in place. This means
291+
that the elements of the original list are rearranged to be in sorted order.
292+
Optional parameters are not supported, therefore they should not be provided.
293+
Note that the .sort() method doesn't return any value.
294+
295+
>>> a = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
296+
>>> a.sort()
297+
>>> print(a)
298+
[1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
299+
300+
Parameters
301+
----------
302+
list_obj : TypedAstNode
303+
The list object which the method is called from.
304+
305+
reverse : TypedAstNode, optional
306+
Argument mimicking sort's reverse parameter. This argument is
307+
unsupported so it should not be provided.
308+
309+
key : FunctionDef, optional
310+
A function to specify the sorting criteria(s). This argument is
311+
unsupported so it should not be provided.
312+
"""
313+
__slots__ = ()
314+
_shape = None
315+
_class_type = VoidType()
316+
name = 'sort'
317+
318+
def __init__(self, list_obj, reverse=None, key=None) -> None:
319+
if reverse is not None or key is not None:
320+
raise TypeError("Optional Parameters are not supported for sort() method.")
321+
super().__init__(list_obj, reverse, key)

pyccel/ast/class_defs.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from pyccel.ast.builtin_methods.set_methods import SetAdd, SetClear, SetCopy, SetPop, SetRemove, SetDiscard
1010
from pyccel.ast.builtin_methods.list_methods import (ListAppend, ListInsert, ListPop,
1111
ListClear, ListExtend, ListRemove,
12-
ListCopy)
12+
ListCopy, ListSort)
1313

1414
from .builtins import PythonImag, PythonReal, PythonConjugate
1515
from .core import ClassDef, PyccelFunctionDef
@@ -147,6 +147,7 @@
147147
PyccelFunctionDef('extend', func_class = ListExtend),
148148
PyccelFunctionDef('insert', func_class = ListInsert),
149149
PyccelFunctionDef('pop', func_class = ListPop),
150+
PyccelFunctionDef('sort', func_class = ListSort),
150151
PyccelFunctionDef('remove', func_class = ListRemove),
151152
])
152153

tests/epyccel/test_epyccel_lists.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,33 @@ def g():
476476
epyc_f = epyccel(f, language=language)
477477
assert f() == epyc_f()
478478

479+
def test_sort_basic(language):
480+
def f():
481+
a = [4, 0, 1, -1]
482+
a.sort()
483+
return a
484+
485+
epyc_f = epyccel(f, language=language)
486+
assert f() == epyc_f()
487+
488+
def test_sort_bool(language):
489+
def f():
490+
a = [True, False, False, True, False]
491+
a.sort()
492+
return a
493+
494+
epyc_f = epyccel(f, language=language)
495+
assert f() == epyc_f()
496+
497+
def test_sort_float(language):
498+
def f():
499+
a = [3.4, 1.0, -4.5, 0.0, 2.1]
500+
a.sort()
501+
return a
502+
503+
epyc_f = epyccel(f, language=language)
504+
assert f() == epyc_f()
505+
479506
def test_extend_list_as_arg(language):
480507
def f():
481508
a = [1, 2, 3]
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 = [1, 2, -3, -4, 5]
4+
a.sort(reverse=True, key=abs)
5+

0 commit comments

Comments
 (0)