From 1d33267092c87c1e1621c806f3742579b37a8835 Mon Sep 17 00:00:00 2001 From: Tanisha Vasudeva Date: Tue, 3 Mar 2026 12:25:56 +0530 Subject: [PATCH] feat: implement dict.popitem() method (#443) (#467) * Added popitem() * fix --------- Co-authored-by: blueloveTH --- src/public/PyDict.c | 19 +++++++++++++++++++ tests/080_dict.py | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/public/PyDict.c b/src/public/PyDict.c index 1e65e13b..b1647771 100644 --- a/src/public/PyDict.c +++ b/src/public/PyDict.c @@ -569,6 +569,24 @@ static bool dict_pop(int argc, py_Ref argv) { return true; } +static bool dict_popitem(int argc, py_Ref argv) { + PY_CHECK_ARGC(1); + Dict* self = py_touserdata(argv); + for(int i = self->entries.length - 1; i >= 0; i--) { + DictEntry* entry = c11__at(DictEntry, &self->entries, i); + if(py_isnil(&entry->key)) continue; + py_Ref p = py_newtuple(py_pushtmp(), 2); + p[0] = entry->key; + p[1] = entry->val; + int res = Dict__pop(self, &p[0]); + c11__rtassert(res == 1); + py_assign(py_retval(), py_peek(-1)); + py_pop(); + return true; + } + return KeyError(py_None()); +} + static bool dict_keys(int argc, py_Ref argv) { PY_CHECK_ARGC(1); Dict* self = py_touserdata(argv); @@ -616,6 +634,7 @@ py_Type pk_dict__register() { py_bindmethod(type, "update", dict_update); py_bindmethod(type, "get", dict_get); py_bindmethod(type, "pop", dict_pop); + py_bindmethod(type, "popitem", dict_popitem); py_bindmethod(type, "keys", dict_keys); py_bindmethod(type, "values", dict_values); py_bindmethod(type, "items", dict_items); diff --git a/tests/080_dict.py b/tests/080_dict.py index 1ccc6603..32431517 100644 --- a/tests/080_dict.py +++ b/tests/080_dict.py @@ -142,6 +142,17 @@ for i in range(n): del a[str(i)] assert len(a) == 0 +# test popitem +n = 2 ** 17 +a = {} +for i in range(n): + a[str(i)] = i +for i in range(n): + k, v = a.popitem() + assert k == str(n - 1 - i) + assert v == n - 1 - i +assert len(a) == 0 + # test del with int keys if 0: n = 2 ** 17