Skip to content

Commit 5e514f2

Browse files
fixed list function implementation (pyccel#1898)
Fix list() issue mentioned in pyccel#1892 . This PR fixes the list() implementation when using a list or a tuple as a parameter Commit Summary - Created PythonListFunction class which acts as a wrapper for PythonList and handles such cases. - Created unit tests using the newly implemented class. --------- Co-authored-by: Emily Bourne <[email protected]>
1 parent 4967933 commit 5e514f2

File tree

5 files changed

+115
-4
lines changed

5 files changed

+115
-4
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ Contributors
3232
* Mustapha Belbiad
3333
* Varadarajan Rengaraj
3434
* Said Mazouz
35+
* Shoaib Moeen

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ All notable changes to this project will be documented in this file.
5454
- #1933 : Improve code printing speed.
5555
- #1930 : Preserve ordering of import targets.
5656
- #1951 : Fix return type for class whose argument cannot be wrapped.
57+
- #1892 : Fix implementation of list function when an iterable is passed as parameter.
5758

5859
### Changed
5960

pyccel/ast/builtins.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
'PythonInt',
4747
'PythonLen',
4848
'PythonList',
49+
'PythonListFunction',
4950
'PythonMap',
5051
'PythonMax',
5152
'PythonMin',
@@ -719,6 +720,47 @@ def is_homogeneous(self):
719720
"""
720721
return True
721722

723+
724+
class PythonListFunction(PyccelFunction):
725+
"""
726+
Class representing a call to the `list` function.
727+
728+
Class representing a call to the `list` function. This is
729+
different to the `[,]' syntax as it only takes one argument
730+
and unpacks any variables.
731+
732+
Parameters
733+
----------
734+
arg : TypedAstNode
735+
The argument passed to the function call.
736+
"""
737+
name = 'list'
738+
__slots__ = ('_class_type', '_shape')
739+
_attribute_nodes = ()
740+
741+
def __new__(cls, arg):
742+
if isinstance(arg, PythonList):
743+
return arg
744+
elif isinstance(arg.shape[0], LiteralInteger):
745+
return PythonList(*[arg[i] for i in range(arg.shape[0])])
746+
else:
747+
return super().__new__(cls)
748+
749+
def __init__(self, copied_obj):
750+
self._class_type = copied_obj.class_type
751+
self._shape = copied_obj.shape
752+
super().__init__(copied_obj)
753+
754+
@property
755+
def copied_obj(self):
756+
"""
757+
The object being copied.
758+
759+
The object being copied to create a new list instance.
760+
"""
761+
return self._args[0]
762+
763+
722764
#==============================================================================
723765
class PythonSet(TypedAstNode):
724766
"""
@@ -1382,7 +1424,7 @@ def print_string(self):
13821424
'float' : PythonFloat,
13831425
'int' : PythonInt,
13841426
'len' : PythonLen,
1385-
'list' : PythonList,
1427+
'list' : PythonListFunction,
13861428
'map' : PythonMap,
13871429
'max' : PythonMax,
13881430
'min' : PythonMin,

pyccel/parser/semantic.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from pyccel.ast.basic import PyccelAstNode, TypedAstNode, ScopedAstNode
2323

2424
from pyccel.ast.builtins import PythonPrint, PythonTupleFunction, PythonSetFunction
25-
from pyccel.ast.builtins import PythonComplex, PythonDict, PythonDictFunction
25+
from pyccel.ast.builtins import PythonComplex, PythonDict, PythonDictFunction, PythonListFunction
2626
from pyccel.ast.builtins import builtin_functions_dict, PythonImag, PythonReal
2727
from pyccel.ast.builtins import PythonList, PythonConjugate , PythonSet
2828
from pyccel.ast.builtins import (PythonRange, PythonZip, PythonEnumerate,
@@ -148,7 +148,7 @@
148148

149149
type_container = {
150150
PythonTupleFunction : HomogeneousTupleType,
151-
PythonList : HomogeneousListType,
151+
PythonListFunction : HomogeneousListType,
152152
PythonSetFunction : HomogeneousSetType,
153153
}
154154

@@ -1969,7 +1969,7 @@ def _get_indexed_type(self, base, args, expr):
19691969
if (len(args) == 2 and args[1] is LiteralEllipsis()) or len(args) == 1:
19701970
syntactic_annotation = self._convert_syntactic_object_to_type_annotation(args[0])
19711971
internal_datatypes = self._visit(syntactic_annotation)
1972-
if dtype_cls in type_container :
1972+
if dtype_cls in type_container:
19731973
class_type = type_container[dtype_cls]
19741974
else:
19751975
raise errors.report(f"Unknown annotation base {base}\n"+PYCCEL_RESTRICTION_TODO,

tests/epyccel/test_epyccel_lists.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,3 +690,70 @@ def f():
690690

691691
epyc_f = epyccel(f, language=stc_language)
692692
assert f() == epyc_f()
693+
694+
def test_homogenous_list_int_copy(language):
695+
def homogeneous_list_int():
696+
return list([1, 2, 3, 4])
697+
f1 = homogeneous_list_int
698+
f2 = epyccel( f1 , language=language)
699+
700+
python_out = f1()
701+
pyccel_out = f2()
702+
print(pyccel_out)
703+
print(python_out)
704+
705+
assert python_out == pyccel_out
706+
707+
def test_homogenous_list_bool_copy(language):
708+
def homogeneous_list_bool():
709+
return list([True, False, True, False])
710+
f1 = homogeneous_list_bool
711+
f2 = epyccel( f1 , language=language)
712+
713+
python_out = f1()
714+
pyccel_out = f2()
715+
print(pyccel_out)
716+
print(python_out)
717+
718+
assert python_out == pyccel_out
719+
720+
def test_homogenous_list_float_copy(language):
721+
def homogeneous_list_float():
722+
return list([1.0, 2.0, 3.0, 4.0])
723+
f1 = homogeneous_list_float
724+
f2 = epyccel( f1 , language=language)
725+
726+
python_out = f1()
727+
pyccel_out = f2()
728+
print(pyccel_out)
729+
print(python_out)
730+
731+
assert python_out == pyccel_out
732+
733+
def test_homogenous_list_int_tuple_copy(language):
734+
def homogeneous_list_int_tuple():
735+
return list((1, 2, 3, 4))
736+
f1 = homogeneous_list_int_tuple
737+
f2 = epyccel( f1 , language=language)
738+
739+
python_out = f1()
740+
pyccel_out = f2()
741+
print(pyccel_out)
742+
print(python_out)
743+
744+
assert python_out == pyccel_out
745+
746+
def test_homogenous_list_unknown_size_copy(language):
747+
def homogeneous_list_unknown_size_copy(n : int):
748+
a = (3,)*n
749+
b = list(a)
750+
return b[0]
751+
f1 = homogeneous_list_unknown_size_copy
752+
f2 = epyccel( f1 , language=language)
753+
754+
python_out = f1(5)
755+
pyccel_out = f2(5)
756+
print(pyccel_out)
757+
print(python_out)
758+
759+
assert python_out == pyccel_out

0 commit comments

Comments
 (0)