Forráskód Böngészése

feat: implement dict.popitem() method (#443) (#467)

* Added popitem()

* fix

---------

Co-authored-by: blueloveTH <blueloveTH@foxmail.com>
Tanisha Vasudeva 2 napja
szülő
commit
1d33267092
2 módosított fájl, 30 hozzáadás és 0 törlés
  1. 19 0
      src/public/PyDict.c
  2. 11 0
      tests/080_dict.py

+ 19 - 0
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);

+ 11 - 0
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