Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mypyc/lib-rt/CPy.h
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,7 @@ CPyTagged CPyList_Index(PyObject *list, PyObject *obj);
PyObject *CPySequence_Multiply(PyObject *seq, CPyTagged t_size);
PyObject *CPySequence_RMultiply(CPyTagged t_size, PyObject *seq);
PyObject *CPyList_GetSlice(PyObject *obj, CPyTagged start, CPyTagged end);
PyObject *CPyList_Copy(PyObject *list);
int CPySequence_Check(PyObject *obj);


Expand Down
14 changes: 14 additions & 0 deletions mypyc/lib-rt/list_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ PyObject *CPyList_Build(Py_ssize_t len, ...) {
return res;
}

PyObject *CPyList_Copy(PyObject *list) {
if(PyList_CheckExact(list)) {
return PyList_GetSlice(list, 0, PyList_GET_SIZE(list));
}
_Py_IDENTIFIER(copy);

PyObject *name = _PyUnicode_FromId(&PyId_copy);
if (name == NULL) {
return NULL;
}
return PyObject_CallMethodNoArgs(list, name);
}


PyObject *CPyList_GetItemUnsafe(PyObject *list, CPyTagged index) {
Py_ssize_t n = CPyTagged_ShortAsSsize_t(index);
PyObject *result = PyList_GET_ITEM(list, n);
Expand Down
9 changes: 9 additions & 0 deletions mypyc/primitives/list_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,15 @@
error_kind=ERR_MAGIC,
)

# list.copy()
method_op(
name="copy",
arg_types=[list_rprimitive],
return_type=list_rprimitive,
c_function_name="CPyList_Copy",
error_kind=ERR_MAGIC,
)

# list * int
binary_op(
name="*",
Expand Down
1 change: 1 addition & 0 deletions mypyc/test-data/fixtures/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ def sort(self) -> None: pass
def reverse(self) -> None: pass
def remove(self, o: _T) -> None: pass
def index(self, o: _T) -> int: pass
def copy(self) -> List[_T]: pass

class dict(Mapping[_K, _V]):
@overload
Expand Down
12 changes: 12 additions & 0 deletions mypyc/test-data/irbuild-lists.test
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ L0:
r1 = r0 << 1
return r1

[case testListCopy]
from typing import List
from typing import Any
def f(a: List[Any]) -> List[Any]:
return a.copy()
[out]
def f(a):
a, r0 :: list
L0:
r0 = CPyList_Copy(a)
return r0

[case testListAppend]
from typing import List
def f(a: List[int], x: int) -> None:
Expand Down
49 changes: 49 additions & 0 deletions mypyc/test-data/run-lists.test
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,55 @@ print(2, a)
1 [-1, 5]
2 [340282366920938463463374607431768211461, -170141183460469231731687303715884105736]

[case testListCopy]
from typing import List
from copysubclass import subc

def test_list_copy() -> None:
l1 = [1, 2, 3, -4, 5]
l2 = l1.copy()
assert l1.copy() == l1
assert l1.copy() == l2
assert l1 == l2
assert l1.copy() == l2.copy()
l1 = l2.copy()
assert l1 == l2
assert l1.copy() == l2
assert l1 == [1, 2, 3, -4, 5]
l2 = [1, 2, -3]
l1 = []
assert l1.copy() == []
assert l2.copy() != l1
assert l2 == l2.copy()
l1 = l2
assert l1.copy().copy() == l2.copy().copy().copy()
assert l1.copy() == l2.copy()
l1 == [1, 2, -3].copy()
assert l1 == l2
l2 = [1, 2, 3].copy()
assert l2 != l1
l1 = [1, 2, 3]
assert l1.copy() == l2.copy()
l3 = [1, 2 , 3, "abcdef"]
assert l3 == l3.copy()
l4 = ["abc", 5, 10]
l4 = l3.copy()
assert l4 == l3
#subclass testing
l5: subc = subc([1, 2, 3])
l6 = l5.copy()
assert l6 == l5
l6 = [1, 2, "3", 4, 5]
l5 = subc([1,2,"3",4,5])
assert l5.copy() == l6.copy()
l6 = l5.copy()
assert l5 == l6

[file copysubclass.py]
from typing import Any
class subc(list[Any]):
pass

[case testSieve]
from typing import List

Expand Down