Skip to content

Commit 5b0ac32

Browse files
[mypyc] Implement list.clear() primitive (#19344)
Add primitive for `list.clear`. Issue: [#1093](mypyc/mypyc#1093)
1 parent 4cefd46 commit 5b0ac32

File tree

6 files changed

+66
-0
lines changed

6 files changed

+66
-0
lines changed

mypyc/lib-rt/CPy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ PyObject *CPySequence_Multiply(PyObject *seq, CPyTagged t_size);
667667
PyObject *CPySequence_RMultiply(CPyTagged t_size, PyObject *seq);
668668
PyObject *CPySequence_InPlaceMultiply(PyObject *seq, CPyTagged t_size);
669669
PyObject *CPyList_GetSlice(PyObject *obj, CPyTagged start, CPyTagged end);
670+
char CPyList_Clear(PyObject *list);
670671
PyObject *CPyList_Copy(PyObject *list);
671672
int CPySequence_Check(PyObject *obj);
672673

mypyc/lib-rt/list_ops.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ PyObject *CPyList_Build(Py_ssize_t len, ...) {
2929
return res;
3030
}
3131

32+
char CPyList_Clear(PyObject *list) {
33+
if (PyList_CheckExact(list)) {
34+
PyList_Clear(list);
35+
} else {
36+
_Py_IDENTIFIER(clear);
37+
PyObject *name = _PyUnicode_FromId(&PyId_clear);
38+
if (name == NULL) {
39+
return 0;
40+
}
41+
PyObject *res = PyObject_CallMethodNoArgs(list, name);
42+
if (res == NULL) {
43+
return 0;
44+
}
45+
}
46+
return 1;
47+
}
48+
3249
PyObject *CPyList_Copy(PyObject *list) {
3350
if(PyList_CheckExact(list)) {
3451
return PyList_GetSlice(list, 0, PyList_GET_SIZE(list));

mypyc/primitives/list_ops.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,15 @@
271271
error_kind=ERR_MAGIC,
272272
)
273273

274+
# list.clear()
275+
method_op(
276+
name="clear",
277+
arg_types=[list_rprimitive],
278+
return_type=bit_rprimitive,
279+
c_function_name="CPyList_Clear",
280+
error_kind=ERR_FALSE,
281+
)
282+
274283
# list.copy()
275284
method_op(
276285
name="copy",

mypyc/test-data/fixtures/ir.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ def sort(self) -> None: pass
245245
def reverse(self) -> None: pass
246246
def remove(self, o: _T) -> None: pass
247247
def index(self, o: _T) -> int: pass
248+
def clear(self) -> None: pass
248249
def copy(self) -> List[_T]: pass
249250

250251
class dict(Mapping[_K, _V]):

mypyc/test-data/irbuild-lists.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,18 @@ L0:
220220
r1 = r0 << 1
221221
return r1
222222

223+
[case testListClear]
224+
from typing import List
225+
def f(l: List[int]) -> None:
226+
return l.clear()
227+
[out]
228+
def f(l):
229+
l :: list
230+
r0 :: bit
231+
L0:
232+
r0 = CPyList_Clear(l)
233+
return 1
234+
223235
[case testListCopy]
224236
from typing import List
225237
from typing import Any

mypyc/test-data/run-lists.test

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,32 @@ print(2, a)
5151
1 [-1, 5]
5252
2 [340282366920938463463374607431768211461, -170141183460469231731687303715884105736]
5353

54+
[case testListClear]
55+
from typing import List, Any
56+
from copysubclass import subc
57+
58+
def test_list_clear() -> None:
59+
l1 = [1, 2, 3, -4, 5]
60+
l1.clear()
61+
assert l1 == []
62+
l1.clear()
63+
assert l1 == []
64+
l2: List[Any] = []
65+
l2.clear()
66+
assert l2 == []
67+
l3 = [1, 2, 3, "abcdef"]
68+
l3.clear()
69+
assert l3 == []
70+
# subclass testing
71+
l4: subc = subc([1, 2, 3])
72+
l4.clear()
73+
assert l4 == []
74+
75+
[file copysubclass.py]
76+
from typing import Any
77+
class subc(list[Any]):
78+
pass
79+
5480
[case testListCopy]
5581
from typing import List
5682
from copysubclass import subc

0 commit comments

Comments
 (0)