diff --git a/mypyc/lib-rt/CPy.h b/mypyc/lib-rt/CPy.h index fa5e9ee499a84..4eab87e4c0116 100644 --- a/mypyc/lib-rt/CPy.h +++ b/mypyc/lib-rt/CPy.h @@ -323,6 +323,7 @@ bool CPyList_SetItem(PyObject *list, CPyTagged index, PyObject *value); PyObject *CPyList_PopLast(PyObject *obj); PyObject *CPyList_Pop(PyObject *obj, CPyTagged index); CPyTagged CPyList_Count(PyObject *obj, PyObject *value); +int CPyList_Insert(PyObject *list, CPyTagged index, PyObject *value); PyObject *CPyList_Extend(PyObject *o1, PyObject *o2); PyObject *CPySequence_Multiply(PyObject *seq, CPyTagged t_size); PyObject *CPySequence_RMultiply(CPyTagged t_size, PyObject *seq); diff --git a/mypyc/lib-rt/list_ops.c b/mypyc/lib-rt/list_ops.c index 5c8fa42fc683b..2c7623398580e 100644 --- a/mypyc/lib-rt/list_ops.c +++ b/mypyc/lib-rt/list_ops.c @@ -108,6 +108,15 @@ CPyTagged CPyList_Count(PyObject *obj, PyObject *value) return list_count((PyListObject *)obj, value); } +int CPyList_Insert(PyObject *list, CPyTagged index, PyObject *value) +{ + if (CPyTagged_CheckShort(index)) { + Py_ssize_t n = CPyTagged_ShortAsSsize_t(index); + return PyList_Insert(list, n, value); + } + return -1; +} + PyObject *CPyList_Extend(PyObject *o1, PyObject *o2) { return _PyList_Extend((PyListObject *)o1, o2); } diff --git a/mypyc/primitives/list_ops.py b/mypyc/primitives/list_ops.py index e94f63dbb0305..fad7a4aacef27 100644 --- a/mypyc/primitives/list_ops.py +++ b/mypyc/primitives/list_ops.py @@ -105,6 +105,14 @@ c_function_name='CPyList_Count', error_kind=ERR_MAGIC) +# list.insert(index, obj) +method_op( + name='insert', + arg_types=[list_rprimitive, int_rprimitive, object_rprimitive], + return_type=c_int_rprimitive, + c_function_name='CPyList_Insert', + error_kind=ERR_NEG_INT) + # list * int binary_op( name='*', diff --git a/mypyc/test-data/irbuild-lists.test b/mypyc/test-data/irbuild-lists.test index 826c04ea64800..5126ca213d261 100644 --- a/mypyc/test-data/irbuild-lists.test +++ b/mypyc/test-data/irbuild-lists.test @@ -233,3 +233,20 @@ L0: r2 = r1 >= 0 :: signed r3 = truncate r1: int32 to builtins.bool return r3 + +[case testListInsert] +from typing import List +def f(x: List[int], y: int) -> None: + x.insert(0, y) +[out] +def f(x, y): + x :: list + y :: int + r0 :: object + r1 :: int32 + r2 :: bit +L0: + r0 = box(int, y) + r1 = CPyList_Insert(x, 0, r0) + r2 = r1 >= 0 :: signed + return 1 diff --git a/mypyc/test-data/run-lists.test b/mypyc/test-data/run-lists.test index 2f02be67d358a..dc5e9862e7ef0 100644 --- a/mypyc/test-data/run-lists.test +++ b/mypyc/test-data/run-lists.test @@ -103,6 +103,12 @@ pop(l, -2) assert l == [1, 3] assert count(l, 1) == 1 assert count(l, 2) == 0 +l.insert(0, 0) +assert l == [0, 1, 3] +l.insert(2, 2) +assert l == [0, 1, 2, 3] +l.insert(4, 4) +assert l == [0, 1, 2, 3, 4] [case testListOfUserDefinedClass] class C: