1 /***********************************************************
2 Copyright (c) 2000, BeOpen.com.
3 Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4 Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
7 See the file "Misc/COPYRIGHT" for information on usage and
8 redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9 ******************************************************************/
11 /* Dictionary object implementation using a hash table */
17 * MINSIZE is the minimum size of a dictionary.
23 Table of irreducible polynomials to efficiently cycle through
24 GF(2^n)-{0}, 2<=n<=30.
26 static long polys
[] = {
59 /* Object used as dummy key to fill deleted entries */
60 static PyObject
*dummy
; /* Initialized by first call to newdictobject() */
63 Invariant for entries: when in use, me_value is not NULL and me_key is
64 not NULL and not dummy; when not in use, me_value is NULL and me_key
65 is either NULL or dummy. A dummy key value cannot be replaced by
66 NULL, since otherwise other keys may be lost.
72 #ifdef USE_CACHE_ALIGNED
78 To ensure the lookup algorithm terminates, the table size must be a
79 prime number and there must be at least one NULL key in the table.
80 The value ma_fill is the number of non-NULL keys; ma_used is the number
81 of non-NULL, non-dummy keys.
82 To avoid slowing down lookups on a near-full table, we resize the table
83 when it is more than half filled.
97 register dictobject
*mp
;
98 if (dummy
== NULL
) { /* Auto-initialize dummy */
99 dummy
= PyString_FromString("<dummy key>");
103 mp
= PyObject_NEW(dictobject
, &PyDict_Type
);
111 PyObject_GC_Init(mp
);
112 return (PyObject
*)mp
;
116 The basic lookup function used by all operations.
117 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
118 Open addressing is preferred over chaining since the link overhead for
119 chaining would be substantial (100% with typical malloc overhead).
120 However, instead of going through the table at constant steps, we cycle
121 through the values of GF(2^n)-{0}. This avoids modulo computations, being
122 much cheaper on RISC machines, without leading to clustering.
124 The initial probe index is computed as hash mod the table size.
125 Subsequent probe indices use the values of x^i in GF(2^n) as an offset,
126 where x is a root. The initial value is derived from hash, too.
128 All arithmetic on hash should ignore overflow.
130 (This version is due to Reimer Behrends, some ideas are also due to
131 Jyrki Alakuijala and Vladimir Marangozov.)
134 lookdict(dictobject
*mp
, PyObject
*key
, register long hash
)
137 register unsigned incr
;
138 register dictentry
*freeslot
;
139 register unsigned int mask
= mp
->ma_size
-1;
140 dictentry
*ep0
= mp
->ma_table
;
141 register dictentry
*ep
;
142 /* We must come up with (i, incr) such that 0 <= i < ma_size
143 and 0 < incr < ma_size and both are a function of hash */
145 /* We use ~hash instead of hash, as degenerate hash functions, such
146 as for ints <sigh>, can have lots of leading zeros. It's not
147 really a performance risk, but better safe than sorry. */
149 if (ep
->me_key
== NULL
|| ep
->me_key
== key
)
151 if (ep
->me_key
== dummy
)
154 if (ep
->me_hash
== hash
&&
155 PyObject_Compare(ep
->me_key
, key
) == 0)
161 /* XXX What if PyObject_Compare returned an exception? */
162 /* Derive incr from hash, just to make it more arbitrary. Note that
163 incr must not be 0, or we will get into an infinite loop.*/
164 incr
= (hash
^ ((unsigned long)hash
>> 3)) & mask
;
168 ep
= &ep0
[(i
+incr
)&mask
];
169 if (ep
->me_key
== NULL
) {
170 if (freeslot
!= NULL
)
175 if (ep
->me_key
== dummy
) {
176 if (freeslot
== NULL
)
179 else if (ep
->me_key
== key
||
180 (ep
->me_hash
== hash
&&
181 PyObject_Compare(ep
->me_key
, key
) == 0)) {
184 /* XXX What if PyObject_Compare returned an exception? */
185 /* Cycle through GF(2^n)-{0} */
188 incr
^= mp
->ma_poly
; /* This will implicitly clear
194 Internal routine to insert a new item into the table.
195 Used both by the internal resize routine and by the public insert routine.
196 Eats a reference to key and one to value.
199 insertdict(register dictobject
*mp
, PyObject
*key
, long hash
, PyObject
*value
)
202 register dictentry
*ep
;
203 ep
= lookdict(mp
, key
, hash
);
204 if (ep
->me_value
!= NULL
) {
205 old_value
= ep
->me_value
;
206 ep
->me_value
= value
;
207 Py_DECREF(old_value
); /* which **CAN** re-enter */
211 if (ep
->me_key
== NULL
)
214 Py_DECREF(ep
->me_key
);
217 ep
->me_value
= value
;
223 Restructure the table by allocating a new table and reinserting all
224 items again. When entries have been deleted, the new table may
225 actually be smaller than the old one.
228 dictresize(dictobject
*mp
, int minused
)
230 register int oldsize
= mp
->ma_size
;
231 register int newsize
, newpoly
;
232 register dictentry
*oldtable
= mp
->ma_table
;
233 register dictentry
*newtable
;
234 register dictentry
*ep
;
236 for (i
= 0, newsize
= MINSIZE
; ; i
++, newsize
<<= 1) {
237 if (i
> sizeof(polys
)/sizeof(polys
[0])) {
238 /* Ran out of polynomials */
242 if (newsize
> minused
) {
247 newtable
= PyMem_NEW(dictentry
, newsize
);
248 if (newtable
== NULL
) {
252 memset(newtable
, '\0', sizeof(dictentry
) * newsize
);
253 mp
->ma_size
= newsize
;
254 mp
->ma_poly
= newpoly
;
255 mp
->ma_table
= newtable
;
259 /* Make two passes, so we can avoid decrefs
260 (and possible side effects) till the table is copied */
261 for (i
= 0, ep
= oldtable
; i
< oldsize
; i
++, ep
++) {
262 if (ep
->me_value
!= NULL
)
263 insertdict(mp
,ep
->me_key
,ep
->me_hash
,ep
->me_value
);
265 for (i
= 0, ep
= oldtable
; i
< oldsize
; i
++, ep
++) {
266 if (ep
->me_value
== NULL
) {
267 Py_XDECREF(ep
->me_key
);
271 if (oldtable
!= NULL
)
277 PyDict_GetItem(PyObject
*op
, PyObject
*key
)
280 if (!PyDict_Check(op
)) {
283 if (((dictobject
*)op
)->ma_table
== NULL
)
286 if (!PyString_Check(key
) ||
287 (hash
= ((PyStringObject
*) key
)->ob_shash
) == -1)
290 hash
= PyObject_Hash(key
);
296 return lookdict((dictobject
*)op
, key
, hash
) -> me_value
;
300 PyDict_SetItem(register PyObject
*op
, PyObject
*key
, PyObject
*value
)
302 register dictobject
*mp
;
304 if (!PyDict_Check(op
)) {
305 PyErr_BadInternalCall();
308 mp
= (dictobject
*)op
;
310 if (PyString_Check(key
)) {
311 #ifdef INTERN_STRINGS
312 if (((PyStringObject
*)key
)->ob_sinterned
!= NULL
) {
313 key
= ((PyStringObject
*)key
)->ob_sinterned
;
314 hash
= ((PyStringObject
*)key
)->ob_shash
;
319 hash
= ((PyStringObject
*)key
)->ob_shash
;
321 hash
= PyObject_Hash(key
);
327 hash
= PyObject_Hash(key
);
331 /* if fill >= 2/3 size, double in size */
332 if (mp
->ma_fill
*3 >= mp
->ma_size
*2) {
333 if (dictresize(mp
, mp
->ma_used
*2) != 0) {
334 if (mp
->ma_fill
+1 > mp
->ma_size
)
340 insertdict(mp
, key
, hash
, value
);
345 PyDict_DelItem(PyObject
*op
, PyObject
*key
)
347 register dictobject
*mp
;
349 register dictentry
*ep
;
350 PyObject
*old_value
, *old_key
;
352 if (!PyDict_Check(op
)) {
353 PyErr_BadInternalCall();
357 if (!PyString_Check(key
) ||
358 (hash
= ((PyStringObject
*) key
)->ob_shash
) == -1)
361 hash
= PyObject_Hash(key
);
365 mp
= (dictobject
*)op
;
366 if (((dictobject
*)op
)->ma_table
== NULL
)
368 ep
= lookdict(mp
, key
, hash
);
369 if (ep
->me_value
== NULL
) {
371 PyErr_SetObject(PyExc_KeyError
, key
);
374 old_key
= ep
->me_key
;
377 old_value
= ep
->me_value
;
380 Py_DECREF(old_value
);
386 PyDict_Clear(PyObject
*op
)
389 register dictentry
*table
;
391 if (!PyDict_Check(op
))
393 mp
= (dictobject
*)op
;
394 table
= mp
->ma_table
;
398 mp
->ma_size
= mp
->ma_used
= mp
->ma_fill
= 0;
400 for (i
= 0; i
< n
; i
++) {
401 Py_XDECREF(table
[i
].me_key
);
402 Py_XDECREF(table
[i
].me_value
);
408 PyDict_Next(PyObject
*op
, int *ppos
, PyObject
**pkey
, PyObject
**pvalue
)
411 register dictobject
*mp
;
412 if (!PyDict_Check(op
))
414 mp
= (dictobject
*)op
;
418 while (i
< mp
->ma_size
&& mp
->ma_table
[i
].me_value
== NULL
)
421 if (i
>= mp
->ma_size
)
424 *pkey
= mp
->ma_table
[i
].me_key
;
426 *pvalue
= mp
->ma_table
[i
].me_value
;
433 dict_dealloc(register dictobject
*mp
)
436 register dictentry
*ep
;
437 Py_TRASHCAN_SAFE_BEGIN(mp
)
438 PyObject_GC_Fini(mp
);
439 for (i
= 0, ep
= mp
->ma_table
; i
< mp
->ma_size
; i
++, ep
++) {
440 if (ep
->me_key
!= NULL
) {
441 Py_DECREF(ep
->me_key
);
443 if (ep
->me_value
!= NULL
) {
444 Py_DECREF(ep
->me_value
);
447 if (mp
->ma_table
!= NULL
)
448 PyMem_DEL(mp
->ma_table
);
449 mp
= (dictobject
*) PyObject_AS_GC(mp
);
451 Py_TRASHCAN_SAFE_END(mp
)
455 dict_print(register dictobject
*mp
, register FILE *fp
, register int flags
)
459 register dictentry
*ep
;
461 i
= Py_ReprEnter((PyObject
*)mp
);
465 fprintf(fp
, "{...}");
471 for (i
= 0, ep
= mp
->ma_table
; i
< mp
->ma_size
; i
++, ep
++) {
472 if (ep
->me_value
!= NULL
) {
475 if (PyObject_Print((PyObject
*)ep
->me_key
, fp
, 0)!=0) {
476 Py_ReprLeave((PyObject
*)mp
);
480 if (PyObject_Print(ep
->me_value
, fp
, 0) != 0) {
481 Py_ReprLeave((PyObject
*)mp
);
487 Py_ReprLeave((PyObject
*)mp
);
492 dict_repr(dictobject
*mp
)
495 PyObject
*sepa
, *colon
;
498 register dictentry
*ep
;
500 i
= Py_ReprEnter((PyObject
*)mp
);
503 return PyString_FromString("{...}");
507 v
= PyString_FromString("{");
508 sepa
= PyString_FromString(", ");
509 colon
= PyString_FromString(": ");
511 for (i
= 0, ep
= mp
->ma_table
; i
< mp
->ma_size
&& v
; i
++, ep
++) {
512 if (ep
->me_value
!= NULL
) {
514 PyString_Concat(&v
, sepa
);
515 PyString_ConcatAndDel(&v
, PyObject_Repr(ep
->me_key
));
516 PyString_Concat(&v
, colon
);
517 PyString_ConcatAndDel(&v
, PyObject_Repr(ep
->me_value
));
520 PyString_ConcatAndDel(&v
, PyString_FromString("}"));
521 Py_ReprLeave((PyObject
*)mp
);
528 dict_length(dictobject
*mp
)
534 dict_subscript(dictobject
*mp
, register PyObject
*key
)
538 if (mp
->ma_table
== NULL
) {
539 PyErr_SetObject(PyExc_KeyError
, key
);
543 if (!PyString_Check(key
) ||
544 (hash
= ((PyStringObject
*) key
)->ob_shash
) == -1)
547 hash
= PyObject_Hash(key
);
551 v
= lookdict(mp
, key
, hash
) -> me_value
;
553 PyErr_SetObject(PyExc_KeyError
, key
);
560 dict_ass_sub(dictobject
*mp
, PyObject
*v
, PyObject
*w
)
563 return PyDict_DelItem((PyObject
*)mp
, v
);
565 return PyDict_SetItem((PyObject
*)mp
, v
, w
);
568 static PyMappingMethods dict_as_mapping
= {
569 (inquiry
)dict_length
, /*mp_length*/
570 (binaryfunc
)dict_subscript
, /*mp_subscript*/
571 (objobjargproc
)dict_ass_sub
, /*mp_ass_subscript*/
575 dict_keys(register dictobject
*mp
, PyObject
*args
)
577 register PyObject
*v
;
579 if (!PyArg_NoArgs(args
))
581 v
= PyList_New(mp
->ma_used
);
584 for (i
= 0, j
= 0; i
< mp
->ma_size
; i
++) {
585 if (mp
->ma_table
[i
].me_value
!= NULL
) {
586 PyObject
*key
= mp
->ma_table
[i
].me_key
;
588 PyList_SetItem(v
, j
, key
);
596 dict_values(register dictobject
*mp
, PyObject
*args
)
598 register PyObject
*v
;
600 if (!PyArg_NoArgs(args
))
602 v
= PyList_New(mp
->ma_used
);
605 for (i
= 0, j
= 0; i
< mp
->ma_size
; i
++) {
606 if (mp
->ma_table
[i
].me_value
!= NULL
) {
607 PyObject
*value
= mp
->ma_table
[i
].me_value
;
609 PyList_SetItem(v
, j
, value
);
617 dict_items(register dictobject
*mp
, PyObject
*args
)
619 register PyObject
*v
;
621 if (!PyArg_NoArgs(args
))
623 v
= PyList_New(mp
->ma_used
);
626 for (i
= 0, j
= 0; i
< mp
->ma_size
; i
++) {
627 if (mp
->ma_table
[i
].me_value
!= NULL
) {
628 PyObject
*key
= mp
->ma_table
[i
].me_key
;
629 PyObject
*value
= mp
->ma_table
[i
].me_value
;
630 PyObject
*item
= PyTuple_New(2);
636 PyTuple_SetItem(item
, 0, key
);
638 PyTuple_SetItem(item
, 1, value
);
639 PyList_SetItem(v
, j
, item
);
647 dict_update(register dictobject
*mp
, PyObject
*args
)
652 if (!PyArg_Parse(args
, "O!", &PyDict_Type
, &other
))
655 goto done
; /* a.update(a); nothing to do */
656 /* Do one big resize at the start, rather than incrementally
657 resizing as we insert new items. Expect that there will be
658 no (or few) overlapping keys. */
659 if ((mp
->ma_fill
+ other
->ma_used
)*3 >= mp
->ma_size
*2) {
660 if (dictresize(mp
, (mp
->ma_used
+ other
->ma_used
)*3/2) != 0)
663 for (i
= 0; i
< other
->ma_size
; i
++) {
664 entry
= &other
->ma_table
[i
];
665 if (entry
->me_value
!= NULL
) {
666 Py_INCREF(entry
->me_key
);
667 Py_INCREF(entry
->me_value
);
668 insertdict(mp
, entry
->me_key
, entry
->me_hash
,
678 dict_copy(register dictobject
*mp
, PyObject
*args
)
680 if (!PyArg_Parse(args
, ""))
682 return PyDict_Copy((PyObject
*)mp
);
686 PyDict_Copy(PyObject
*o
)
688 register dictobject
*mp
;
693 if (o
== NULL
|| !PyDict_Check(o
)) {
694 PyErr_BadInternalCall();
697 mp
= (dictobject
*)o
;
698 copy
= (dictobject
*)PyDict_New();
701 if (mp
->ma_used
> 0) {
702 if (dictresize(copy
, mp
->ma_used
*3/2) != 0)
704 for (i
= 0; i
< mp
->ma_size
; i
++) {
705 entry
= &mp
->ma_table
[i
];
706 if (entry
->me_value
!= NULL
) {
707 Py_INCREF(entry
->me_key
);
708 Py_INCREF(entry
->me_value
);
709 insertdict(copy
, entry
->me_key
, entry
->me_hash
,
714 return (PyObject
*)copy
;
718 PyDict_Size(PyObject
*mp
)
720 if (mp
== NULL
|| !PyDict_Check(mp
)) {
721 PyErr_BadInternalCall();
724 return ((dictobject
*)mp
)->ma_used
;
728 PyDict_Keys(PyObject
*mp
)
730 if (mp
== NULL
|| !PyDict_Check(mp
)) {
731 PyErr_BadInternalCall();
734 return dict_keys((dictobject
*)mp
, (PyObject
*)NULL
);
738 PyDict_Values(PyObject
*mp
)
740 if (mp
== NULL
|| !PyDict_Check(mp
)) {
741 PyErr_BadInternalCall();
744 return dict_values((dictobject
*)mp
, (PyObject
*)NULL
);
748 PyDict_Items(PyObject
*mp
)
750 if (mp
== NULL
|| !PyDict_Check(mp
)) {
751 PyErr_BadInternalCall();
754 return dict_items((dictobject
*)mp
, (PyObject
*)NULL
);
761 /* Subroutine which returns the smallest key in a for which b's value
762 is different or absent. The value is returned too, through the
763 pval argument. No reference counts are incremented. */
766 characterize(dictobject
*a
, dictobject
*b
, PyObject
**pval
)
768 PyObject
*diff
= NULL
;
772 for (i
= 0; i
< a
->ma_size
; i
++) {
773 if (a
->ma_table
[i
].me_value
!= NULL
) {
774 PyObject
*key
= a
->ma_table
[i
].me_key
;
775 PyObject
*aval
, *bval
;
776 /* XXX What if PyObject_Compare raises an exception? */
777 if (diff
!= NULL
&& PyObject_Compare(key
, diff
) > 0)
779 aval
= a
->ma_table
[i
].me_value
;
780 bval
= PyDict_GetItem((PyObject
*)b
, key
);
781 /* XXX What if PyObject_Compare raises an exception? */
782 if (bval
== NULL
|| PyObject_Compare(aval
, bval
) != 0)
793 dict_compare(dictobject
*a
, dictobject
*b
)
795 PyObject
*adiff
, *bdiff
, *aval
, *bval
;
798 /* Compare lengths first */
799 if (a
->ma_used
< b
->ma_used
)
800 return -1; /* a is shorter */
801 else if (a
->ma_used
> b
->ma_used
)
802 return 1; /* b is shorter */
803 /* Same length -- check all keys */
804 adiff
= characterize(a
, b
, &aval
);
805 if (PyErr_Occurred())
808 return 0; /* a is a subset with the same length */
809 bdiff
= characterize(b
, a
, &bval
);
810 if (PyErr_Occurred())
812 /* bdiff == NULL would be impossible now */
813 res
= PyObject_Compare(adiff
, bdiff
);
815 res
= PyObject_Compare(aval
, bval
);
822 dict_compare(dictobject
*a
, dictobject
*b
)
824 PyObject
*akeys
, *bkeys
;
828 if (a
->ma_used
== 0) {
838 akeys
= dict_keys(a
, (PyObject
*)NULL
);
839 bkeys
= dict_keys(b
, (PyObject
*)NULL
);
840 if (akeys
== NULL
|| bkeys
== NULL
) {
841 /* Oops, out of memory -- what to do? */
842 /* For now, sort on address! */
852 n
= a
->ma_used
< b
->ma_used
? a
->ma_used
: b
->ma_used
; /* smallest */
854 for (i
= 0; i
< n
; i
++) {
855 PyObject
*akey
, *bkey
, *aval
, *bval
;
857 akey
= PyList_GetItem(akeys
, i
);
858 bkey
= PyList_GetItem(bkeys
, i
);
859 res
= PyObject_Compare(akey
, bkey
);
863 if (!PyString_Check(akey
) ||
864 (ahash
= ((PyStringObject
*) akey
)->ob_shash
) == -1)
867 ahash
= PyObject_Hash(akey
);
869 PyErr_Clear(); /* Don't want errors here */
872 if (!PyString_Check(bkey
) ||
873 (bhash
= ((PyStringObject
*) bkey
)->ob_shash
) == -1)
876 bhash
= PyObject_Hash(bkey
);
878 PyErr_Clear(); /* Don't want errors here */
880 aval
= lookdict(a
, akey
, ahash
) -> me_value
;
881 bval
= lookdict(b
, bkey
, bhash
) -> me_value
;
882 res
= PyObject_Compare(aval
, bval
);
887 if (a
->ma_used
< b
->ma_used
)
889 else if (a
->ma_used
> b
->ma_used
)
900 dict_has_key(register dictobject
*mp
, PyObject
*args
)
905 if (!PyArg_ParseTuple(args
, "O:has_key", &key
))
908 if (!PyString_Check(key
) ||
909 (hash
= ((PyStringObject
*) key
)->ob_shash
) == -1)
912 hash
= PyObject_Hash(key
);
916 ok
= mp
->ma_size
!= 0 && lookdict(mp
, key
, hash
)->me_value
!= NULL
;
917 return PyInt_FromLong(ok
);
921 dict_get(register dictobject
*mp
, PyObject
*args
)
924 PyObject
*failobj
= Py_None
;
925 PyObject
*val
= NULL
;
928 if (!PyArg_ParseTuple(args
, "O|O:get", &key
, &failobj
))
930 if (mp
->ma_table
== NULL
)
934 if (!PyString_Check(key
) ||
935 (hash
= ((PyStringObject
*) key
)->ob_shash
) == -1)
938 hash
= PyObject_Hash(key
);
942 val
= lookdict(mp
, key
, hash
)->me_value
;
953 dict_setdefault(register dictobject
*mp
, PyObject
*args
)
956 PyObject
*failobj
= Py_None
;
957 PyObject
*val
= NULL
;
960 if (!PyArg_ParseTuple(args
, "O|O:setdefault", &key
, &failobj
))
962 if (mp
->ma_table
== NULL
)
966 if (!PyString_Check(key
) ||
967 (hash
= ((PyStringObject
*) key
)->ob_shash
) == -1)
970 hash
= PyObject_Hash(key
);
974 val
= lookdict(mp
, key
, hash
)->me_value
;
979 if (PyDict_SetItem((PyObject
*)mp
, key
, failobj
))
988 dict_clear(register dictobject
*mp
, PyObject
*args
)
990 if (!PyArg_NoArgs(args
))
992 PyDict_Clear((PyObject
*)mp
);
998 dict_traverse(PyObject
*op
, visitproc visit
, void *arg
)
1004 while (PyDict_Next(op
, &i
, &pk
, &pv
)) {
1005 err
= visit(pk
, arg
);
1008 err
= visit(pv
, arg
);
1016 dict_tp_clear(PyObject
*op
)
1022 static PyMethodDef mapp_methods
[] = {
1023 {"has_key", (PyCFunction
)dict_has_key
, METH_VARARGS
},
1024 {"keys", (PyCFunction
)dict_keys
},
1025 {"items", (PyCFunction
)dict_items
},
1026 {"values", (PyCFunction
)dict_values
},
1027 {"update", (PyCFunction
)dict_update
},
1028 {"clear", (PyCFunction
)dict_clear
},
1029 {"copy", (PyCFunction
)dict_copy
},
1030 {"get", (PyCFunction
)dict_get
, METH_VARARGS
},
1031 {"setdefault", (PyCFunction
)dict_setdefault
, METH_VARARGS
},
1032 {NULL
, NULL
} /* sentinel */
1036 dict_getattr(dictobject
*mp
, char *name
)
1038 return Py_FindMethod(mapp_methods
, (PyObject
*)mp
, name
);
1041 PyTypeObject PyDict_Type
= {
1042 PyObject_HEAD_INIT(&PyType_Type
)
1045 sizeof(dictobject
) + PyGC_HEAD_SIZE
,
1047 (destructor
)dict_dealloc
, /*tp_dealloc*/
1048 (printfunc
)dict_print
, /*tp_print*/
1049 (getattrfunc
)dict_getattr
, /*tp_getattr*/
1051 (cmpfunc
)dict_compare
, /*tp_compare*/
1052 (reprfunc
)dict_repr
, /*tp_repr*/
1054 0, /*tp_as_sequence*/
1055 &dict_as_mapping
, /*tp_as_mapping*/
1059 0, /* tp_getattro */
1060 0, /* tp_setattro */
1061 0, /* tp_as_buffer */
1062 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_GC
, /*tp_flags*/
1064 (traverseproc
)dict_traverse
, /* tp_traverse */
1065 (inquiry
)dict_tp_clear
, /* tp_clear */
1068 /* For backward compatibility with old dictionary interface */
1071 PyDict_GetItemString(PyObject
*v
, char *key
)
1074 kv
= PyString_FromString(key
);
1077 rv
= PyDict_GetItem(v
, kv
);
1083 PyDict_SetItemString(PyObject
*v
, char *key
, PyObject
*item
)
1087 kv
= PyString_FromString(key
);
1090 PyString_InternInPlace(&kv
); /* XXX Should we really? */
1091 err
= PyDict_SetItem(v
, kv
, item
);
1097 PyDict_DelItemString(PyObject
*v
, char *key
)
1101 kv
= PyString_FromString(key
);
1104 err
= PyDict_DelItem(v
, kv
);