Commit 96c6af9b authored by Eric Snow's avatar Eric Snow

Issue #16991: Add a C implementation of collections.OrderedDict.

parent 0a3297d7
......@@ -85,6 +85,7 @@
#include "tupleobject.h"
#include "listobject.h"
#include "dictobject.h"
#include "odictobject.h"
#include "enumobject.h"
#include "setobject.h"
#include "methodobject.h"
......
......@@ -27,6 +27,11 @@ typedef struct {
PyObject **ma_values;
} PyDictObject;
typedef struct {
PyObject_HEAD
PyDictObject *dv_dict;
} _PyDictViewObject;
#endif /* Py_LIMITED_API */
PyAPI_DATA(PyTypeObject) PyDict_Type;
......@@ -40,9 +45,9 @@ PyAPI_DATA(PyTypeObject) PyDictValues_Type;
#define PyDict_Check(op) \
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS)
#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
#define PyDictKeys_Check(op) (Py_TYPE(op) == &PyDictKeys_Type)
#define PyDictItems_Check(op) (Py_TYPE(op) == &PyDictItems_Type)
#define PyDictValues_Check(op) (Py_TYPE(op) == &PyDictValues_Type)
#define PyDictKeys_Check(op) (PyObject_IsInstance(op, (PyObject *)&PyDictKeys_Type))
#define PyDictItems_Check(op) (PyObject_IsInstance(op, (PyObject *)&PyDictItems_Type))
#define PyDictValues_Check(op) (PyObject_IsInstance(op, (PyObject *)&PyDictValues_Type))
/* This excludes Values, since they are not sets. */
# define PyDictViewSet_Check(op) \
(PyDictKeys_Check(op) || PyDictItems_Check(op))
......@@ -75,6 +80,7 @@ PyDictKeysObject *_PyDict_NewKeysForClass(void);
PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *);
PyAPI_FUNC(int) _PyDict_Next(
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
PyObject *_PyDictView_New(PyObject *, PyTypeObject *);
#endif
PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
......@@ -88,6 +94,9 @@ PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys);
PyObject *_PyDict_SizeOf(PyDictObject *);
PyObject *_PyDict_Pop(PyDictObject *, PyObject *, PyObject *);
PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
PyAPI_FUNC(int) PyDict_ClearFreeList(void);
......
#ifndef Py_ODICTOBJECT_H
#define Py_ODICTOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
/* OrderedDict */
#ifndef Py_LIMITED_API
typedef struct _odictobject PyODictObject;
PyAPI_DATA(PyTypeObject) PyODict_Type;
PyAPI_DATA(PyTypeObject) PyODictIter_Type;
PyAPI_DATA(PyTypeObject) PyODictKeys_Type;
PyAPI_DATA(PyTypeObject) PyODictItems_Type;
PyAPI_DATA(PyTypeObject) PyODictValues_Type;
#endif /* Py_LIMITED_API */
#define PyODict_Check(op) PyObject_IsInstance(op, (PyObject *)&PyODict_Type)
#define PyODict_CheckExact(op) (Py_TYPE(op) == &PyODict_Type)
#define PyODict_SIZE(op) ((PyDictObject *)op)->ma_used
#define PyODict_HasKey(od, key) (PyMapping_HasKey(PyObject *)od, key)
PyAPI_FUNC(PyObject *) PyODict_New(void);
PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item);
PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key);
/* wrappers around PyDict* functions */
#define PyODict_GetItem(od, key) PyDict_GetItem((PyObject *)od, key)
#define PyODict_Contains(od, key) PyDict_Contains((PyObject *)od, key)
#define PyODict_Size(od) PyDict_Size((PyObject *)od)
#define PyODict_GetItemString(od, key) \
PyDict_GetItemString((PyObject *)od, key)
#define Py_ODict_GetItemId(od, key) _PyDict_GetItemId((PyObject *)od, key)
#ifdef __cplusplus
}
#endif
#endif /* !Py_ODICTOBJECT_H */
......@@ -7,7 +7,6 @@ from _collections_abc import *
import _collections_abc
__all__ += _collections_abc.__all__
from _collections import deque, defaultdict
from operator import itemgetter as _itemgetter, eq as _eq
from keyword import iskeyword as _iskeyword
import sys as _sys
......@@ -16,7 +15,18 @@ from _weakref import proxy as _proxy
from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
from reprlib import recursive_repr as _recursive_repr
MutableSequence.register(deque)
try:
from _collections import deque
except ImportError:
pass
else:
MutableSequence.register(deque)
try:
from _collections import defaultdict
except ImportError:
pass
################################################################################
### OrderedDict
......@@ -264,6 +274,13 @@ class OrderedDict(dict):
return dict.__eq__(self, other)
try:
from _collections import OrderedDict
except ImportError:
# Leave the pure Python version in place.
pass
################################################################################
### namedtuple
################################################################################
......
This diff is collapsed.
......@@ -437,6 +437,7 @@ OBJECT_OBJS= \
Objects/listobject.o \
Objects/longobject.o \
Objects/dictobject.o \
Objects/odictobject.o \
Objects/memoryobject.o \
Objects/methodobject.o \
Objects/moduleobject.o \
......
......@@ -23,6 +23,8 @@ Library
- Issue #24326: Fixed audioop.ratecv() with non-default weightB argument.
Original patch by David Moore.
- Issue #16991: Add a C implementation of OrderedDict.
What's New in Python 3.5.0 beta 1?
==================================
......
......@@ -2263,6 +2263,9 @@ PyInit__collections(void)
Py_INCREF(&defdict_type);
PyModule_AddObject(m, "defaultdict", (PyObject *)&defdict_type);
Py_INCREF(&PyODict_Type);
PyModule_AddObject(m, "OrderedDict", (PyObject *)&PyODict_Type);
if (PyType_Ready(&dequeiter_type) < 0)
return NULL;
Py_INCREF(&dequeiter_type);
......
#ifndef Py_DICT_COMMON_H
#define Py_DICT_COMMON_H
typedef struct {
/* Cached hash code of me_key. */
Py_hash_t me_hash;
PyObject *me_key;
PyObject *me_value; /* This field is only meaningful for combined tables */
} PyDictKeyEntry;
typedef PyDictKeyEntry *(*dict_lookup_func)
(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject ***value_addr);
struct _dictkeysobject {
Py_ssize_t dk_refcnt;
Py_ssize_t dk_size;
dict_lookup_func dk_lookup;
Py_ssize_t dk_usable;
PyDictKeyEntry dk_entries[1];
};
#endif
This diff is collapsed.
......@@ -1607,6 +1607,21 @@ _Py_ReadyTypes(void)
if (PyType_Ready(&PyDict_Type) < 0)
Py_FatalError("Can't initialize dict type");
if (PyType_Ready(&PyODict_Type) < 0)
Py_FatalError("Can't initialize OrderedDict type");
if (PyType_Ready(&PyODictKeys_Type) < 0)
Py_FatalError("Can't initialize odict_keys type");
if (PyType_Ready(&PyODictItems_Type) < 0)
Py_FatalError("Can't initialize odict_items type");
if (PyType_Ready(&PyODictValues_Type) < 0)
Py_FatalError("Can't initialize odict_values type");
if (PyType_Ready(&PyODictIter_Type) < 0)
Py_FatalError("Can't initialize odict_keyiterator type");
if (PyType_Ready(&PySet_Type) < 0)
Py_FatalError("Can't initialize set type");
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment