Commits

Eric Snow committed 7ec70be

getting closer to a basic COrderedDict

Comments (0)

Files changed (2)

.unstable/cordereddict/odictobject.c

 static PyObject *
 odict_clear(register ODictObject *od)
 {
-    if (PyObject_CallMethod(Py_TYPE(od)->tp_base, "clear", NULL) == NULL)
-        return -1;
-    _odict_clear_keys(od);
-    return 0;
+    ODictClear((PyObject *)od);
+    Py_RETURN_NONE;
 }
 
 /* copy() */
     return odict_update(self, args, kwds);
 };
 
+/* tp_clear */
+static int
+odict_tp_clear(PyObject *od)
+{
+    ODict_Clear(op);
+    return 0;
+}
+
 /* Forward */
 static PyObject *dictkeys_new(PyObject *);
 static PyObject *dictitems_new(PyObject *);
 static PyMethodDef odict_methods[] = {
 
     /* overridden dict methods */
-    {"__sizeof__",      (PyCFunction)ODict_sizeof,      METH_NOARGS,
+    {"__sizeof__",      (PyCFunction)odict_sizeof,      METH_NOARGS,
      sizeof__doc__},
-    {"__reduce__",      (PyCFunction)ODict_reduce,      METH_NOARGS,
+    {"__reduce__",      (PyCFunction)odict_reduce,      METH_NOARGS,
      reduce__doc__},
-    {"__repr__",        (PyCFunction)ODict_repr,        METH_NOARGS,
+    {"__repr__",        (PyCFunction)odict_repr,        METH_NOARGS,
      repr__doc__},
-    {"setdefault",      (PyCFunction)ODict_setdefault,  METH_VARARGS,
+    {"setdefault",      (PyCFunction)odict_setdefault,  METH_VARARGS,
      setdefault_doc__},
-    {"pop",             (PyCFunction)ODict_pop,         METH_VARARGS,
+    {"pop",             (PyCFunction)odict_pop,         METH_VARARGS,
      pop__doc__},
-    {"popitem",         (PyCFunction)ODict_popitem,     METH_NOARGS,
+    {"popitem",         (PyCFunction)odict_popitem,     METH_NOARGS,
      popitem__doc__},
     {"keys",            (PyCFunction)odictkeys_new,     METH_NOARGS,
      keys__doc__},
      items__doc__},
     {"values",          (PyCFunction)odictvalues_new,   METH_NOARGS,
      values__doc__},
-    {"update",          (PyCFunction)ODict_update,      METH_VARARGS | METH_KEYWORDS,
+    {"update",          (PyCFunction)odict_update,      METH_VARARGS | METH_KEYWORDS,
      update__doc__},
-    {"clear",           (PyCFunction)ODict_clear,       METH_NOARGS,
+    {"clear",           (PyCFunction)odict_clear,       METH_NOARGS,
      clear__doc__},
-    {"copy",            (PyCFunction)ODict_copy,        METH_NOARGS,
+    {"copy",            (PyCFunction)odict_copy,        METH_NOARGS,
      copy__doc__},
 
     /* new methods */
-    {"__reversed__",    (PyCFunction)ODict_reversed,    METH_NOARGS,
+    {"__reversed__",    (PyCFunction)odict_reversed,    METH_NOARGS,
      reversed__doc__},
     {"move_to_end",     (PyCFunction)odict_move_to_end, METH_VARARGS,
      move_to_end__doc__},
         "Dictionary that remembers insertion order");
 
 /* tp_as_mapping */
-static PyMappingMethods ODict_as_mapping = {
+static PyMappingMethods odict_as_mapping = {
     /* XXX don't these need to be set? inherited? */
     0, /*(lenfunc)dict_length,*/        /*mp_length*/
     0, /*(binaryfunc)dict_subscript,*/  /*mp_subscript*/
     0,                              /* tp_flags */
     odict_doc,                      /* tp_doc */
     0,                              /* tp_traverse */
-    0,                              /* tp_clear */
+    odict_tp_clear,                 /* tp_clear */
     odict_richcompare               /* tp_richcompare */
     0,                              /* tp_weaklistoffset */
     (getiterfunco)odict_iter,       /* tp_iter */
 
 
 /* ODict_New is intended as a more efficient approach than odict_new. */
-PyAPI_FUNC(PyObject *) ODict_New(void) {
+PyAPI_FUNC(PyObject *)
+ODict_New(void) {
     /* XXX do the whole free_list thing, a la PyDict_New */
     return odict_new(&ODict_Type, NULL, NULL);
 };
 
-PyAPI_FUNC(int) ODict_SetItem(PyObject *od, PyObject *key, PyObject *item) {
+PyAPI_FUNC(int)
+ODict_SetItem(PyObject *od, PyObject *key, PyObject *item) {
     /* XXX not finished */
 };
 
-PyAPI_FUNC(int) ODict_DelItem(PyObject *od, PyObject *key) {
-    /* XXX not finished */
+PyAPI_FUNC(int)
+ODict_DelItem(PyObject *od, PyObject *key) {
+    /* XXX better handle other super classes */
+    int res = PyDict_DelItem(od, key);
+    if (res == 0)
+        _odict_remove_key((ODictObject *)od, key);
+    return res
 };
 
-PyAPI_FUNC(void) ODict_Clear(PyObject *od) {
-    /* XXX not finished */
+PyAPI_FUNC(void)
+ODict_Clear(PyObject *od) {
+    /* XXX handle exceptions here? */
+    PyObject_CallMethod(Py_TYPE(od)->tp_base, "clear", NULL);
+    _odict_clear_keys(od);
 };
 
-PyAPI_FUNC(int) ODict_Next(
-    PyObject *od, Py_ssize_t *pos, PyObject **key, PyObject **value) {
-    /* XXX not finished */
+PyAPI_FUNC(int)
+ODict_Next(PyObject *op, Py_ssize_t *pos, PyObject **key, PyObject **value) {
+    odictkey *node;
+    Py_ssize_t i;
+
+    if (!ODict_Check(op))
+        return 0;
+
+    node = (ODictObject *)od->keys;
+    for (i = 0; i < *pos; ++i) {
+        node = node->next;
+        if (node == NULL)
+            return 0;
+    }
+    if (node == NULL)
+        return 0;
+    *pos = i + 1;
+    *key = *(node->key);
+    *value = *(ODict_GetItem(op, node->key));
+    return 1;
 };
 
-PyAPI_FUNC(PyObject *) ODict_Keys(PyObject *od) {
-    /* XXX not finished */
+PyAPI_FUNC(PyObject *)
+ODict_Keys(PyObject *od)
+{
+    if (od == NULL || !ODict_Check(od)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return odict_keys((ODictObject *)od);
+}
+
+PyAPI_FUNC(PyObject *)
+ODict_Values(PyObject *od)
+{
+    if (od == NULL || !ODict_Check(od)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return odict_values((ODictObject *)od);
+}
+
+PyAPI_FUNC(PyObject *)
+ODict_Items(PyObject *od)
+{
+    if (od == NULL || !ODict_Check(od)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    return odict_items((ODictObject *)od);
+}
+
+PyAPI_FUNC(PyObject *)
+ODict_Copy(PyObject *op) {
+    ODictObject *od = (ODictObject *)op;
+    PyObject *obj = PyODict_New();
+    if (obj != NULL) {
+        for (odictkey *node = od->keys; node != NULL; node = node->next) {
+            PyObject *value = ODict_GetItem(op, node->key);
+            if (ODict_SetItem(obj, node->key, value) != 0) {
+                ODict_Clear(obj);
+                Py_DECREF(obj);
+                return NULL;
+            } else {
+                Py_DECREF(value);
+            }
+        }
+    }
+    return obj;
 };
 
-PyAPI_FUNC(PyObject *) ODict_Values(PyObject *od) {
-    /* XXX not finished */
+PyAPI_FUNC(int)
+ODict_Update(PyObject *od, PyObject *other) {
+    return ODict_Merge(od, other, 1);
 };
 
-PyAPI_FUNC(PyObject *) ODict_Items(PyObject *od) {
-    /* XXX not finished */
+PyAPI_FUNC(int)
+ODict_Merge(PyObject *od, PyObject *other, int override) {
+    /* XXX better handle other super classes */
+    int res = PyDict_Merge(od, other, override);
+    if (res == 0) {
+        /* XXX iterate over other.keys() and add new ones on to the end */
+    }
+    return res;
 };
 
-PyAPI_FUNC(Py_ssize_t) ODict_Size(PyObject *od) {
-    /* XXX not finished */
+PyAPI_FUNC(int)
+ODict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) {
+    /* XXX better handle other super classes */
+    int res = PyDict_MergeFromSeq2(d, seq2, override);
+    if (res == 0) {
+        /* XXX iterate over seq2 and add the new keys on to the end */
+    }
+    return res
 };
 
-PyAPI_FUNC(PyObject *) ODict_Copy(PyObject *od) {
-    /* XXX not finished */
+PyAPI_FUNC(int)
+ODict_SetItemString(PyObject *dp, const char *key, PyObject *item) {
+    PyObject *kv;
+    int err;
+    kv = PyUnicode_FromString(key);
+    if (kv == NULL)
+        return -1;
+    PyUnicode_InternInPlace(&kv);
+    err = ODict_SetItem(v, kv, item);
+    Py_DECREF(kv);
+    return err;
 };
 
-PyAPI_FUNC(int) ODict_Update(PyObject *od, PyObject *other) {
-    /* XXX not finished */
+PyAPI_FUNC(int)
+ODict_DelItemString(PyObject *dp, const char *key) {
+    PyObject *kv;
+    int err;
+    kv = PyUnicode_FromString(key);
+    if (kv == NULL)
+        return -1;
+    err = ODict_DelItem(v, kv);
+    Py_DECREF(kv);
+    return err;
 };
-
-PyAPI_FUNC(int) ODict_Merge(PyObject *od,
-                            PyObject *other,
-                            int override) {
-    /* XXX not finished */
-};
-
-PyAPI_FUNC(int) ODict_MergeFromSeq2(PyObject *d,
-                                    PyObject *seq2,
-                                    int override) {
-    /* XXX not finished */
-};
-
-PyAPI_FUNC(int) ODict_SetItemString(PyObject *dp,
-                                    const char *key,
-                                    PyObject *item) {
-    /* XXX not finished */
-};
-
-PyAPI_FUNC(int) ODict_DelItemString(PyObject *dp, const char *key) {
-    /* XXX not finished */
-};

.unstable/cordereddict/odictobject.h

 #define ODict_SIZE(op) ((PyDictObject *)op)->ma_used
 
 PyObject *ODict_New(void);
-int ODict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
-int ODict_DelItem(PyObject *mp, PyObject *key);
-void ODict_Clear(PyObject *mp);
+int ODict_SetItem(PyObject *od, PyObject *key, PyObject *item);
+int ODict_DelItem(PyObject *od, PyObject *key);
+void ODict_Clear(PyObject *od);
 int ODict_Next(
-        PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
+        PyObject *od, Py_ssize_t *pos, PyObject **key, PyObject **value);
 
-PyObject *ODict_Keys(PyObject *mp);
-PyObject *ODict_Values(PyObject *mp);
-PyObject *ODict_Items(PyObject *mp);
-Py_ssize_t ODict_Size(PyObject *mp);
-PyObject *ODict_Copy(PyObject *mp);
+PyObject *ODict_Keys(PyObject *od);
+PyObject *ODict_Values(PyObject *od);
+PyObject *ODict_Items(PyObject *od);
+Py_ssize_t ODict_Size(PyObject *od);
+PyObject *ODict_Copy(PyObject *od);
 
-int ODict_Update(PyObject *mp, PyObject *other);
-int ODict_Merge(PyObject *mp, PyObject *other, int override);
-int ODict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override);
-int ODict_SetItemString(PyObject *dp, const char *key, PyObject *item);
-int ODict_DelItemString(PyObject *dp, const char *key);
+int ODict_Update(PyObject *od, PyObject *other);
+int ODict_Merge(PyObject *od, PyObject *other, int override);
+int ODict_MergeFromSeq2(PyObject *od, PyObject *seq2, int override);
+int ODict_SetItemString(PyObject *od, const char *key, PyObject *item);
+int ODict_DelItemString(PyObject *od, const char *key);
 
 /* wrappers around PyDict* macros */
 
 
 /* wrappers around PyDict* functions */
 
-#define ODict_GetItem(mp, key) PyDict_GetItem(mp, key)
-#define ODict_GetItemWithError(mp, key) PyDict_GetItemWithError(mp, key)
-#define ODict_Contains(mp, key) PyDict_Contains(mp, key)
+#define ODict_GetItem(od, key) PyDict_GetItem(od, key)
+#define ODict_GetItemWithError(od, key) PyDict_GetItemWithError(od, key)
+#define ODict_Contains(od, key) PyDict_Contains(od, key)
+#define ODict_Size(od) PyDict_Size(od)
 
-#define ODict_GetItemString(dp, key)  PyDict_GetItemString(dp, key)
-#define _ODict_GetItemId(dp, key)  _PyDict_GetItemId(dp, key)
+#define ODict_GetItemString(od, key)  PyDict_GetItemString(od, key)
+#define _ODict_GetItemId(od, key)  _PyDict_GetItemId(od, key)
 
 
 #ifdef __cplusplus