| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1 |  | 
| Guido van Rossum | 2bc1379 | 1999-03-24 19:06:42 +0000 | [diff] [blame] | 2 | /* Dictionary object implementation using a hash table */ | 
| Guido van Rossum | 9bfef44 | 1993-03-29 10:43:31 +0000 | [diff] [blame] | 3 |  | 
| Raymond Hettinger | 930427b | 2003-05-03 06:51:59 +0000 | [diff] [blame] | 4 | /* The distribution includes a separate file, Objects/dictnotes.txt, | 
| Tim Peters | 60b2996 | 2006-01-01 01:19:23 +0000 | [diff] [blame] | 5 |    describing explorations into dictionary design and optimization. | 
| Raymond Hettinger | 930427b | 2003-05-03 06:51:59 +0000 | [diff] [blame] | 6 |    It covers typical dictionary use patterns, the parameters for | 
 | 7 |    tuning dictionaries, and several ideas for possible optimizations. | 
 | 8 | */ | 
 | 9 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 10 | #include "Python.h" | 
| Christian Heimes | 0ded5b5 | 2007-12-10 15:50:56 +0000 | [diff] [blame] | 11 | #include "stringlib/eq.h" | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 12 |  | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 13 |  | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 14 | /* Set a key error with the specified argument, wrapping it in a | 
 | 15 |  * tuple automatically so that tuple keys are not unpacked as the | 
 | 16 |  * exception arguments. */ | 
 | 17 | static void | 
 | 18 | set_key_error(PyObject *arg) | 
 | 19 | { | 
 | 20 | 	PyObject *tup; | 
 | 21 | 	tup = PyTuple_Pack(1, arg); | 
 | 22 | 	if (!tup) | 
 | 23 | 		return; /* caller will expect error to be set anyway */ | 
 | 24 | 	PyErr_SetObject(PyExc_KeyError, tup); | 
 | 25 | 	Py_DECREF(tup); | 
 | 26 | } | 
 | 27 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 28 | /* Define this out if you don't want conversion statistics on exit. */ | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 29 | #undef SHOW_CONVERSION_COUNTS | 
 | 30 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 31 | /* See large comment block below.  This must be >= 1. */ | 
 | 32 | #define PERTURB_SHIFT 5 | 
 | 33 |  | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 34 | /* | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 35 | Major subtleties ahead:  Most hash schemes depend on having a "good" hash | 
 | 36 | function, in the sense of simulating randomness.  Python doesn't:  its most | 
 | 37 | important hash functions (for strings and ints) are very regular in common | 
 | 38 | cases: | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 39 |  | 
| Guido van Rossum | dc5f6b2 | 2006-08-24 21:29:26 +0000 | [diff] [blame] | 40 |   >>> map(hash, (0, 1, 2, 3)) | 
 | 41 |   [0, 1, 2, 3] | 
 | 42 |   >>> map(hash, ("namea", "nameb", "namec", "named")) | 
 | 43 |   [-1658398457, -1658398460, -1658398459, -1658398462] | 
 | 44 |   >>> | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 45 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 46 | This isn't necessarily bad!  To the contrary, in a table of size 2**i, taking | 
 | 47 | the low-order i bits as the initial table index is extremely fast, and there | 
 | 48 | are no collisions at all for dicts indexed by a contiguous range of ints. | 
 | 49 | The same is approximately true when keys are "consecutive" strings.  So this | 
 | 50 | gives better-than-random behavior in common cases, and that's very desirable. | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 51 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 52 | OTOH, when collisions occur, the tendency to fill contiguous slices of the | 
 | 53 | hash table makes a good collision resolution strategy crucial.  Taking only | 
 | 54 | the last i bits of the hash code is also vulnerable:  for example, consider | 
| Guido van Rossum | dc5f6b2 | 2006-08-24 21:29:26 +0000 | [diff] [blame] | 55 | the list [i << 16 for i in range(20000)] as a set of keys.  Since ints are  | 
 | 56 | their own hash codes, and this fits in a dict of size 2**15, the last 15 bits | 
 | 57 |  of every hash code are all 0:  they *all* map to the same table index. | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 58 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 59 | But catering to unusual cases should not slow the usual ones, so we just take | 
 | 60 | the last i bits anyway.  It's up to collision resolution to do the rest.  If | 
 | 61 | we *usually* find the key we're looking for on the first try (and, it turns | 
 | 62 | out, we usually do -- the table load factor is kept under 2/3, so the odds | 
 | 63 | are solidly in our favor), then it makes best sense to keep the initial index | 
 | 64 | computation dirt cheap. | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 65 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 66 | The first half of collision resolution is to visit table indices via this | 
 | 67 | recurrence: | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 68 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 69 |     j = ((5*j) + 1) mod 2**i | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 70 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 71 | For any initial j in range(2**i), repeating that 2**i times generates each | 
 | 72 | int in range(2**i) exactly once (see any text on random-number generation for | 
 | 73 | proof).  By itself, this doesn't help much:  like linear probing (setting | 
 | 74 | j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed | 
 | 75 | order.  This would be bad, except that's not the only thing we do, and it's | 
 | 76 | actually *good* in the common cases where hash keys are consecutive.  In an | 
 | 77 | example that's really too small to make this entirely clear, for a table of | 
 | 78 | size 2**3 the order of indices is: | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 79 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 80 |     0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating] | 
 | 81 |  | 
 | 82 | If two things come in at index 5, the first place we look after is index 2, | 
 | 83 | not 6, so if another comes in at index 6 the collision at 5 didn't hurt it. | 
 | 84 | Linear probing is deadly in this case because there the fixed probe order | 
 | 85 | is the *same* as the order consecutive keys are likely to arrive.  But it's | 
 | 86 | extremely unlikely hash codes will follow a 5*j+1 recurrence by accident, | 
 | 87 | and certain that consecutive hash codes do not. | 
 | 88 |  | 
 | 89 | The other half of the strategy is to get the other bits of the hash code | 
 | 90 | into play.  This is done by initializing a (unsigned) vrbl "perturb" to the | 
 | 91 | full hash code, and changing the recurrence to: | 
 | 92 |  | 
 | 93 |     j = (5*j) + 1 + perturb; | 
 | 94 |     perturb >>= PERTURB_SHIFT; | 
 | 95 |     use j % 2**i as the next table index; | 
 | 96 |  | 
 | 97 | Now the probe sequence depends (eventually) on every bit in the hash code, | 
 | 98 | and the pseudo-scrambling property of recurring on 5*j+1 is more valuable, | 
 | 99 | because it quickly magnifies small differences in the bits that didn't affect | 
 | 100 | the initial index.  Note that because perturb is unsigned, if the recurrence | 
 | 101 | is executed often enough perturb eventually becomes and remains 0.  At that | 
 | 102 | point (very rarely reached) the recurrence is on (just) 5*j+1 again, and | 
 | 103 | that's certain to find an empty slot eventually (since it generates every int | 
 | 104 | in range(2**i), and we make sure there's always at least one empty slot). | 
 | 105 |  | 
 | 106 | Selecting a good value for PERTURB_SHIFT is a balancing act.  You want it | 
 | 107 | small so that the high bits of the hash code continue to affect the probe | 
 | 108 | sequence across iterations; but you want it large so that in really bad cases | 
 | 109 | the high-order hash bits have an effect on early iterations.  5 was "the | 
 | 110 | best" in minimizing total collisions across experiments Tim Peters ran (on | 
 | 111 | both normal and pathological cases), but 4 and 6 weren't significantly worse. | 
 | 112 |  | 
| Guido van Rossum | dc5f6b2 | 2006-08-24 21:29:26 +0000 | [diff] [blame] | 113 | Historical: Reimer Behrends contributed the idea of using a polynomial-based | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 114 | approach, using repeated multiplication by x in GF(2**n) where an irreducible | 
 | 115 | polynomial for each table size was chosen such that x was a primitive root. | 
 | 116 | Christian Tismer later extended that to use division by x instead, as an | 
 | 117 | efficient way to get the high bits of the hash code into play.  This scheme | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 118 | also gave excellent collision statistics, but was more expensive:  two | 
 | 119 | if-tests were required inside the loop; computing "the next" index took about | 
 | 120 | the same number of operations but without as much potential parallelism | 
 | 121 | (e.g., computing 5*j can go on at the same time as computing 1+perturb in the | 
 | 122 | above, and then shifting perturb can be done while the table index is being | 
 | 123 | masked); and the PyDictObject struct required a member to hold the table's | 
 | 124 | polynomial.  In Tim's experiments the current scheme ran faster, produced | 
 | 125 | equally good collision statistics, needed less code & used less memory. | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 126 |  | 
 | 127 | Theoretical Python 2.5 headache:  hash codes are only C "long", but | 
 | 128 | sizeof(Py_ssize_t) > sizeof(long) may be possible.  In that case, and if a | 
 | 129 | dict is genuinely huge, then only the slots directly reachable via indexing | 
 | 130 | by a C long can be the first slot in a probe sequence.  The probe sequence | 
 | 131 | will still eventually reach every slot in the table, but the collision rate | 
 | 132 | on initial probes may be much higher than this scheme was designed for. | 
 | 133 | Getting a hash code as fat as Py_ssize_t is the only real cure.  But in | 
 | 134 | practice, this probably won't make a lick of difference for many years (at | 
 | 135 | which point everyone will have terabytes of RAM on 64-bit boxes). | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 136 | */ | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 137 |  | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 138 | /* Object used as dummy key to fill deleted entries */ | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 139 | static PyObject *dummy = NULL; /* Initialized by first call to newPyDictObject() */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 140 |  | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 141 | #ifdef Py_REF_DEBUG | 
 | 142 | PyObject * | 
 | 143 | _PyDict_Dummy(void) | 
 | 144 | { | 
 | 145 | 	return dummy; | 
 | 146 | } | 
 | 147 | #endif | 
 | 148 |  | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 149 | /* forward declarations */ | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 150 | static PyDictEntry * | 
 | 151 | lookdict_unicode(PyDictObject *mp, PyObject *key, long hash); | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 152 |  | 
 | 153 | #ifdef SHOW_CONVERSION_COUNTS | 
 | 154 | static long created = 0L; | 
 | 155 | static long converted = 0L; | 
 | 156 |  | 
 | 157 | static void | 
 | 158 | show_counts(void) | 
 | 159 | { | 
 | 160 | 	fprintf(stderr, "created %ld string dicts\n", created); | 
 | 161 | 	fprintf(stderr, "converted %ld to normal dicts\n", converted); | 
 | 162 | 	fprintf(stderr, "%.2f%% conversion rate\n", (100.0*converted)/created); | 
 | 163 | } | 
 | 164 | #endif | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 165 |  | 
| Christian Heimes | 77c02eb | 2008-02-09 02:18:51 +0000 | [diff] [blame] | 166 | /* Debug statistic to compare allocations with reuse through the free list */ | 
 | 167 | #undef SHOW_ALLOC_COUNT | 
 | 168 | #ifdef SHOW_ALLOC_COUNT | 
 | 169 | static size_t count_alloc = 0; | 
 | 170 | static size_t count_reuse = 0; | 
 | 171 |  | 
 | 172 | static void | 
 | 173 | show_alloc(void) | 
 | 174 | { | 
| Christian Heimes | 23daade0 | 2008-02-25 12:39:23 +0000 | [diff] [blame] | 175 | 	fprintf(stderr, "Dict allocations: %" PY_FORMAT_SIZE_T "d\n", | 
 | 176 | 		count_alloc); | 
 | 177 | 	fprintf(stderr, "Dict reuse through freelist: %" PY_FORMAT_SIZE_T | 
 | 178 | 		"d\n", count_reuse); | 
| Christian Heimes | 77c02eb | 2008-02-09 02:18:51 +0000 | [diff] [blame] | 179 | 	fprintf(stderr, "%.2f%% reuse rate\n\n", | 
 | 180 | 		(100.0*count_reuse/(count_alloc+count_reuse))); | 
 | 181 | } | 
 | 182 | #endif | 
 | 183 |  | 
| Antoine Pitrou | 3a652b1 | 2009-03-23 18:52:06 +0000 | [diff] [blame] | 184 | /* Debug statistic to count GC tracking of dicts */ | 
 | 185 | #ifdef SHOW_TRACK_COUNT | 
 | 186 | static Py_ssize_t count_untracked = 0; | 
 | 187 | static Py_ssize_t count_tracked = 0; | 
 | 188 |  | 
 | 189 | static void | 
 | 190 | show_track(void) | 
 | 191 | { | 
 | 192 | 	fprintf(stderr, "Dicts created: %" PY_FORMAT_SIZE_T "d\n", | 
 | 193 | 		count_tracked + count_untracked); | 
 | 194 | 	fprintf(stderr, "Dicts tracked by the GC: %" PY_FORMAT_SIZE_T | 
 | 195 | 		"d\n", count_tracked); | 
 | 196 | 	fprintf(stderr, "%.2f%% dict tracking rate\n\n", | 
 | 197 | 		(100.0*count_tracked/(count_untracked+count_tracked))); | 
 | 198 | } | 
 | 199 | #endif | 
 | 200 |  | 
 | 201 |  | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 202 | /* Initialization macros. | 
 | 203 |    There are two ways to create a dict:  PyDict_New() is the main C API | 
 | 204 |    function, and the tp_new slot maps to dict_new().  In the latter case we | 
 | 205 |    can save a little time over what PyDict_New does because it's guaranteed | 
 | 206 |    that the PyDictObject struct is already zeroed out. | 
 | 207 |    Everyone except dict_new() should use EMPTY_TO_MINSIZE (unless they have | 
 | 208 |    an excellent reason not to). | 
 | 209 | */ | 
 | 210 |  | 
 | 211 | #define INIT_NONZERO_DICT_SLOTS(mp) do {				\ | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 212 | 	(mp)->ma_table = (mp)->ma_smalltable;				\ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 213 | 	(mp)->ma_mask = PyDict_MINSIZE - 1;				\ | 
 | 214 |     } while(0) | 
 | 215 |  | 
 | 216 | #define EMPTY_TO_MINSIZE(mp) do {					\ | 
 | 217 | 	memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable));	\ | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 218 | 	(mp)->ma_used = (mp)->ma_fill = 0;				\ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 219 | 	INIT_NONZERO_DICT_SLOTS(mp);					\ | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 220 |     } while(0) | 
 | 221 |  | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 222 | /* Dictionary reuse scheme to save calls to malloc, free, and memset */ | 
| Christian Heimes | 2202f87 | 2008-02-06 14:31:34 +0000 | [diff] [blame] | 223 | #ifndef PyDict_MAXFREELIST | 
 | 224 | #define PyDict_MAXFREELIST 80 | 
 | 225 | #endif | 
 | 226 | static PyDictObject *free_list[PyDict_MAXFREELIST]; | 
 | 227 | static int numfree = 0; | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 228 |  | 
| Christian Heimes | 77c02eb | 2008-02-09 02:18:51 +0000 | [diff] [blame] | 229 | void | 
 | 230 | PyDict_Fini(void) | 
 | 231 | { | 
 | 232 | 	PyDictObject *op; | 
 | 233 |  | 
 | 234 | 	while (numfree) { | 
 | 235 | 		op = free_list[--numfree]; | 
 | 236 | 		assert(PyDict_CheckExact(op)); | 
 | 237 | 		PyObject_GC_Del(op); | 
 | 238 | 	} | 
 | 239 | } | 
 | 240 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 241 | PyObject * | 
| Thomas Wouters | 7889010 | 2000-07-22 19:25:51 +0000 | [diff] [blame] | 242 | PyDict_New(void) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 243 | { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 244 | 	register PyDictObject *mp; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 245 | 	if (dummy == NULL) { /* Auto-initialize dummy */ | 
| Neal Norwitz | 53cbdaa | 2007-08-23 21:42:55 +0000 | [diff] [blame] | 246 | 		dummy = PyUnicode_FromString("<dummy key>"); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 247 | 		if (dummy == NULL) | 
 | 248 | 			return NULL; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 249 | #ifdef SHOW_CONVERSION_COUNTS | 
 | 250 | 		Py_AtExit(show_counts); | 
 | 251 | #endif | 
| Christian Heimes | 77c02eb | 2008-02-09 02:18:51 +0000 | [diff] [blame] | 252 | #ifdef SHOW_ALLOC_COUNT | 
 | 253 | 		Py_AtExit(show_alloc); | 
 | 254 | #endif | 
| Antoine Pitrou | 3a652b1 | 2009-03-23 18:52:06 +0000 | [diff] [blame] | 255 | #ifdef SHOW_TRACK_COUNT | 
 | 256 | 		Py_AtExit(show_track); | 
 | 257 | #endif | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 258 | 	} | 
| Christian Heimes | 2202f87 | 2008-02-06 14:31:34 +0000 | [diff] [blame] | 259 | 	if (numfree) { | 
 | 260 | 		mp = free_list[--numfree]; | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 261 | 		assert (mp != NULL); | 
| Christian Heimes | 90aa764 | 2007-12-19 02:45:37 +0000 | [diff] [blame] | 262 | 		assert (Py_TYPE(mp) == &PyDict_Type); | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 263 | 		_Py_NewReference((PyObject *)mp); | 
 | 264 | 		if (mp->ma_fill) { | 
 | 265 | 			EMPTY_TO_MINSIZE(mp); | 
| Georg Brandl | 6aa2d1f | 2008-08-12 08:35:52 +0000 | [diff] [blame] | 266 | 		} else { | 
 | 267 | 			/* At least set ma_table and ma_mask; these are wrong | 
 | 268 | 			   if an empty but presized dict is added to freelist */ | 
 | 269 | 			INIT_NONZERO_DICT_SLOTS(mp); | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 270 | 		} | 
 | 271 | 		assert (mp->ma_used == 0); | 
 | 272 | 		assert (mp->ma_table == mp->ma_smalltable); | 
 | 273 | 		assert (mp->ma_mask == PyDict_MINSIZE - 1); | 
| Christian Heimes | 77c02eb | 2008-02-09 02:18:51 +0000 | [diff] [blame] | 274 | #ifdef SHOW_ALLOC_COUNT | 
 | 275 | 		count_reuse++; | 
 | 276 | #endif | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 277 | 	} else { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 278 | 		mp = PyObject_GC_New(PyDictObject, &PyDict_Type); | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 279 | 		if (mp == NULL) | 
 | 280 | 			return NULL; | 
 | 281 | 		EMPTY_TO_MINSIZE(mp); | 
| Christian Heimes | 77c02eb | 2008-02-09 02:18:51 +0000 | [diff] [blame] | 282 | #ifdef SHOW_ALLOC_COUNT | 
 | 283 | 		count_alloc++; | 
 | 284 | #endif | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 285 | 	} | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 286 | 	mp->ma_lookup = lookdict_unicode; | 
| Antoine Pitrou | 3a652b1 | 2009-03-23 18:52:06 +0000 | [diff] [blame] | 287 | #ifdef SHOW_TRACK_COUNT | 
 | 288 | 	count_untracked++; | 
 | 289 | #endif | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 290 | #ifdef SHOW_CONVERSION_COUNTS | 
 | 291 | 	++created; | 
 | 292 | #endif | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 293 | 	return (PyObject *)mp; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 294 | } | 
 | 295 |  | 
 | 296 | /* | 
 | 297 | The basic lookup function used by all operations. | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 298 | This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4. | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 299 | Open addressing is preferred over chaining since the link overhead for | 
 | 300 | chaining would be substantial (100% with typical malloc overhead). | 
 | 301 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 302 | The initial probe index is computed as hash mod the table size. Subsequent | 
 | 303 | probe indices are computed as explained earlier. | 
| Guido van Rossum | 2bc1379 | 1999-03-24 19:06:42 +0000 | [diff] [blame] | 304 |  | 
 | 305 | All arithmetic on hash should ignore overflow. | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 306 |  | 
| Guido van Rossum | dc5f6b2 | 2006-08-24 21:29:26 +0000 | [diff] [blame] | 307 | The details in this version are due to Tim Peters, building on many past | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 308 | contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and | 
| Guido van Rossum | dc5f6b2 | 2006-08-24 21:29:26 +0000 | [diff] [blame] | 309 | Christian Tismer. | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 310 |  | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 311 | lookdict() is general-purpose, and may return NULL if (and only if) a | 
 | 312 | comparison raises an exception (this was new in Python 2.5). | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 313 | lookdict_unicode() below is specialized to string keys, comparison of which can | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 314 | never raise an exception; that function can never return NULL.  For both, when | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 315 | the key isn't found a PyDictEntry* is returned for which the me_value field is | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 316 | NULL; this is the slot in the dict at which the key would have been found, and | 
 | 317 | the caller can (if it wishes) add the <key, value> pair to the returned | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 318 | PyDictEntry*. | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 319 | */ | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 320 | static PyDictEntry * | 
 | 321 | lookdict(PyDictObject *mp, PyObject *key, register long hash) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 322 | { | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 323 | 	register size_t i; | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 324 | 	register size_t perturb; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 325 | 	register PyDictEntry *freeslot; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 326 | 	register size_t mask = (size_t)mp->ma_mask; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 327 | 	PyDictEntry *ep0 = mp->ma_table; | 
 | 328 | 	register PyDictEntry *ep; | 
| Fred Drake | c88b99c | 2000-08-31 19:04:07 +0000 | [diff] [blame] | 329 | 	register int cmp; | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 330 | 	PyObject *startkey; | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 331 |  | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 332 | 	i = (size_t)hash & mask; | 
| Guido van Rossum | efb4609 | 1997-01-29 15:53:56 +0000 | [diff] [blame] | 333 | 	ep = &ep0[i]; | 
| Guido van Rossum | c1c7b1a | 1998-10-06 16:01:14 +0000 | [diff] [blame] | 334 | 	if (ep->me_key == NULL || ep->me_key == key) | 
| Guido van Rossum | 7d18159 | 1997-01-16 21:06:45 +0000 | [diff] [blame] | 335 | 		return ep; | 
| Tim Peters | 7b5d0af | 2001-06-03 04:14:43 +0000 | [diff] [blame] | 336 |  | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 337 | 	if (ep->me_key == dummy) | 
| Guido van Rossum | 7d18159 | 1997-01-16 21:06:45 +0000 | [diff] [blame] | 338 | 		freeslot = ep; | 
| Guido van Rossum | fd7a0b8 | 1997-08-18 21:52:47 +0000 | [diff] [blame] | 339 | 	else { | 
| Fred Drake | c88b99c | 2000-08-31 19:04:07 +0000 | [diff] [blame] | 340 | 		if (ep->me_hash == hash) { | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 341 | 			startkey = ep->me_key; | 
| Guido van Rossum | 2fd4f37 | 2007-11-29 18:43:05 +0000 | [diff] [blame] | 342 | 			Py_INCREF(startkey); | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 343 | 			cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); | 
| Guido van Rossum | 2fd4f37 | 2007-11-29 18:43:05 +0000 | [diff] [blame] | 344 | 			Py_DECREF(startkey); | 
| Tim Peters | 7b5d0af | 2001-06-03 04:14:43 +0000 | [diff] [blame] | 345 | 			if (cmp < 0) | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 346 | 				return NULL; | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 347 | 			if (ep0 == mp->ma_table && ep->me_key == startkey) { | 
 | 348 | 				if (cmp > 0) | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 349 | 					return ep; | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 350 | 			} | 
 | 351 | 			else { | 
 | 352 | 				/* The compare did major nasty stuff to the | 
 | 353 | 				 * dict:  start over. | 
 | 354 | 				 * XXX A clever adversary could prevent this | 
 | 355 | 				 * XXX from terminating. | 
 | 356 |  				 */ | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 357 |  				return lookdict(mp, key, hash); | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 358 |  			} | 
| Guido van Rossum | fd7a0b8 | 1997-08-18 21:52:47 +0000 | [diff] [blame] | 359 | 		} | 
 | 360 | 		freeslot = NULL; | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 361 | 	} | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 362 |  | 
| Tim Peters | 342c65e | 2001-05-13 06:43:53 +0000 | [diff] [blame] | 363 | 	/* In the loop, me_key == dummy is by far (factor of 100s) the | 
 | 364 | 	   least likely outcome, so test for that last. */ | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 365 | 	for (perturb = hash; ; perturb >>= PERTURB_SHIFT) { | 
 | 366 | 		i = (i << 2) + i + perturb + 1; | 
 | 367 | 		ep = &ep0[i & mask]; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 368 | 		if (ep->me_key == NULL) | 
 | 369 | 			return freeslot == NULL ? ep : freeslot; | 
| Tim Peters | 7b5d0af | 2001-06-03 04:14:43 +0000 | [diff] [blame] | 370 | 		if (ep->me_key == key) | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 371 | 			return ep; | 
| Tim Peters | 7b5d0af | 2001-06-03 04:14:43 +0000 | [diff] [blame] | 372 | 		if (ep->me_hash == hash && ep->me_key != dummy) { | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 373 | 			startkey = ep->me_key; | 
| Guido van Rossum | 2fd4f37 | 2007-11-29 18:43:05 +0000 | [diff] [blame] | 374 | 			Py_INCREF(startkey); | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 375 | 			cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); | 
| Guido van Rossum | 2fd4f37 | 2007-11-29 18:43:05 +0000 | [diff] [blame] | 376 | 			Py_DECREF(startkey); | 
| Tim Peters | 7b5d0af | 2001-06-03 04:14:43 +0000 | [diff] [blame] | 377 | 			if (cmp < 0) | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 378 | 				return NULL; | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 379 | 			if (ep0 == mp->ma_table && ep->me_key == startkey) { | 
 | 380 | 				if (cmp > 0) | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 381 | 					return ep; | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 382 | 			} | 
 | 383 | 			else { | 
 | 384 | 				/* The compare did major nasty stuff to the | 
 | 385 | 				 * dict:  start over. | 
 | 386 | 				 * XXX A clever adversary could prevent this | 
 | 387 | 				 * XXX from terminating. | 
 | 388 |  				 */ | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 389 |  				return lookdict(mp, key, hash); | 
| Tim Peters | 453163d | 2001-06-03 04:54:32 +0000 | [diff] [blame] | 390 |  			} | 
| Guido van Rossum | 16e93a8 | 1997-01-28 00:00:11 +0000 | [diff] [blame] | 391 | 		} | 
| Tim Peters | 342c65e | 2001-05-13 06:43:53 +0000 | [diff] [blame] | 392 | 		else if (ep->me_key == dummy && freeslot == NULL) | 
 | 393 | 			freeslot = ep; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 394 | 	} | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 395 | 	assert(0);	/* NOT REACHED */ | 
 | 396 | 	return 0; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 397 | } | 
 | 398 |  | 
 | 399 | /* | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 400 |  * Hacked up version of lookdict which can assume keys are always | 
 | 401 |  * unicodes; this assumption allows testing for errors during | 
 | 402 |  * PyObject_RichCompareBool() to be dropped; unicode-unicode | 
 | 403 |  * comparisons never raise exceptions.  This also means we don't need | 
 | 404 |  * to go through PyObject_RichCompareBool(); we can always use | 
 | 405 |  * unicode_eq() directly. | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 406 |  * | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 407 |  * This is valuable because dicts with only unicode keys are very common. | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 408 |  */ | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 409 | static PyDictEntry * | 
 | 410 | lookdict_unicode(PyDictObject *mp, PyObject *key, register long hash) | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 411 | { | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 412 | 	register size_t i; | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 413 | 	register size_t perturb; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 414 | 	register PyDictEntry *freeslot; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 415 | 	register size_t mask = (size_t)mp->ma_mask; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 416 | 	PyDictEntry *ep0 = mp->ma_table; | 
 | 417 | 	register PyDictEntry *ep; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 418 |  | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 419 | 	/* Make sure this function doesn't have to handle non-unicode keys, | 
| Tim Peters | 0ab085c | 2001-09-14 00:25:33 +0000 | [diff] [blame] | 420 | 	   including subclasses of str; e.g., one reason to subclass | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 421 | 	   unicodes is to override __eq__, and for speed we don't cater to | 
| Tim Peters | 0ab085c | 2001-09-14 00:25:33 +0000 | [diff] [blame] | 422 | 	   that here. */ | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 423 | 	if (!PyUnicode_CheckExact(key)) { | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 424 | #ifdef SHOW_CONVERSION_COUNTS | 
 | 425 | 		++converted; | 
 | 426 | #endif | 
 | 427 | 		mp->ma_lookup = lookdict; | 
 | 428 | 		return lookdict(mp, key, hash); | 
 | 429 | 	} | 
| Tim Peters | 2f228e7 | 2001-05-13 00:19:31 +0000 | [diff] [blame] | 430 | 	i = hash & mask; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 431 | 	ep = &ep0[i]; | 
 | 432 | 	if (ep->me_key == NULL || ep->me_key == key) | 
 | 433 | 		return ep; | 
 | 434 | 	if (ep->me_key == dummy) | 
 | 435 | 		freeslot = ep; | 
 | 436 | 	else { | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 437 | 		if (ep->me_hash == hash && unicode_eq(ep->me_key, key)) | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 438 | 			return ep; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 439 | 		freeslot = NULL; | 
 | 440 | 	} | 
| Tim Peters | 15d4929 | 2001-05-27 07:39:22 +0000 | [diff] [blame] | 441 |  | 
| Tim Peters | 342c65e | 2001-05-13 06:43:53 +0000 | [diff] [blame] | 442 | 	/* In the loop, me_key == dummy is by far (factor of 100s) the | 
 | 443 | 	   least likely outcome, so test for that last. */ | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 444 | 	for (perturb = hash; ; perturb >>= PERTURB_SHIFT) { | 
 | 445 | 		i = (i << 2) + i + perturb + 1; | 
 | 446 | 		ep = &ep0[i & mask]; | 
| Tim Peters | 342c65e | 2001-05-13 06:43:53 +0000 | [diff] [blame] | 447 | 		if (ep->me_key == NULL) | 
 | 448 | 			return freeslot == NULL ? ep : freeslot; | 
 | 449 | 		if (ep->me_key == key | 
 | 450 | 		    || (ep->me_hash == hash | 
 | 451 | 		        && ep->me_key != dummy | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 452 | 			&& unicode_eq(ep->me_key, key))) | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 453 | 			return ep; | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 454 | 		if (ep->me_key == dummy && freeslot == NULL) | 
| Tim Peters | 342c65e | 2001-05-13 06:43:53 +0000 | [diff] [blame] | 455 | 			freeslot = ep; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 456 | 	} | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 457 | 	assert(0);	/* NOT REACHED */ | 
 | 458 | 	return 0; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 459 | } | 
 | 460 |  | 
| Antoine Pitrou | 3a652b1 | 2009-03-23 18:52:06 +0000 | [diff] [blame] | 461 | #ifdef SHOW_TRACK_COUNT | 
 | 462 | #define INCREASE_TRACK_COUNT \ | 
 | 463 | 	(count_tracked++, count_untracked--); | 
 | 464 | #define DECREASE_TRACK_COUNT \ | 
 | 465 | 	(count_tracked--, count_untracked++); | 
 | 466 | #else | 
 | 467 | #define INCREASE_TRACK_COUNT | 
 | 468 | #define DECREASE_TRACK_COUNT | 
 | 469 | #endif | 
 | 470 |  | 
 | 471 | #define MAINTAIN_TRACKING(mp, key, value) \ | 
 | 472 | 	do { \ | 
 | 473 | 		if (!_PyObject_GC_IS_TRACKED(mp)) { \ | 
 | 474 | 			if (_PyObject_GC_MAY_BE_TRACKED(key) || \ | 
 | 475 | 				_PyObject_GC_MAY_BE_TRACKED(value)) { \ | 
 | 476 | 				_PyObject_GC_TRACK(mp); \ | 
 | 477 | 				INCREASE_TRACK_COUNT \ | 
 | 478 | 			} \ | 
 | 479 | 		} \ | 
 | 480 | 	} while(0) | 
 | 481 |  | 
 | 482 | void | 
 | 483 | _PyDict_MaybeUntrack(PyObject *op) | 
 | 484 | { | 
 | 485 | 	PyDictObject *mp; | 
 | 486 | 	PyObject *value; | 
 | 487 | 	Py_ssize_t mask, i; | 
 | 488 | 	PyDictEntry *ep; | 
 | 489 |  | 
 | 490 | 	if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op)) | 
 | 491 | 		return; | 
 | 492 | 	 | 
 | 493 | 	mp = (PyDictObject *) op; | 
 | 494 | 	ep = mp->ma_table; | 
 | 495 | 	mask = mp->ma_mask; | 
 | 496 | 	for (i = 0; i <= mask; i++) { | 
 | 497 | 		if ((value = ep[i].me_value) == NULL) | 
 | 498 | 			continue; | 
 | 499 | 		if (_PyObject_GC_MAY_BE_TRACKED(value) || | 
 | 500 | 			_PyObject_GC_MAY_BE_TRACKED(ep[i].me_key)) | 
 | 501 | 			return; | 
 | 502 | 	} | 
| Antoine Pitrou | acc5d6b | 2009-03-23 19:19:54 +0000 | [diff] [blame] | 503 | 	DECREASE_TRACK_COUNT | 
| Antoine Pitrou | 3a652b1 | 2009-03-23 18:52:06 +0000 | [diff] [blame] | 504 | 	_PyObject_GC_UNTRACK(op); | 
 | 505 | } | 
 | 506 |  | 
 | 507 |  | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 508 | /* | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 509 | Internal routine to insert a new item into the table. | 
 | 510 | Used both by the internal resize routine and by the public insert routine. | 
 | 511 | Eats a reference to key and one to value. | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 512 | Returns -1 if an error occurred, or 0 on success. | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 513 | */ | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 514 | static int | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 515 | insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 516 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 517 | 	PyObject *old_value; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 518 | 	register PyDictEntry *ep; | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 519 | 	typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long); | 
 | 520 |  | 
 | 521 | 	assert(mp->ma_lookup != NULL); | 
 | 522 | 	ep = mp->ma_lookup(mp, key, hash); | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 523 | 	if (ep == NULL) { | 
 | 524 | 		Py_DECREF(key); | 
 | 525 | 		Py_DECREF(value); | 
 | 526 | 		return -1; | 
 | 527 | 	} | 
| Antoine Pitrou | 3a652b1 | 2009-03-23 18:52:06 +0000 | [diff] [blame] | 528 | 	MAINTAIN_TRACKING(mp, key, value); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 529 | 	if (ep->me_value != NULL) { | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 530 | 		old_value = ep->me_value; | 
 | 531 | 		ep->me_value = value; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 532 | 		Py_DECREF(old_value); /* which **CAN** re-enter */ | 
 | 533 | 		Py_DECREF(key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 534 | 	} | 
 | 535 | 	else { | 
 | 536 | 		if (ep->me_key == NULL) | 
 | 537 | 			mp->ma_fill++; | 
| Raymond Hettinger | 07ead17 | 2005-02-05 23:42:57 +0000 | [diff] [blame] | 538 | 		else { | 
 | 539 | 			assert(ep->me_key == dummy); | 
 | 540 | 			Py_DECREF(dummy); | 
 | 541 | 		} | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 542 | 		ep->me_key = key; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 543 | 		ep->me_hash = (Py_ssize_t)hash; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 544 | 		ep->me_value = value; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 545 | 		mp->ma_used++; | 
 | 546 | 	} | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 547 | 	return 0; | 
 | 548 | } | 
 | 549 |  | 
 | 550 | /* | 
 | 551 | Internal routine used by dictresize() to insert an item which is | 
 | 552 | known to be absent from the dict.  This routine also assumes that | 
 | 553 | the dict contains no deleted entries.  Besides the performance benefit, | 
 | 554 | using insertdict() in dictresize() is dangerous (SF bug #1456209). | 
 | 555 | Note that no refcounts are changed by this routine; if needed, the caller | 
 | 556 | is responsible for incref'ing `key` and `value`. | 
 | 557 | */ | 
 | 558 | static void | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 559 | insertdict_clean(register PyDictObject *mp, PyObject *key, long hash, | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 560 | 		 PyObject *value) | 
 | 561 | { | 
 | 562 | 	register size_t i; | 
 | 563 | 	register size_t perturb; | 
 | 564 | 	register size_t mask = (size_t)mp->ma_mask; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 565 | 	PyDictEntry *ep0 = mp->ma_table; | 
 | 566 | 	register PyDictEntry *ep; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 567 |  | 
| Antoine Pitrou | 3a652b1 | 2009-03-23 18:52:06 +0000 | [diff] [blame] | 568 | 	MAINTAIN_TRACKING(mp, key, value); | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 569 | 	i = hash & mask; | 
 | 570 | 	ep = &ep0[i]; | 
 | 571 | 	for (perturb = hash; ep->me_key != NULL; perturb >>= PERTURB_SHIFT) { | 
 | 572 | 		i = (i << 2) + i + perturb + 1; | 
 | 573 | 		ep = &ep0[i & mask]; | 
 | 574 | 	} | 
 | 575 | 	assert(ep->me_value == NULL); | 
 | 576 | 	mp->ma_fill++; | 
 | 577 | 	ep->me_key = key; | 
 | 578 | 	ep->me_hash = (Py_ssize_t)hash; | 
 | 579 | 	ep->me_value = value; | 
 | 580 | 	mp->ma_used++; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 581 | } | 
 | 582 |  | 
 | 583 | /* | 
 | 584 | Restructure the table by allocating a new table and reinserting all | 
 | 585 | items again.  When entries have been deleted, the new table may | 
 | 586 | actually be smaller than the old one. | 
 | 587 | */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 588 | static int | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 589 | dictresize(PyDictObject *mp, Py_ssize_t minused) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 590 | { | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 591 | 	Py_ssize_t newsize; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 592 | 	PyDictEntry *oldtable, *newtable, *ep; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 593 | 	Py_ssize_t i; | 
| Tim Peters | 0c6010b | 2001-05-23 23:33:57 +0000 | [diff] [blame] | 594 | 	int is_oldtable_malloced; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 595 | 	PyDictEntry small_copy[PyDict_MINSIZE]; | 
| Tim Peters | 91a364d | 2001-05-19 07:04:38 +0000 | [diff] [blame] | 596 |  | 
 | 597 | 	assert(minused >= 0); | 
| Tim Peters | 0c6010b | 2001-05-23 23:33:57 +0000 | [diff] [blame] | 598 |  | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 599 | 	/* Find the smallest table size > minused. */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 600 | 	for (newsize = PyDict_MINSIZE; | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 601 | 	     newsize <= minused && newsize > 0; | 
 | 602 | 	     newsize <<= 1) | 
 | 603 | 		; | 
 | 604 | 	if (newsize <= 0) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 605 | 		PyErr_NoMemory(); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 606 | 		return -1; | 
 | 607 | 	} | 
| Tim Peters | 0c6010b | 2001-05-23 23:33:57 +0000 | [diff] [blame] | 608 |  | 
 | 609 | 	/* Get space for a new table. */ | 
 | 610 | 	oldtable = mp->ma_table; | 
 | 611 | 	assert(oldtable != NULL); | 
 | 612 | 	is_oldtable_malloced = oldtable != mp->ma_smalltable; | 
 | 613 |  | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 614 | 	if (newsize == PyDict_MINSIZE) { | 
| Tim Peters | f8a548c | 2001-05-24 16:26:40 +0000 | [diff] [blame] | 615 | 		/* A large table is shrinking, or we can't get any smaller. */ | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 616 | 		newtable = mp->ma_smalltable; | 
| Tim Peters | 0c6010b | 2001-05-23 23:33:57 +0000 | [diff] [blame] | 617 | 		if (newtable == oldtable) { | 
| Tim Peters | f8a548c | 2001-05-24 16:26:40 +0000 | [diff] [blame] | 618 | 			if (mp->ma_fill == mp->ma_used) { | 
 | 619 | 				/* No dummies, so no point doing anything. */ | 
| Tim Peters | 0c6010b | 2001-05-23 23:33:57 +0000 | [diff] [blame] | 620 | 				return 0; | 
| Tim Peters | f8a548c | 2001-05-24 16:26:40 +0000 | [diff] [blame] | 621 | 			} | 
 | 622 | 			/* We're not going to resize it, but rebuild the | 
 | 623 | 			   table anyway to purge old dummy entries. | 
 | 624 | 			   Subtle:  This is *necessary* if fill==size, | 
 | 625 | 			   as lookdict needs at least one virgin slot to | 
 | 626 | 			   terminate failing searches.  If fill < size, it's | 
 | 627 | 			   merely desirable, as dummies slow searches. */ | 
 | 628 | 			assert(mp->ma_fill > mp->ma_used); | 
| Tim Peters | 0c6010b | 2001-05-23 23:33:57 +0000 | [diff] [blame] | 629 | 			memcpy(small_copy, oldtable, sizeof(small_copy)); | 
 | 630 | 			oldtable = small_copy; | 
 | 631 | 		} | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 632 | 	} | 
 | 633 | 	else { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 634 | 		newtable = PyMem_NEW(PyDictEntry, newsize); | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 635 | 		if (newtable == NULL) { | 
 | 636 | 			PyErr_NoMemory(); | 
 | 637 | 			return -1; | 
 | 638 | 		} | 
 | 639 | 	} | 
| Tim Peters | 0c6010b | 2001-05-23 23:33:57 +0000 | [diff] [blame] | 640 |  | 
 | 641 | 	/* Make the dict empty, using the new table. */ | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 642 | 	assert(newtable != oldtable); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 643 | 	mp->ma_table = newtable; | 
| Tim Peters | afb6ae8 | 2001-06-04 21:00:21 +0000 | [diff] [blame] | 644 | 	mp->ma_mask = newsize - 1; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 645 | 	memset(newtable, 0, sizeof(PyDictEntry) * newsize); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 646 | 	mp->ma_used = 0; | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 647 | 	i = mp->ma_fill; | 
 | 648 | 	mp->ma_fill = 0; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 649 |  | 
| Tim Peters | 1928314 | 2001-05-17 22:25:34 +0000 | [diff] [blame] | 650 | 	/* Copy the data over; this is refcount-neutral for active entries; | 
 | 651 | 	   dummy entries aren't copied over, of course */ | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 652 | 	for (ep = oldtable; i > 0; ep++) { | 
 | 653 | 		if (ep->me_value != NULL) {	/* active entry */ | 
 | 654 | 			--i; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 655 | 			insertdict_clean(mp, ep->me_key, (long)ep->me_hash, | 
 | 656 | 					 ep->me_value); | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 657 | 		} | 
| Tim Peters | 1928314 | 2001-05-17 22:25:34 +0000 | [diff] [blame] | 658 | 		else if (ep->me_key != NULL) {	/* dummy entry */ | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 659 | 			--i; | 
| Tim Peters | 1928314 | 2001-05-17 22:25:34 +0000 | [diff] [blame] | 660 | 			assert(ep->me_key == dummy); | 
 | 661 | 			Py_DECREF(ep->me_key); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 662 | 		} | 
| Tim Peters | 1928314 | 2001-05-17 22:25:34 +0000 | [diff] [blame] | 663 | 		/* else key == value == NULL:  nothing to do */ | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 664 | 	} | 
 | 665 |  | 
| Tim Peters | 0c6010b | 2001-05-23 23:33:57 +0000 | [diff] [blame] | 666 | 	if (is_oldtable_malloced) | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 667 | 		PyMem_DEL(oldtable); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 668 | 	return 0; | 
 | 669 | } | 
 | 670 |  | 
| Christian Heimes | 99170a5 | 2007-12-19 02:07:34 +0000 | [diff] [blame] | 671 | /* Create a new dictionary pre-sized to hold an estimated number of elements. | 
 | 672 |    Underestimates are okay because the dictionary will resize as necessary. | 
 | 673 |    Overestimates just mean the dictionary will be more sparse than usual. | 
 | 674 | */ | 
 | 675 |  | 
 | 676 | PyObject * | 
 | 677 | _PyDict_NewPresized(Py_ssize_t minused) | 
 | 678 | { | 
 | 679 | 	PyObject *op = PyDict_New(); | 
 | 680 |  | 
 | 681 | 	if (minused>5 && op != NULL && dictresize((PyDictObject *)op, minused) == -1) { | 
 | 682 | 		Py_DECREF(op); | 
 | 683 | 		return NULL; | 
 | 684 | 	} | 
 | 685 | 	return op; | 
 | 686 | } | 
 | 687 |  | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 688 | /* Note that, for historical reasons, PyDict_GetItem() suppresses all errors | 
 | 689 |  * that may occur (originally dicts supported only string keys, and exceptions | 
 | 690 |  * weren't possible).  So, while the original intent was that a NULL return | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 691 |  * meant the key wasn't present, in reality it can mean that, or that an error | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 692 |  * (suppressed) occurred while computing the key's hash, or that some error | 
 | 693 |  * (suppressed) occurred when comparing keys in the dict's internal probe | 
 | 694 |  * sequence.  A nasty example of the latter is when a Python-coded comparison | 
 | 695 |  * function hits a stack-depth error, which can cause this to return NULL | 
 | 696 |  * even if the key is present. | 
 | 697 |  */ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 698 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 699 | PyDict_GetItem(PyObject *op, PyObject *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 700 | { | 
 | 701 | 	long hash; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 702 | 	PyDictObject *mp = (PyDictObject *)op; | 
 | 703 | 	PyDictEntry *ep; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 704 | 	PyThreadState *tstate; | 
 | 705 | 	if (!PyDict_Check(op)) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 706 | 		return NULL; | 
| Guido van Rossum | 4d02772 | 2007-09-18 04:30:42 +0000 | [diff] [blame] | 707 | 	if (!PyUnicode_CheckExact(key) || | 
 | 708 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 709 | 	{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 710 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | 474b19e | 1998-05-14 01:00:51 +0000 | [diff] [blame] | 711 | 		if (hash == -1) { | 
 | 712 | 			PyErr_Clear(); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 713 | 			return NULL; | 
| Guido van Rossum | 474b19e | 1998-05-14 01:00:51 +0000 | [diff] [blame] | 714 | 		} | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 715 | 	} | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 716 |  | 
 | 717 | 	/* We can arrive here with a NULL tstate during initialization: | 
 | 718 | 	   try running "python -Wi" for an example related to string | 
 | 719 | 	   interning.  Let's just hope that no exception occurs then... */ | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 720 | 	tstate = _PyThreadState_Current; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 721 | 	if (tstate != NULL && tstate->curexc_type != NULL) { | 
 | 722 | 		/* preserve the existing exception */ | 
 | 723 | 		PyObject *err_type, *err_value, *err_tb; | 
 | 724 | 		PyErr_Fetch(&err_type, &err_value, &err_tb); | 
 | 725 | 		ep = (mp->ma_lookup)(mp, key, hash); | 
 | 726 | 		/* ignore errors */ | 
 | 727 | 		PyErr_Restore(err_type, err_value, err_tb); | 
 | 728 | 		if (ep == NULL) | 
 | 729 | 			return NULL; | 
 | 730 | 	} | 
 | 731 | 	else { | 
 | 732 | 		ep = (mp->ma_lookup)(mp, key, hash); | 
 | 733 | 		if (ep == NULL) { | 
 | 734 | 			PyErr_Clear(); | 
 | 735 | 			return NULL; | 
 | 736 | 		} | 
 | 737 | 	} | 
 | 738 | 	return ep->me_value; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 739 | } | 
 | 740 |  | 
| Guido van Rossum | 47b9ff6 | 2006-08-24 00:41:19 +0000 | [diff] [blame] | 741 | /* Variant of PyDict_GetItem() that doesn't suppress exceptions. | 
 | 742 |    This returns NULL *with* an exception set if an exception occurred. | 
 | 743 |    It returns NULL *without* an exception set if the key wasn't present. | 
 | 744 | */ | 
 | 745 | PyObject * | 
 | 746 | PyDict_GetItemWithError(PyObject *op, PyObject *key) | 
 | 747 | { | 
 | 748 | 	long hash; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 749 |         PyDictObject*mp = (PyDictObject *)op; | 
 | 750 | 	PyDictEntry *ep; | 
| Guido van Rossum | 47b9ff6 | 2006-08-24 00:41:19 +0000 | [diff] [blame] | 751 |  | 
 | 752 | 	if (!PyDict_Check(op)) { | 
 | 753 | 		PyErr_BadInternalCall(); | 
 | 754 | 		return NULL; | 
 | 755 | 	} | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 756 | 	if (!PyUnicode_CheckExact(key) || | 
 | 757 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) | 
| Guido van Rossum | 47b9ff6 | 2006-08-24 00:41:19 +0000 | [diff] [blame] | 758 | 	{ | 
 | 759 | 		hash = PyObject_Hash(key); | 
 | 760 | 		if (hash == -1) { | 
 | 761 | 			return NULL; | 
 | 762 | 		} | 
 | 763 | 	} | 
 | 764 |  | 
 | 765 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
 | 766 | 	if (ep == NULL) | 
 | 767 | 		return NULL; | 
 | 768 | 	return ep->me_value; | 
 | 769 | } | 
 | 770 |  | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 771 | /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the | 
| Tim Peters | 60b2996 | 2006-01-01 01:19:23 +0000 | [diff] [blame] | 772 |  * dictionary if it's merely replacing the value for an existing key. | 
 | 773 |  * This means that it's safe to loop over a dictionary with PyDict_Next() | 
 | 774 |  * and occasionally replace a value -- but you can't insert new keys or | 
 | 775 |  * remove them. | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 776 |  */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 777 | int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 778 | PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 779 | { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 780 | 	register PyDictObject *mp; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 781 | 	register long hash; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 782 | 	register Py_ssize_t n_used; | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 783 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 784 | 	if (!PyDict_Check(op)) { | 
 | 785 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 786 | 		return -1; | 
 | 787 | 	} | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 788 | 	assert(key); | 
 | 789 | 	assert(value); | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 790 | 	mp = (PyDictObject *)op; | 
| Guido van Rossum | 4d02772 | 2007-09-18 04:30:42 +0000 | [diff] [blame] | 791 | 	if (!PyUnicode_CheckExact(key) || | 
 | 792 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) | 
 | 793 | 	{ | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 794 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 795 | 		if (hash == -1) | 
 | 796 | 			return -1; | 
| Guido van Rossum | 2a61e74 | 1997-01-18 07:55:05 +0000 | [diff] [blame] | 797 | 	} | 
| Tim Peters | afb6ae8 | 2001-06-04 21:00:21 +0000 | [diff] [blame] | 798 | 	assert(mp->ma_fill <= mp->ma_mask);  /* at least one empty slot */ | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 799 | 	n_used = mp->ma_used; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 800 | 	Py_INCREF(value); | 
 | 801 | 	Py_INCREF(key); | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 802 | 	if (insertdict(mp, key, hash, value) != 0) | 
 | 803 | 		return -1; | 
| Raymond Hettinger | 3539f6b | 2003-05-05 22:22:10 +0000 | [diff] [blame] | 804 | 	/* If we added a key, we can safely resize.  Otherwise just return! | 
 | 805 | 	 * If fill >= 2/3 size, adjust size.  Normally, this doubles or | 
 | 806 | 	 * quaduples the size, but it's also possible for the dict to shrink | 
| Tim Peters | 60b2996 | 2006-01-01 01:19:23 +0000 | [diff] [blame] | 807 | 	 * (if ma_fill is much larger than ma_used, meaning a lot of dict | 
| Raymond Hettinger | 3539f6b | 2003-05-05 22:22:10 +0000 | [diff] [blame] | 808 | 	 * keys have been * deleted). | 
| Tim Peters | 60b2996 | 2006-01-01 01:19:23 +0000 | [diff] [blame] | 809 | 	 * | 
| Raymond Hettinger | 3539f6b | 2003-05-05 22:22:10 +0000 | [diff] [blame] | 810 | 	 * Quadrupling the size improves average dictionary sparseness | 
 | 811 | 	 * (reducing collisions) at the cost of some memory and iteration | 
 | 812 | 	 * speed (which loops over every possible entry).  It also halves | 
 | 813 | 	 * the number of expensive resize operations in a growing dictionary. | 
| Tim Peters | 60b2996 | 2006-01-01 01:19:23 +0000 | [diff] [blame] | 814 | 	 * | 
 | 815 | 	 * Very large dictionaries (over 50K items) use doubling instead. | 
| Raymond Hettinger | 3539f6b | 2003-05-05 22:22:10 +0000 | [diff] [blame] | 816 | 	 * This may help applications with severe memory constraints. | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 817 | 	 */ | 
| Raymond Hettinger | 3539f6b | 2003-05-05 22:22:10 +0000 | [diff] [blame] | 818 | 	if (!(mp->ma_used > n_used && mp->ma_fill*3 >= (mp->ma_mask+1)*2)) | 
 | 819 | 		return 0; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 820 | 	return dictresize(mp, (mp->ma_used > 50000 ? 2 : 4) * mp->ma_used); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 821 | } | 
 | 822 |  | 
 | 823 | int | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 824 | PyDict_DelItem(PyObject *op, PyObject *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 825 | { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 826 | 	register PyDictObject *mp; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 827 | 	register long hash; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 828 | 	register PyDictEntry *ep; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 829 | 	PyObject *old_value, *old_key; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 830 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 831 | 	if (!PyDict_Check(op)) { | 
 | 832 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 833 | 		return -1; | 
 | 834 | 	} | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 835 | 	assert(key); | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 836 | 	if (!PyUnicode_CheckExact(key) || | 
 | 837 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 838 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 839 | 		if (hash == -1) | 
 | 840 | 			return -1; | 
 | 841 | 	} | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 842 | 	mp = (PyDictObject *)op; | 
| Fred Drake | 1bff34a | 2000-08-31 19:31:38 +0000 | [diff] [blame] | 843 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 844 | 	if (ep == NULL) | 
 | 845 | 		return -1; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 846 | 	if (ep->me_value == NULL) { | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 847 | 		set_key_error(key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 848 | 		return -1; | 
 | 849 | 	} | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 850 | 	old_key = ep->me_key; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 851 | 	Py_INCREF(dummy); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 852 | 	ep->me_key = dummy; | 
| Guido van Rossum | d7047b3 | 1995-01-02 19:07:15 +0000 | [diff] [blame] | 853 | 	old_value = ep->me_value; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 854 | 	ep->me_value = NULL; | 
 | 855 | 	mp->ma_used--; | 
| Tim Peters | ea8f2bf | 2000-12-13 01:02:46 +0000 | [diff] [blame] | 856 | 	Py_DECREF(old_value); | 
 | 857 | 	Py_DECREF(old_key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 858 | 	return 0; | 
 | 859 | } | 
 | 860 |  | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 861 | void | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 862 | PyDict_Clear(PyObject *op) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 863 | { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 864 | 	PyDictObject *mp; | 
 | 865 | 	PyDictEntry *ep, *table; | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 866 | 	int table_is_malloced; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 867 | 	Py_ssize_t fill; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 868 | 	PyDictEntry small_copy[PyDict_MINSIZE]; | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 869 | #ifdef Py_DEBUG | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 870 | 	Py_ssize_t i, n; | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 871 | #endif | 
 | 872 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 873 | 	if (!PyDict_Check(op)) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 874 | 		return; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 875 | 	mp = (PyDictObject *)op; | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 876 | #ifdef Py_DEBUG | 
| Tim Peters | afb6ae8 | 2001-06-04 21:00:21 +0000 | [diff] [blame] | 877 | 	n = mp->ma_mask + 1; | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 878 | 	i = 0; | 
 | 879 | #endif | 
 | 880 |  | 
 | 881 | 	table = mp->ma_table; | 
 | 882 | 	assert(table != NULL); | 
 | 883 | 	table_is_malloced = table != mp->ma_smalltable; | 
 | 884 |  | 
 | 885 | 	/* This is delicate.  During the process of clearing the dict, | 
 | 886 | 	 * decrefs can cause the dict to mutate.  To avoid fatal confusion | 
 | 887 | 	 * (voice of experience), we have to make the dict empty before | 
 | 888 | 	 * clearing the slots, and never refer to anything via mp->xxx while | 
 | 889 | 	 * clearing. | 
 | 890 | 	 */ | 
 | 891 | 	fill = mp->ma_fill; | 
 | 892 | 	if (table_is_malloced) | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 893 | 		EMPTY_TO_MINSIZE(mp); | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 894 |  | 
 | 895 | 	else if (fill > 0) { | 
 | 896 | 		/* It's a small table with something that needs to be cleared. | 
 | 897 | 		 * Afraid the only safe way is to copy the dict entries into | 
 | 898 | 		 * another small table first. | 
 | 899 | 		 */ | 
 | 900 | 		memcpy(small_copy, table, sizeof(small_copy)); | 
 | 901 | 		table = small_copy; | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 902 | 		EMPTY_TO_MINSIZE(mp); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 903 | 	} | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 904 | 	/* else it's a small table that's already empty */ | 
 | 905 |  | 
 | 906 | 	/* Now we can finally clear things.  If C had refcounts, we could | 
 | 907 | 	 * assert that the refcount on table is 1 now, i.e. that this function | 
 | 908 | 	 * has unique access to it, so decref side-effects can't alter it. | 
 | 909 | 	 */ | 
 | 910 | 	for (ep = table; fill > 0; ++ep) { | 
 | 911 | #ifdef Py_DEBUG | 
 | 912 | 		assert(i < n); | 
 | 913 | 		++i; | 
 | 914 | #endif | 
 | 915 | 		if (ep->me_key) { | 
 | 916 | 			--fill; | 
 | 917 | 			Py_DECREF(ep->me_key); | 
 | 918 | 			Py_XDECREF(ep->me_value); | 
 | 919 | 		} | 
 | 920 | #ifdef Py_DEBUG | 
 | 921 | 		else | 
 | 922 | 			assert(ep->me_value == NULL); | 
 | 923 | #endif | 
 | 924 | 	} | 
 | 925 |  | 
 | 926 | 	if (table_is_malloced) | 
 | 927 | 		PyMem_DEL(table); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 928 | } | 
 | 929 |  | 
| Tim Peters | 080c88b | 2003-02-15 03:01:11 +0000 | [diff] [blame] | 930 | /* | 
 | 931 |  * Iterate over a dict.  Use like so: | 
 | 932 |  * | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 933 |  *     Py_ssize_t i; | 
| Tim Peters | 080c88b | 2003-02-15 03:01:11 +0000 | [diff] [blame] | 934 |  *     PyObject *key, *value; | 
 | 935 |  *     i = 0;   # important!  i should not otherwise be changed by you | 
| Neal Norwitz | 0732301 | 2003-02-15 14:45:12 +0000 | [diff] [blame] | 936 |  *     while (PyDict_Next(yourdict, &i, &key, &value)) { | 
| Tim Peters | 080c88b | 2003-02-15 03:01:11 +0000 | [diff] [blame] | 937 |  *              Refer to borrowed references in key and value. | 
 | 938 |  *     } | 
 | 939 |  * | 
 | 940 |  * CAUTION:  In general, it isn't safe to use PyDict_Next in a loop that | 
| Tim Peters | 6783070 | 2001-03-21 19:23:56 +0000 | [diff] [blame] | 941 |  * mutates the dict.  One exception:  it is safe if the loop merely changes | 
 | 942 |  * the values associated with the keys (but doesn't insert new keys or | 
 | 943 |  * delete keys), via PyDict_SetItem(). | 
 | 944 |  */ | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 945 | int | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 946 | PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 947 | { | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 948 | 	register Py_ssize_t i; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 949 | 	register Py_ssize_t mask; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 950 | 	register PyDictEntry *ep; | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 951 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 952 | 	if (!PyDict_Check(op)) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 953 | 		return 0; | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 954 | 	i = *ppos; | 
 | 955 | 	if (i < 0) | 
 | 956 | 		return 0; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 957 | 	ep = ((PyDictObject *)op)->ma_table; | 
 | 958 | 	mask = ((PyDictObject *)op)->ma_mask; | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 959 | 	while (i <= mask && ep[i].me_value == NULL) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 960 | 		i++; | 
 | 961 | 	*ppos = i+1; | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 962 | 	if (i > mask) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 963 | 		return 0; | 
 | 964 | 	if (pkey) | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 965 | 		*pkey = ep[i].me_key; | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 966 | 	if (pvalue) | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 967 | 		*pvalue = ep[i].me_value; | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 968 | 	return 1; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 969 | } | 
 | 970 |  | 
| Thomas Wouters | cf297e4 | 2007-02-23 15:07:44 +0000 | [diff] [blame] | 971 | /* Internal version of PyDict_Next that returns a hash value in addition to the key and value.*/ | 
 | 972 | int | 
 | 973 | _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, long *phash) | 
 | 974 | { | 
 | 975 | 	register Py_ssize_t i; | 
 | 976 | 	register Py_ssize_t mask; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 977 | 	register PyDictEntry *ep; | 
| Thomas Wouters | cf297e4 | 2007-02-23 15:07:44 +0000 | [diff] [blame] | 978 |  | 
 | 979 | 	if (!PyDict_Check(op)) | 
 | 980 | 		return 0; | 
 | 981 | 	i = *ppos; | 
 | 982 | 	if (i < 0) | 
 | 983 | 		return 0; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 984 | 	ep = ((PyDictObject *)op)->ma_table; | 
 | 985 | 	mask = ((PyDictObject *)op)->ma_mask; | 
| Thomas Wouters | cf297e4 | 2007-02-23 15:07:44 +0000 | [diff] [blame] | 986 | 	while (i <= mask && ep[i].me_value == NULL) | 
 | 987 | 		i++; | 
 | 988 | 	*ppos = i+1; | 
 | 989 | 	if (i > mask) | 
 | 990 | 		return 0; | 
 | 991 |         *phash = (long)(ep[i].me_hash); | 
 | 992 | 	if (pkey) | 
 | 993 | 		*pkey = ep[i].me_key; | 
 | 994 | 	if (pvalue) | 
 | 995 | 		*pvalue = ep[i].me_value; | 
 | 996 | 	return 1; | 
 | 997 | } | 
 | 998 |  | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 999 | /* Methods */ | 
 | 1000 |  | 
 | 1001 | static void | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1002 | dict_dealloc(register PyDictObject *mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1003 | { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1004 | 	register PyDictEntry *ep; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1005 | 	Py_ssize_t fill = mp->ma_fill; | 
| Guido van Rossum | ff413af | 2002-03-28 20:34:59 +0000 | [diff] [blame] | 1006 |  	PyObject_GC_UnTrack(mp); | 
| Guido van Rossum | d724b23 | 2000-03-13 16:01:29 +0000 | [diff] [blame] | 1007 | 	Py_TRASHCAN_SAFE_BEGIN(mp) | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 1008 | 	for (ep = mp->ma_table; fill > 0; ep++) { | 
 | 1009 | 		if (ep->me_key) { | 
 | 1010 | 			--fill; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1011 | 			Py_DECREF(ep->me_key); | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 1012 | 			Py_XDECREF(ep->me_value); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 1013 | 		} | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1014 | 	} | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 1015 | 	if (mp->ma_table != mp->ma_smalltable) | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 1016 | 		PyMem_DEL(mp->ma_table); | 
| Christian Heimes | 2202f87 | 2008-02-06 14:31:34 +0000 | [diff] [blame] | 1017 | 	if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type) | 
 | 1018 | 		free_list[numfree++] = mp; | 
| Tim Peters | 60b2996 | 2006-01-01 01:19:23 +0000 | [diff] [blame] | 1019 | 	else | 
| Christian Heimes | 90aa764 | 2007-12-19 02:45:37 +0000 | [diff] [blame] | 1020 | 		Py_TYPE(mp)->tp_free((PyObject *)mp); | 
| Guido van Rossum | d724b23 | 2000-03-13 16:01:29 +0000 | [diff] [blame] | 1021 | 	Py_TRASHCAN_SAFE_END(mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1022 | } | 
 | 1023 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1024 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1025 | dict_repr(PyDictObject *mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1026 | { | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 1027 | 	Py_ssize_t i; | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1028 | 	PyObject *s, *temp, *colon = NULL; | 
 | 1029 | 	PyObject *pieces = NULL, *result = NULL; | 
 | 1030 | 	PyObject *key, *value; | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 1031 |  | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1032 | 	i = Py_ReprEnter((PyObject *)mp); | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 1033 | 	if (i != 0) { | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1034 | 		return i > 0 ? PyUnicode_FromString("{...}") : NULL; | 
| Guido van Rossum | 255443b | 1998-04-10 22:47:14 +0000 | [diff] [blame] | 1035 | 	} | 
 | 1036 |  | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1037 | 	if (mp->ma_used == 0) { | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1038 | 		result = PyUnicode_FromString("{}"); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1039 | 		goto Done; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1040 | 	} | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1041 |  | 
 | 1042 | 	pieces = PyList_New(0); | 
 | 1043 | 	if (pieces == NULL) | 
 | 1044 | 		goto Done; | 
 | 1045 |  | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1046 | 	colon = PyUnicode_FromString(": "); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1047 | 	if (colon == NULL) | 
 | 1048 | 		goto Done; | 
 | 1049 |  | 
 | 1050 | 	/* Do repr() on each key+value pair, and insert ": " between them. | 
 | 1051 | 	   Note that repr may mutate the dict. */ | 
| Tim Peters | c605784 | 2001-06-16 07:52:53 +0000 | [diff] [blame] | 1052 | 	i = 0; | 
 | 1053 | 	while (PyDict_Next((PyObject *)mp, &i, &key, &value)) { | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1054 | 		int status; | 
 | 1055 | 		/* Prevent repr from deleting value during key format. */ | 
 | 1056 | 		Py_INCREF(value); | 
 | 1057 | 		s = PyObject_Repr(key); | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1058 | 		PyUnicode_Append(&s, colon); | 
 | 1059 | 		PyUnicode_AppendAndDel(&s, PyObject_Repr(value)); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1060 | 		Py_DECREF(value); | 
 | 1061 | 		if (s == NULL) | 
 | 1062 | 			goto Done; | 
 | 1063 | 		status = PyList_Append(pieces, s); | 
 | 1064 | 		Py_DECREF(s);  /* append created a new ref */ | 
 | 1065 | 		if (status < 0) | 
 | 1066 | 			goto Done; | 
 | 1067 | 	} | 
 | 1068 |  | 
 | 1069 | 	/* Add "{}" decorations to the first and last items. */ | 
 | 1070 | 	assert(PyList_GET_SIZE(pieces) > 0); | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1071 | 	s = PyUnicode_FromString("{"); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1072 | 	if (s == NULL) | 
 | 1073 | 		goto Done; | 
 | 1074 | 	temp = PyList_GET_ITEM(pieces, 0); | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1075 | 	PyUnicode_AppendAndDel(&s, temp); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1076 | 	PyList_SET_ITEM(pieces, 0, s); | 
 | 1077 | 	if (s == NULL) | 
 | 1078 | 		goto Done; | 
 | 1079 |  | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1080 | 	s = PyUnicode_FromString("}"); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1081 | 	if (s == NULL) | 
 | 1082 | 		goto Done; | 
 | 1083 | 	temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1084 | 	PyUnicode_AppendAndDel(&temp, s); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1085 | 	PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); | 
 | 1086 | 	if (temp == NULL) | 
 | 1087 | 		goto Done; | 
 | 1088 |  | 
 | 1089 | 	/* Paste them all together with ", " between. */ | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1090 | 	s = PyUnicode_FromString(", "); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1091 | 	if (s == NULL) | 
 | 1092 | 		goto Done; | 
| Walter Dörwald | 1ab8330 | 2007-05-18 17:15:44 +0000 | [diff] [blame] | 1093 | 	result = PyUnicode_Join(s, pieces); | 
| Tim Peters | 0ab085c | 2001-09-14 00:25:33 +0000 | [diff] [blame] | 1094 | 	Py_DECREF(s); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1095 |  | 
 | 1096 | Done: | 
 | 1097 | 	Py_XDECREF(pieces); | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1098 | 	Py_XDECREF(colon); | 
| Tim Peters | a725959 | 2001-06-16 05:11:17 +0000 | [diff] [blame] | 1099 | 	Py_ReprLeave((PyObject *)mp); | 
 | 1100 | 	return result; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1101 | } | 
 | 1102 |  | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 1103 | static Py_ssize_t | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1104 | dict_length(PyDictObject *mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1105 | { | 
 | 1106 | 	return mp->ma_used; | 
 | 1107 | } | 
 | 1108 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1109 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1110 | dict_subscript(PyDictObject *mp, register PyObject *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1111 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1112 | 	PyObject *v; | 
| Sjoerd Mullender | 3bb8a05 | 1993-10-22 12:04:32 +0000 | [diff] [blame] | 1113 | 	long hash; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1114 | 	PyDictEntry *ep; | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 1115 | 	assert(mp->ma_table != NULL); | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 1116 | 	if (!PyUnicode_CheckExact(key) || | 
 | 1117 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1118 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1119 | 		if (hash == -1) | 
 | 1120 | 			return NULL; | 
 | 1121 | 	} | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1122 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
 | 1123 | 	if (ep == NULL) | 
 | 1124 | 		return NULL; | 
 | 1125 | 	v = ep->me_value; | 
| Guido van Rossum | 1968ad3 | 2006-02-25 22:38:04 +0000 | [diff] [blame] | 1126 | 	if (v == NULL) { | 
 | 1127 | 		if (!PyDict_CheckExact(mp)) { | 
 | 1128 | 			/* Look up __missing__ method if we're a subclass. */ | 
| Guido van Rossum | 4b92a82 | 2006-02-25 23:32:30 +0000 | [diff] [blame] | 1129 | 		    	PyObject *missing; | 
| Guido van Rossum | 1968ad3 | 2006-02-25 22:38:04 +0000 | [diff] [blame] | 1130 | 			static PyObject *missing_str = NULL; | 
 | 1131 | 			if (missing_str == NULL) | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1132 | 				missing_str = | 
| Martin v. Löwis | 5b22213 | 2007-06-10 09:51:05 +0000 | [diff] [blame] | 1133 | 				  PyUnicode_InternFromString("__missing__"); | 
| Christian Heimes | 90aa764 | 2007-12-19 02:45:37 +0000 | [diff] [blame] | 1134 | 			missing = _PyType_Lookup(Py_TYPE(mp), missing_str); | 
| Guido van Rossum | 1968ad3 | 2006-02-25 22:38:04 +0000 | [diff] [blame] | 1135 | 			if (missing != NULL) | 
 | 1136 | 				return PyObject_CallFunctionObjArgs(missing, | 
 | 1137 | 					(PyObject *)mp, key, NULL); | 
 | 1138 | 		} | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1139 | 		set_key_error(key); | 
| Guido van Rossum | 1968ad3 | 2006-02-25 22:38:04 +0000 | [diff] [blame] | 1140 | 		return NULL; | 
 | 1141 | 	} | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1142 | 	else | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1143 | 		Py_INCREF(v); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1144 | 	return v; | 
 | 1145 | } | 
 | 1146 |  | 
 | 1147 | static int | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1148 | dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1149 | { | 
 | 1150 | 	if (w == NULL) | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1151 | 		return PyDict_DelItem((PyObject *)mp, v); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1152 | 	else | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1153 | 		return PyDict_SetItem((PyObject *)mp, v, w); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1154 | } | 
 | 1155 |  | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 1156 | static PyMappingMethods dict_as_mapping = { | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 1157 | 	(lenfunc)dict_length, /*mp_length*/ | 
| Guido van Rossum | a9e7a81 | 1997-05-13 21:02:11 +0000 | [diff] [blame] | 1158 | 	(binaryfunc)dict_subscript, /*mp_subscript*/ | 
 | 1159 | 	(objobjargproc)dict_ass_sub, /*mp_ass_subscript*/ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1160 | }; | 
 | 1161 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1162 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1163 | dict_keys(register PyDictObject *mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1164 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1165 | 	register PyObject *v; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1166 | 	register Py_ssize_t i, j; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1167 | 	PyDictEntry *ep; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1168 | 	Py_ssize_t mask, n; | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1169 |  | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1170 |   again: | 
 | 1171 | 	n = mp->ma_used; | 
 | 1172 | 	v = PyList_New(n); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1173 | 	if (v == NULL) | 
 | 1174 | 		return NULL; | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1175 | 	if (n != mp->ma_used) { | 
 | 1176 | 		/* Durnit.  The allocations caused the dict to resize. | 
 | 1177 | 		 * Just start over, this shouldn't normally happen. | 
 | 1178 | 		 */ | 
 | 1179 | 		Py_DECREF(v); | 
 | 1180 | 		goto again; | 
 | 1181 | 	} | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 1182 | 	ep = mp->ma_table; | 
 | 1183 | 	mask = mp->ma_mask; | 
 | 1184 | 	for (i = 0, j = 0; i <= mask; i++) { | 
 | 1185 | 		if (ep[i].me_value != NULL) { | 
 | 1186 | 			PyObject *key = ep[i].me_key; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1187 | 			Py_INCREF(key); | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1188 | 			PyList_SET_ITEM(v, j, key); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1189 | 			j++; | 
 | 1190 | 		} | 
 | 1191 | 	} | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 1192 | 	assert(j == n); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1193 | 	return v; | 
 | 1194 | } | 
 | 1195 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1196 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1197 | dict_values(register PyDictObject *mp) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1198 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1199 | 	register PyObject *v; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1200 | 	register Py_ssize_t i, j; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1201 | 	PyDictEntry *ep; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1202 | 	Py_ssize_t mask, n; | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1203 |  | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1204 |   again: | 
 | 1205 | 	n = mp->ma_used; | 
 | 1206 | 	v = PyList_New(n); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1207 | 	if (v == NULL) | 
 | 1208 | 		return NULL; | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1209 | 	if (n != mp->ma_used) { | 
 | 1210 | 		/* Durnit.  The allocations caused the dict to resize. | 
 | 1211 | 		 * Just start over, this shouldn't normally happen. | 
 | 1212 | 		 */ | 
 | 1213 | 		Py_DECREF(v); | 
 | 1214 | 		goto again; | 
 | 1215 | 	} | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 1216 | 	ep = mp->ma_table; | 
 | 1217 | 	mask = mp->ma_mask; | 
 | 1218 | 	for (i = 0, j = 0; i <= mask; i++) { | 
 | 1219 | 		if (ep[i].me_value != NULL) { | 
 | 1220 | 			PyObject *value = ep[i].me_value; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1221 | 			Py_INCREF(value); | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1222 | 			PyList_SET_ITEM(v, j, value); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1223 | 			j++; | 
 | 1224 | 		} | 
 | 1225 | 	} | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 1226 | 	assert(j == n); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1227 | 	return v; | 
 | 1228 | } | 
 | 1229 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1230 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1231 | dict_items(register PyDictObject *mp) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1232 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1233 | 	register PyObject *v; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1234 | 	register Py_ssize_t i, j, n; | 
 | 1235 | 	Py_ssize_t mask; | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1236 | 	PyObject *item, *key, *value; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1237 | 	PyDictEntry *ep; | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1238 |  | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1239 | 	/* Preallocate the list of tuples, to avoid allocations during | 
 | 1240 | 	 * the loop over the items, which could trigger GC, which | 
 | 1241 | 	 * could resize the dict. :-( | 
 | 1242 | 	 */ | 
 | 1243 |   again: | 
 | 1244 | 	n = mp->ma_used; | 
 | 1245 | 	v = PyList_New(n); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1246 | 	if (v == NULL) | 
 | 1247 | 		return NULL; | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1248 | 	for (i = 0; i < n; i++) { | 
 | 1249 | 		item = PyTuple_New(2); | 
 | 1250 | 		if (item == NULL) { | 
 | 1251 | 			Py_DECREF(v); | 
 | 1252 | 			return NULL; | 
 | 1253 | 		} | 
 | 1254 | 		PyList_SET_ITEM(v, i, item); | 
 | 1255 | 	} | 
 | 1256 | 	if (n != mp->ma_used) { | 
 | 1257 | 		/* Durnit.  The allocations caused the dict to resize. | 
 | 1258 | 		 * Just start over, this shouldn't normally happen. | 
 | 1259 | 		 */ | 
 | 1260 | 		Py_DECREF(v); | 
 | 1261 | 		goto again; | 
 | 1262 | 	} | 
 | 1263 | 	/* Nothing we do below makes any function calls. */ | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 1264 | 	ep = mp->ma_table; | 
 | 1265 | 	mask = mp->ma_mask; | 
 | 1266 | 	for (i = 0, j = 0; i <= mask; i++) { | 
| Raymond Hettinger | 0690512 | 2004-03-19 10:30:00 +0000 | [diff] [blame] | 1267 | 		if ((value=ep[i].me_value) != NULL) { | 
| Raymond Hettinger | 4344278 | 2004-03-17 21:55:03 +0000 | [diff] [blame] | 1268 | 			key = ep[i].me_key; | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1269 | 			item = PyList_GET_ITEM(v, j); | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1270 | 			Py_INCREF(key); | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1271 | 			PyTuple_SET_ITEM(item, 0, key); | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1272 | 			Py_INCREF(value); | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1273 | 			PyTuple_SET_ITEM(item, 1, value); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1274 | 			j++; | 
 | 1275 | 		} | 
 | 1276 | 	} | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1277 | 	assert(j == n); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1278 | 	return v; | 
 | 1279 | } | 
 | 1280 |  | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 1281 | static PyObject * | 
| Tim Peters | bca1cbc | 2002-12-09 22:56:13 +0000 | [diff] [blame] | 1282 | dict_fromkeys(PyObject *cls, PyObject *args) | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1283 | { | 
 | 1284 | 	PyObject *seq; | 
 | 1285 | 	PyObject *value = Py_None; | 
 | 1286 | 	PyObject *it;	/* iter(seq) */ | 
 | 1287 | 	PyObject *key; | 
 | 1288 | 	PyObject *d; | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1289 | 	int status; | 
 | 1290 |  | 
| Raymond Hettinger | ea3fdf4 | 2002-12-29 16:33:45 +0000 | [diff] [blame] | 1291 | 	if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value)) | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1292 | 		return NULL; | 
 | 1293 |  | 
 | 1294 | 	d = PyObject_CallObject(cls, NULL); | 
 | 1295 | 	if (d == NULL) | 
 | 1296 | 		return NULL; | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1297 |  | 
| Guido van Rossum | 58da931 | 2007-11-10 23:39:45 +0000 | [diff] [blame] | 1298 | 	if (PyDict_CheckExact(d) && PyDict_CheckExact(seq)) { | 
 | 1299 | 		PyDictObject *mp = (PyDictObject *)d; | 
 | 1300 | 		PyObject *oldvalue; | 
 | 1301 | 		Py_ssize_t pos = 0; | 
 | 1302 | 		PyObject *key; | 
 | 1303 | 		long hash; | 
 | 1304 |  | 
| Benjamin Peterson | 4118174 | 2008-07-02 20:22:54 +0000 | [diff] [blame] | 1305 | 		if (dictresize(mp, Py_SIZE(seq))) | 
| Guido van Rossum | 58da931 | 2007-11-10 23:39:45 +0000 | [diff] [blame] | 1306 | 			return NULL; | 
 | 1307 |  | 
 | 1308 | 		while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) { | 
 | 1309 | 			Py_INCREF(key); | 
 | 1310 | 			Py_INCREF(value); | 
 | 1311 | 			if (insertdict(mp, key, hash, value)) | 
 | 1312 | 				return NULL; | 
 | 1313 | 		} | 
 | 1314 | 		return d; | 
 | 1315 | 	} | 
 | 1316 |  | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1317 | 	if (PyDict_CheckExact(d) && PyAnySet_CheckExact(seq)) { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1318 | 		PyDictObject *mp = (PyDictObject *)d; | 
| Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1319 | 		Py_ssize_t pos = 0; | 
 | 1320 | 		PyObject *key; | 
 | 1321 | 		long hash; | 
 | 1322 |  | 
 | 1323 | 		if (dictresize(mp, PySet_GET_SIZE(seq))) | 
 | 1324 | 			return NULL; | 
 | 1325 |  | 
 | 1326 | 		while (_PySet_NextEntry(seq, &pos, &key, &hash)) { | 
 | 1327 | 			Py_INCREF(key); | 
 | 1328 | 			Py_INCREF(value); | 
 | 1329 | 			if (insertdict(mp, key, hash, value)) | 
 | 1330 | 				return NULL; | 
 | 1331 | 		} | 
 | 1332 | 		return d; | 
 | 1333 | 	} | 
 | 1334 |  | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1335 | 	it = PyObject_GetIter(seq); | 
 | 1336 | 	if (it == NULL){ | 
 | 1337 | 		Py_DECREF(d); | 
 | 1338 | 		return NULL; | 
 | 1339 | 	} | 
 | 1340 |  | 
| Guido van Rossum | 58da931 | 2007-11-10 23:39:45 +0000 | [diff] [blame] | 1341 | 	if (PyDict_CheckExact(d)) { | 
 | 1342 | 		while ((key = PyIter_Next(it)) != NULL) { | 
 | 1343 | 			status = PyDict_SetItem(d, key, value); | 
 | 1344 | 			Py_DECREF(key); | 
 | 1345 | 			if (status < 0) | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1346 | 				goto Fail; | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1347 | 		} | 
| Guido van Rossum | 58da931 | 2007-11-10 23:39:45 +0000 | [diff] [blame] | 1348 | 	} else { | 
 | 1349 | 		while ((key = PyIter_Next(it)) != NULL) { | 
 | 1350 | 			status = PyObject_SetItem(d, key, value); | 
 | 1351 | 			Py_DECREF(key); | 
 | 1352 | 			if (status < 0) | 
 | 1353 | 				goto Fail; | 
 | 1354 | 		} | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1355 | 	} | 
 | 1356 |  | 
| Guido van Rossum | 58da931 | 2007-11-10 23:39:45 +0000 | [diff] [blame] | 1357 | 	if (PyErr_Occurred()) | 
 | 1358 | 		goto Fail; | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1359 | 	Py_DECREF(it); | 
 | 1360 | 	return d; | 
 | 1361 |  | 
 | 1362 | Fail: | 
 | 1363 | 	Py_DECREF(it); | 
 | 1364 | 	Py_DECREF(d); | 
 | 1365 | 	return NULL; | 
 | 1366 | } | 
 | 1367 |  | 
| Raymond Hettinger | 31017ae | 2004-03-04 08:25:44 +0000 | [diff] [blame] | 1368 | static int | 
 | 1369 | dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, char *methname) | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 1370 | { | 
| Raymond Hettinger | 31017ae | 2004-03-04 08:25:44 +0000 | [diff] [blame] | 1371 | 	PyObject *arg = NULL; | 
 | 1372 | 	int result = 0; | 
 | 1373 |  | 
 | 1374 | 	if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) | 
 | 1375 | 		result = -1; | 
 | 1376 |  | 
 | 1377 | 	else if (arg != NULL) { | 
 | 1378 | 		if (PyObject_HasAttrString(arg, "keys")) | 
 | 1379 | 			result = PyDict_Merge(self, arg, 1); | 
 | 1380 | 		else | 
 | 1381 | 			result = PyDict_MergeFromSeq2(self, arg, 1); | 
 | 1382 | 	} | 
 | 1383 | 	if (result == 0 && kwds != NULL) | 
 | 1384 | 		result = PyDict_Merge(self, kwds, 1); | 
 | 1385 | 	return result; | 
 | 1386 | } | 
 | 1387 |  | 
 | 1388 | static PyObject * | 
 | 1389 | dict_update(PyObject *self, PyObject *args, PyObject *kwds) | 
 | 1390 | { | 
| Raymond Hettinger | 7892b1c | 2004-04-12 18:10:01 +0000 | [diff] [blame] | 1391 | 	if (dict_update_common(self, args, kwds, "update") != -1) | 
 | 1392 | 		Py_RETURN_NONE; | 
 | 1393 | 	return NULL; | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1394 | } | 
 | 1395 |  | 
| Guido van Rossum | 05ac6de | 2001-08-10 20:28:28 +0000 | [diff] [blame] | 1396 | /* Update unconditionally replaces existing items. | 
 | 1397 |    Merge has a 3rd argument 'override'; if set, it acts like Update, | 
| Tim Peters | 1fc240e | 2001-10-26 05:06:50 +0000 | [diff] [blame] | 1398 |    otherwise it leaves existing items unchanged. | 
 | 1399 |  | 
 | 1400 |    PyDict_{Update,Merge} update/merge from a mapping object. | 
 | 1401 |  | 
| Tim Peters | f582b82 | 2001-12-11 18:51:08 +0000 | [diff] [blame] | 1402 |    PyDict_MergeFromSeq2 updates/merges from any iterable object | 
| Tim Peters | 1fc240e | 2001-10-26 05:06:50 +0000 | [diff] [blame] | 1403 |    producing iterable objects of length 2. | 
 | 1404 | */ | 
 | 1405 |  | 
| Tim Peters | f582b82 | 2001-12-11 18:51:08 +0000 | [diff] [blame] | 1406 | int | 
| Tim Peters | 1fc240e | 2001-10-26 05:06:50 +0000 | [diff] [blame] | 1407 | PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) | 
 | 1408 | { | 
 | 1409 | 	PyObject *it;	/* iter(seq2) */ | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1410 | 	Py_ssize_t i;	/* index into seq2 of current element */ | 
| Tim Peters | 1fc240e | 2001-10-26 05:06:50 +0000 | [diff] [blame] | 1411 | 	PyObject *item;	/* seq2[i] */ | 
 | 1412 | 	PyObject *fast;	/* item as a 2-tuple or 2-list */ | 
 | 1413 |  | 
 | 1414 | 	assert(d != NULL); | 
 | 1415 | 	assert(PyDict_Check(d)); | 
 | 1416 | 	assert(seq2 != NULL); | 
 | 1417 |  | 
 | 1418 | 	it = PyObject_GetIter(seq2); | 
 | 1419 | 	if (it == NULL) | 
 | 1420 | 		return -1; | 
 | 1421 |  | 
 | 1422 | 	for (i = 0; ; ++i) { | 
 | 1423 | 		PyObject *key, *value; | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 1424 | 		Py_ssize_t n; | 
| Tim Peters | 1fc240e | 2001-10-26 05:06:50 +0000 | [diff] [blame] | 1425 |  | 
 | 1426 | 		fast = NULL; | 
 | 1427 | 		item = PyIter_Next(it); | 
 | 1428 | 		if (item == NULL) { | 
 | 1429 | 			if (PyErr_Occurred()) | 
 | 1430 | 				goto Fail; | 
 | 1431 | 			break; | 
 | 1432 | 		} | 
 | 1433 |  | 
 | 1434 | 		/* Convert item to sequence, and verify length 2. */ | 
 | 1435 | 		fast = PySequence_Fast(item, ""); | 
 | 1436 | 		if (fast == NULL) { | 
 | 1437 | 			if (PyErr_ExceptionMatches(PyExc_TypeError)) | 
 | 1438 | 				PyErr_Format(PyExc_TypeError, | 
 | 1439 | 					"cannot convert dictionary update " | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1440 | 					"sequence element #%zd to a sequence", | 
| Tim Peters | 1fc240e | 2001-10-26 05:06:50 +0000 | [diff] [blame] | 1441 | 					i); | 
 | 1442 | 			goto Fail; | 
 | 1443 | 		} | 
 | 1444 | 		n = PySequence_Fast_GET_SIZE(fast); | 
 | 1445 | 		if (n != 2) { | 
 | 1446 | 			PyErr_Format(PyExc_ValueError, | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1447 | 				     "dictionary update sequence element #%zd " | 
| Martin v. Löwis | 2c95cc6 | 2006-02-16 06:54:25 +0000 | [diff] [blame] | 1448 | 				     "has length %zd; 2 is required", | 
| Martin v. Löwis | e0e89f7 | 2006-02-16 06:59:22 +0000 | [diff] [blame] | 1449 | 				     i, n); | 
| Tim Peters | 1fc240e | 2001-10-26 05:06:50 +0000 | [diff] [blame] | 1450 | 			goto Fail; | 
 | 1451 | 		} | 
 | 1452 |  | 
 | 1453 | 		/* Update/merge with this (key, value) pair. */ | 
 | 1454 | 		key = PySequence_Fast_GET_ITEM(fast, 0); | 
 | 1455 | 		value = PySequence_Fast_GET_ITEM(fast, 1); | 
 | 1456 | 		if (override || PyDict_GetItem(d, key) == NULL) { | 
 | 1457 | 			int status = PyDict_SetItem(d, key, value); | 
 | 1458 | 			if (status < 0) | 
 | 1459 | 				goto Fail; | 
 | 1460 | 		} | 
 | 1461 | 		Py_DECREF(fast); | 
 | 1462 | 		Py_DECREF(item); | 
 | 1463 | 	} | 
 | 1464 |  | 
 | 1465 | 	i = 0; | 
 | 1466 | 	goto Return; | 
 | 1467 | Fail: | 
 | 1468 | 	Py_XDECREF(item); | 
 | 1469 | 	Py_XDECREF(fast); | 
 | 1470 | 	i = -1; | 
 | 1471 | Return: | 
 | 1472 | 	Py_DECREF(it); | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1473 | 	return Py_SAFE_DOWNCAST(i, Py_ssize_t, int); | 
| Tim Peters | 1fc240e | 2001-10-26 05:06:50 +0000 | [diff] [blame] | 1474 | } | 
 | 1475 |  | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1476 | int | 
 | 1477 | PyDict_Update(PyObject *a, PyObject *b) | 
 | 1478 | { | 
| Guido van Rossum | 05ac6de | 2001-08-10 20:28:28 +0000 | [diff] [blame] | 1479 | 	return PyDict_Merge(a, b, 1); | 
 | 1480 | } | 
 | 1481 |  | 
 | 1482 | int | 
 | 1483 | PyDict_Merge(PyObject *a, PyObject *b, int override) | 
 | 1484 | { | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1485 | 	register PyDictObject *mp, *other; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1486 | 	register Py_ssize_t i; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1487 | 	PyDictEntry *entry; | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1488 |  | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1489 | 	/* We accept for the argument either a concrete dictionary object, | 
 | 1490 | 	 * or an abstract "mapping" object.  For the former, we can do | 
 | 1491 | 	 * things quite efficiently.  For the latter, we only require that | 
 | 1492 | 	 * PyMapping_Keys() and PyObject_GetItem() be supported. | 
 | 1493 | 	 */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1494 | 	if (a == NULL || !PyDict_Check(a) || b == NULL) { | 
 | 1495 | 		PyErr_BadInternalCall(); | 
 | 1496 | 		return -1; | 
 | 1497 | 	} | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1498 | 	mp = (PyDictObject*)a; | 
| Christian Heimes | af98da1 | 2008-01-27 15:18:18 +0000 | [diff] [blame] | 1499 | 	if (PyDict_Check(b)) { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1500 | 		other = (PyDictObject*)b; | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1501 | 		if (other == mp || other->ma_used == 0) | 
 | 1502 | 			/* a.update(a) or a.update({}); nothing to do */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1503 | 			return 0; | 
| Raymond Hettinger | 186e739 | 2005-05-14 18:08:25 +0000 | [diff] [blame] | 1504 | 		if (mp->ma_used == 0) | 
 | 1505 | 			/* Since the target dict is empty, PyDict_GetItem() | 
 | 1506 | 			 * always returns NULL.  Setting override to 1 | 
 | 1507 | 			 * skips the unnecessary test. | 
 | 1508 | 			 */ | 
 | 1509 | 			override = 1; | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1510 | 		/* Do one big resize at the start, rather than | 
 | 1511 | 		 * incrementally resizing as we insert new items.  Expect | 
 | 1512 | 		 * that there will be no (or few) overlapping keys. | 
 | 1513 | 		 */ | 
 | 1514 | 		if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) { | 
| Raymond Hettinger | c8d2290 | 2003-05-07 00:49:40 +0000 | [diff] [blame] | 1515 | 		   if (dictresize(mp, (mp->ma_used + other->ma_used)*2) != 0) | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1516 | 			   return -1; | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1517 | 		} | 
 | 1518 | 		for (i = 0; i <= other->ma_mask; i++) { | 
 | 1519 | 			entry = &other->ma_table[i]; | 
| Guido van Rossum | 05ac6de | 2001-08-10 20:28:28 +0000 | [diff] [blame] | 1520 | 			if (entry->me_value != NULL && | 
 | 1521 | 			    (override || | 
 | 1522 | 			     PyDict_GetItem(a, entry->me_key) == NULL)) { | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1523 | 				Py_INCREF(entry->me_key); | 
 | 1524 | 				Py_INCREF(entry->me_value); | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1525 | 				if (insertdict(mp, entry->me_key, | 
 | 1526 | 					       (long)entry->me_hash, | 
 | 1527 | 					       entry->me_value) != 0) | 
 | 1528 | 					return -1; | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1529 | 			} | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 1530 | 		} | 
 | 1531 | 	} | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1532 | 	else { | 
 | 1533 | 		/* Do it the generic, slower way */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1534 | 		PyObject *keys = PyMapping_Keys(b); | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1535 | 		PyObject *iter; | 
 | 1536 | 		PyObject *key, *value; | 
 | 1537 | 		int status; | 
 | 1538 |  | 
 | 1539 | 		if (keys == NULL) | 
 | 1540 | 			/* Docstring says this is equivalent to E.keys() so | 
 | 1541 | 			 * if E doesn't have a .keys() method we want | 
 | 1542 | 			 * AttributeError to percolate up.  Might as well | 
 | 1543 | 			 * do the same for any other error. | 
 | 1544 | 			 */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1545 | 			return -1; | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1546 |  | 
 | 1547 | 		iter = PyObject_GetIter(keys); | 
 | 1548 | 		Py_DECREF(keys); | 
 | 1549 | 		if (iter == NULL) | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1550 | 			return -1; | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1551 |  | 
 | 1552 | 		for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) { | 
| Guido van Rossum | 05ac6de | 2001-08-10 20:28:28 +0000 | [diff] [blame] | 1553 | 			if (!override && PyDict_GetItem(a, key) != NULL) { | 
 | 1554 | 				Py_DECREF(key); | 
 | 1555 | 				continue; | 
 | 1556 | 			} | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1557 | 			value = PyObject_GetItem(b, key); | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1558 | 			if (value == NULL) { | 
 | 1559 | 				Py_DECREF(iter); | 
 | 1560 | 				Py_DECREF(key); | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1561 | 				return -1; | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1562 | 			} | 
| Guido van Rossum | 05ac6de | 2001-08-10 20:28:28 +0000 | [diff] [blame] | 1563 | 			status = PyDict_SetItem(a, key, value); | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1564 | 			Py_DECREF(key); | 
 | 1565 | 			Py_DECREF(value); | 
 | 1566 | 			if (status < 0) { | 
 | 1567 | 				Py_DECREF(iter); | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1568 | 				return -1; | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1569 | 			} | 
 | 1570 | 		} | 
 | 1571 | 		Py_DECREF(iter); | 
 | 1572 | 		if (PyErr_Occurred()) | 
 | 1573 | 			/* Iterator completed, via error */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1574 | 			return -1; | 
| Barry Warsaw | 66a0d1d | 2001-06-26 20:08:32 +0000 | [diff] [blame] | 1575 | 	} | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1576 | 	return 0; | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 1577 | } | 
 | 1578 |  | 
 | 1579 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1580 | dict_copy(register PyDictObject *mp) | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 1581 | { | 
| Jeremy Hylton | a12c7a7 | 2000-03-30 22:27:31 +0000 | [diff] [blame] | 1582 | 	return PyDict_Copy((PyObject*)mp); | 
 | 1583 | } | 
 | 1584 |  | 
 | 1585 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1586 | PyDict_Copy(PyObject *o) | 
| Jeremy Hylton | a12c7a7 | 2000-03-30 22:27:31 +0000 | [diff] [blame] | 1587 | { | 
| Raymond Hettinger | ebedb2f | 2004-03-08 04:19:01 +0000 | [diff] [blame] | 1588 | 	PyObject *copy; | 
| Jeremy Hylton | a12c7a7 | 2000-03-30 22:27:31 +0000 | [diff] [blame] | 1589 |  | 
 | 1590 | 	if (o == NULL || !PyDict_Check(o)) { | 
 | 1591 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 1592 | 		return NULL; | 
| Jeremy Hylton | a12c7a7 | 2000-03-30 22:27:31 +0000 | [diff] [blame] | 1593 | 	} | 
| Raymond Hettinger | ebedb2f | 2004-03-08 04:19:01 +0000 | [diff] [blame] | 1594 | 	copy = PyDict_New(); | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 1595 | 	if (copy == NULL) | 
 | 1596 | 		return NULL; | 
| Raymond Hettinger | ebedb2f | 2004-03-08 04:19:01 +0000 | [diff] [blame] | 1597 | 	if (PyDict_Merge(copy, o, 1) == 0) | 
 | 1598 | 		return copy; | 
 | 1599 | 	Py_DECREF(copy); | 
| Raymond Hettinger | 1356f78 | 2005-04-15 15:58:42 +0000 | [diff] [blame] | 1600 | 	return NULL; | 
| Guido van Rossum | e3f5b9c | 1997-05-28 19:15:28 +0000 | [diff] [blame] | 1601 | } | 
 | 1602 |  | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 1603 | Py_ssize_t | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1604 | PyDict_Size(PyObject *mp) | 
| Guido van Rossum | 4199fac | 1993-11-05 10:18:44 +0000 | [diff] [blame] | 1605 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1606 | 	if (mp == NULL || !PyDict_Check(mp)) { | 
 | 1607 | 		PyErr_BadInternalCall(); | 
| Jeremy Hylton | 7083bb7 | 2004-02-17 20:10:11 +0000 | [diff] [blame] | 1608 | 		return -1; | 
| Guido van Rossum | 4199fac | 1993-11-05 10:18:44 +0000 | [diff] [blame] | 1609 | 	} | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1610 | 	return ((PyDictObject *)mp)->ma_used; | 
| Guido van Rossum | 4199fac | 1993-11-05 10:18:44 +0000 | [diff] [blame] | 1611 | } | 
 | 1612 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1613 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1614 | PyDict_Keys(PyObject *mp) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1615 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1616 | 	if (mp == NULL || !PyDict_Check(mp)) { | 
 | 1617 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1618 | 		return NULL; | 
 | 1619 | 	} | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1620 | 	return dict_keys((PyDictObject *)mp); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1621 | } | 
 | 1622 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1623 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1624 | PyDict_Values(PyObject *mp) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1625 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1626 | 	if (mp == NULL || !PyDict_Check(mp)) { | 
 | 1627 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1628 | 		return NULL; | 
 | 1629 | 	} | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1630 | 	return dict_values((PyDictObject *)mp); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1631 | } | 
 | 1632 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1633 | PyObject * | 
| Tim Peters | 1f5871e | 2000-07-04 17:44:48 +0000 | [diff] [blame] | 1634 | PyDict_Items(PyObject *mp) | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1635 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1636 | 	if (mp == NULL || !PyDict_Check(mp)) { | 
 | 1637 | 		PyErr_BadInternalCall(); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1638 | 		return NULL; | 
 | 1639 | 	} | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1640 | 	return dict_items((PyDictObject *)mp); | 
| Guido van Rossum | 2583165 | 1993-05-19 14:50:45 +0000 | [diff] [blame] | 1641 | } | 
 | 1642 |  | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 1643 | /* Return 1 if dicts equal, 0 if not, -1 if error. | 
 | 1644 |  * Gets out as soon as any difference is detected. | 
 | 1645 |  * Uses only Py_EQ comparison. | 
 | 1646 |  */ | 
 | 1647 | static int | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1648 | dict_equal(PyDictObject *a, PyDictObject *b) | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 1649 | { | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1650 | 	Py_ssize_t i; | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 1651 |  | 
 | 1652 | 	if (a->ma_used != b->ma_used) | 
 | 1653 | 		/* can't be equal if # of entries differ */ | 
 | 1654 | 		return 0; | 
| Tim Peters | eb28ef2 | 2001-06-02 05:27:19 +0000 | [diff] [blame] | 1655 |  | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 1656 | 	/* Same # of entries -- check all of 'em.  Exit early on any diff. */ | 
| Tim Peters | afb6ae8 | 2001-06-04 21:00:21 +0000 | [diff] [blame] | 1657 | 	for (i = 0; i <= a->ma_mask; i++) { | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 1658 | 		PyObject *aval = a->ma_table[i].me_value; | 
 | 1659 | 		if (aval != NULL) { | 
 | 1660 | 			int cmp; | 
 | 1661 | 			PyObject *bval; | 
 | 1662 | 			PyObject *key = a->ma_table[i].me_key; | 
 | 1663 | 			/* temporarily bump aval's refcount to ensure it stays | 
 | 1664 | 			   alive until we're done with it */ | 
 | 1665 | 			Py_INCREF(aval); | 
| Guido van Rossum | dc5f6b2 | 2006-08-24 21:29:26 +0000 | [diff] [blame] | 1666 | 			/* ditto for key */ | 
 | 1667 | 			Py_INCREF(key); | 
| Guido van Rossum | 47b9ff6 | 2006-08-24 00:41:19 +0000 | [diff] [blame] | 1668 | 			bval = PyDict_GetItemWithError((PyObject *)b, key); | 
| Guido van Rossum | dc5f6b2 | 2006-08-24 21:29:26 +0000 | [diff] [blame] | 1669 | 			Py_DECREF(key); | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 1670 | 			if (bval == NULL) { | 
 | 1671 | 				Py_DECREF(aval); | 
| Guido van Rossum | 47b9ff6 | 2006-08-24 00:41:19 +0000 | [diff] [blame] | 1672 | 				if (PyErr_Occurred()) | 
 | 1673 | 					return -1; | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 1674 | 				return 0; | 
 | 1675 | 			} | 
 | 1676 | 			cmp = PyObject_RichCompareBool(aval, bval, Py_EQ); | 
 | 1677 | 			Py_DECREF(aval); | 
 | 1678 | 			if (cmp <= 0)  /* error or not equal */ | 
 | 1679 | 				return cmp; | 
 | 1680 |  		} | 
 | 1681 | 	} | 
 | 1682 | 	return 1; | 
 | 1683 |  } | 
 | 1684 |  | 
 | 1685 | static PyObject * | 
 | 1686 | dict_richcompare(PyObject *v, PyObject *w, int op) | 
 | 1687 | { | 
 | 1688 | 	int cmp; | 
 | 1689 | 	PyObject *res; | 
 | 1690 |  | 
 | 1691 | 	if (!PyDict_Check(v) || !PyDict_Check(w)) { | 
 | 1692 | 		res = Py_NotImplemented; | 
 | 1693 | 	} | 
 | 1694 | 	else if (op == Py_EQ || op == Py_NE) { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1695 | 		cmp = dict_equal((PyDictObject *)v, (PyDictObject *)w); | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 1696 | 		if (cmp < 0) | 
 | 1697 | 			return NULL; | 
 | 1698 | 		res = (cmp == (op == Py_EQ)) ? Py_True : Py_False; | 
 | 1699 | 	} | 
| Tim Peters | 4fa58bf | 2001-05-10 21:45:19 +0000 | [diff] [blame] | 1700 | 	else | 
 | 1701 | 		res = Py_NotImplemented; | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 1702 | 	Py_INCREF(res); | 
 | 1703 | 	return res; | 
 | 1704 |  } | 
 | 1705 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1706 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1707 | dict_contains(register PyDictObject *mp, PyObject *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1708 | { | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1709 | 	long hash; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1710 | 	PyDictEntry *ep; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1711 |  | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 1712 | 	if (!PyUnicode_CheckExact(key) || | 
 | 1713 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1714 | 		hash = PyObject_Hash(key); | 
| Guido van Rossum | ca756f2 | 1997-01-23 19:39:29 +0000 | [diff] [blame] | 1715 | 		if (hash == -1) | 
 | 1716 | 			return NULL; | 
 | 1717 | 	} | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1718 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
 | 1719 | 	if (ep == NULL) | 
 | 1720 | 		return NULL; | 
 | 1721 | 	return PyBool_FromLong(ep->me_value != NULL); | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 1722 | } | 
 | 1723 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1724 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1725 | dict_get(register PyDictObject *mp, PyObject *args) | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1726 | { | 
 | 1727 | 	PyObject *key; | 
| Barry Warsaw | 320ac33 | 1997-10-20 17:26:25 +0000 | [diff] [blame] | 1728 | 	PyObject *failobj = Py_None; | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1729 | 	PyObject *val = NULL; | 
 | 1730 | 	long hash; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1731 | 	PyDictEntry *ep; | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1732 |  | 
| Raymond Hettinger | ea3fdf4 | 2002-12-29 16:33:45 +0000 | [diff] [blame] | 1733 | 	if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj)) | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1734 | 		return NULL; | 
 | 1735 |  | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 1736 | 	if (!PyUnicode_CheckExact(key) || | 
 | 1737 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) { | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1738 | 		hash = PyObject_Hash(key); | 
 | 1739 | 		if (hash == -1) | 
 | 1740 | 			return NULL; | 
 | 1741 | 	} | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1742 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
 | 1743 | 	if (ep == NULL) | 
 | 1744 | 		return NULL; | 
 | 1745 | 	val = ep->me_value; | 
| Barry Warsaw | c38c5da | 1997-10-06 17:49:20 +0000 | [diff] [blame] | 1746 | 	if (val == NULL) | 
 | 1747 | 		val = failobj; | 
 | 1748 | 	Py_INCREF(val); | 
 | 1749 | 	return val; | 
 | 1750 | } | 
 | 1751 |  | 
 | 1752 |  | 
 | 1753 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1754 | dict_setdefault(register PyDictObject *mp, PyObject *args) | 
| Guido van Rossum | 164452c | 2000-08-08 16:12:54 +0000 | [diff] [blame] | 1755 | { | 
 | 1756 | 	PyObject *key; | 
 | 1757 | 	PyObject *failobj = Py_None; | 
 | 1758 | 	PyObject *val = NULL; | 
 | 1759 | 	long hash; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1760 | 	PyDictEntry *ep; | 
| Guido van Rossum | 164452c | 2000-08-08 16:12:54 +0000 | [diff] [blame] | 1761 |  | 
| Raymond Hettinger | ea3fdf4 | 2002-12-29 16:33:45 +0000 | [diff] [blame] | 1762 | 	if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj)) | 
| Guido van Rossum | 164452c | 2000-08-08 16:12:54 +0000 | [diff] [blame] | 1763 | 		return NULL; | 
| Guido van Rossum | 164452c | 2000-08-08 16:12:54 +0000 | [diff] [blame] | 1764 |  | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 1765 | 	if (!PyUnicode_CheckExact(key) || | 
 | 1766 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) { | 
| Guido van Rossum | 164452c | 2000-08-08 16:12:54 +0000 | [diff] [blame] | 1767 | 		hash = PyObject_Hash(key); | 
 | 1768 | 		if (hash == -1) | 
 | 1769 | 			return NULL; | 
 | 1770 | 	} | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1771 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
 | 1772 | 	if (ep == NULL) | 
 | 1773 | 		return NULL; | 
 | 1774 | 	val = ep->me_value; | 
| Guido van Rossum | 164452c | 2000-08-08 16:12:54 +0000 | [diff] [blame] | 1775 | 	if (val == NULL) { | 
 | 1776 | 		val = failobj; | 
 | 1777 | 		if (PyDict_SetItem((PyObject*)mp, key, failobj)) | 
 | 1778 | 			val = NULL; | 
 | 1779 | 	} | 
 | 1780 | 	Py_XINCREF(val); | 
 | 1781 | 	return val; | 
 | 1782 | } | 
 | 1783 |  | 
 | 1784 |  | 
 | 1785 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1786 | dict_clear(register PyDictObject *mp) | 
| Guido van Rossum | fb8f1ca | 1997-03-21 21:55:12 +0000 | [diff] [blame] | 1787 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1788 | 	PyDict_Clear((PyObject *)mp); | 
| Raymond Hettinger | 7892b1c | 2004-04-12 18:10:01 +0000 | [diff] [blame] | 1789 | 	Py_RETURN_NONE; | 
| Guido van Rossum | fb8f1ca | 1997-03-21 21:55:12 +0000 | [diff] [blame] | 1790 | } | 
 | 1791 |  | 
| Guido van Rossum | ba6ab84 | 2000-12-12 22:02:18 +0000 | [diff] [blame] | 1792 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1793 | dict_pop(PyDictObject *mp, PyObject *args) | 
| Guido van Rossum | e027d98 | 2002-04-12 15:11:59 +0000 | [diff] [blame] | 1794 | { | 
 | 1795 | 	long hash; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1796 | 	PyDictEntry *ep; | 
| Guido van Rossum | e027d98 | 2002-04-12 15:11:59 +0000 | [diff] [blame] | 1797 | 	PyObject *old_value, *old_key; | 
| Raymond Hettinger | a3e1e4c | 2003-03-06 23:54:28 +0000 | [diff] [blame] | 1798 | 	PyObject *key, *deflt = NULL; | 
| Guido van Rossum | e027d98 | 2002-04-12 15:11:59 +0000 | [diff] [blame] | 1799 |  | 
| Raymond Hettinger | a3e1e4c | 2003-03-06 23:54:28 +0000 | [diff] [blame] | 1800 | 	if(!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &deflt)) | 
 | 1801 | 		return NULL; | 
| Guido van Rossum | e027d98 | 2002-04-12 15:11:59 +0000 | [diff] [blame] | 1802 | 	if (mp->ma_used == 0) { | 
| Raymond Hettinger | a3e1e4c | 2003-03-06 23:54:28 +0000 | [diff] [blame] | 1803 | 		if (deflt) { | 
 | 1804 | 			Py_INCREF(deflt); | 
 | 1805 | 			return deflt; | 
 | 1806 | 		} | 
| Guido van Rossum | e027d98 | 2002-04-12 15:11:59 +0000 | [diff] [blame] | 1807 | 		PyErr_SetString(PyExc_KeyError, | 
 | 1808 | 				"pop(): dictionary is empty"); | 
 | 1809 | 		return NULL; | 
 | 1810 | 	} | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 1811 | 	if (!PyUnicode_CheckExact(key) || | 
 | 1812 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) { | 
| Guido van Rossum | e027d98 | 2002-04-12 15:11:59 +0000 | [diff] [blame] | 1813 | 		hash = PyObject_Hash(key); | 
 | 1814 | 		if (hash == -1) | 
 | 1815 | 			return NULL; | 
 | 1816 | 	} | 
 | 1817 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1818 | 	if (ep == NULL) | 
 | 1819 | 		return NULL; | 
| Guido van Rossum | e027d98 | 2002-04-12 15:11:59 +0000 | [diff] [blame] | 1820 | 	if (ep->me_value == NULL) { | 
| Raymond Hettinger | a3e1e4c | 2003-03-06 23:54:28 +0000 | [diff] [blame] | 1821 | 		if (deflt) { | 
 | 1822 | 			Py_INCREF(deflt); | 
 | 1823 | 			return deflt; | 
 | 1824 | 		} | 
| Thomas Wouters | 89f507f | 2006-12-13 04:49:30 +0000 | [diff] [blame] | 1825 | 		set_key_error(key); | 
| Guido van Rossum | e027d98 | 2002-04-12 15:11:59 +0000 | [diff] [blame] | 1826 | 		return NULL; | 
 | 1827 | 	} | 
 | 1828 | 	old_key = ep->me_key; | 
 | 1829 | 	Py_INCREF(dummy); | 
 | 1830 | 	ep->me_key = dummy; | 
 | 1831 | 	old_value = ep->me_value; | 
 | 1832 | 	ep->me_value = NULL; | 
 | 1833 | 	mp->ma_used--; | 
 | 1834 | 	Py_DECREF(old_key); | 
 | 1835 | 	return old_value; | 
 | 1836 | } | 
 | 1837 |  | 
 | 1838 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1839 | dict_popitem(PyDictObject *mp) | 
| Guido van Rossum | ba6ab84 | 2000-12-12 22:02:18 +0000 | [diff] [blame] | 1840 | { | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1841 | 	Py_ssize_t i = 0; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1842 | 	PyDictEntry *ep; | 
| Guido van Rossum | ba6ab84 | 2000-12-12 22:02:18 +0000 | [diff] [blame] | 1843 | 	PyObject *res; | 
 | 1844 |  | 
| Tim Peters | f4b33f6 | 2001-06-02 05:42:29 +0000 | [diff] [blame] | 1845 | 	/* Allocate the result tuple before checking the size.  Believe it | 
 | 1846 | 	 * or not, this allocation could trigger a garbage collection which | 
 | 1847 | 	 * could empty the dict, so if we checked the size first and that | 
 | 1848 | 	 * happened, the result would be an infinite loop (searching for an | 
 | 1849 | 	 * entry that no longer exists).  Note that the usual popitem() | 
 | 1850 | 	 * idiom is "while d: k, v = d.popitem()". so needing to throw the | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1851 | 	 * tuple away if the dict *is* empty isn't a significant | 
| Tim Peters | f4b33f6 | 2001-06-02 05:42:29 +0000 | [diff] [blame] | 1852 | 	 * inefficiency -- possible, but unlikely in practice. | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1853 | 	 */ | 
 | 1854 | 	res = PyTuple_New(2); | 
 | 1855 | 	if (res == NULL) | 
 | 1856 | 		return NULL; | 
| Guido van Rossum | e04eaec | 2001-04-16 00:02:32 +0000 | [diff] [blame] | 1857 | 	if (mp->ma_used == 0) { | 
 | 1858 | 		Py_DECREF(res); | 
 | 1859 | 		PyErr_SetString(PyExc_KeyError, | 
 | 1860 | 				"popitem(): dictionary is empty"); | 
 | 1861 | 		return NULL; | 
 | 1862 | 	} | 
| Guido van Rossum | ba6ab84 | 2000-12-12 22:02:18 +0000 | [diff] [blame] | 1863 | 	/* Set ep to "the first" dict entry with a value.  We abuse the hash | 
 | 1864 | 	 * field of slot 0 to hold a search finger: | 
 | 1865 | 	 * If slot 0 has a value, use slot 0. | 
 | 1866 | 	 * Else slot 0 is being used to hold a search finger, | 
 | 1867 | 	 * and we use its hash value as the first index to look. | 
 | 1868 | 	 */ | 
 | 1869 | 	ep = &mp->ma_table[0]; | 
 | 1870 | 	if (ep->me_value == NULL) { | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 1871 | 		i = ep->me_hash; | 
| Tim Peters | dea48ec | 2001-05-22 20:40:22 +0000 | [diff] [blame] | 1872 | 		/* The hash field may be a real hash value, or it may be a | 
 | 1873 | 		 * legit search finger, or it may be a once-legit search | 
 | 1874 | 		 * finger that's out of bounds now because it wrapped around | 
 | 1875 | 		 * or the table shrunk -- simply make sure it's in bounds now. | 
| Guido van Rossum | ba6ab84 | 2000-12-12 22:02:18 +0000 | [diff] [blame] | 1876 | 		 */ | 
| Tim Peters | afb6ae8 | 2001-06-04 21:00:21 +0000 | [diff] [blame] | 1877 | 		if (i > mp->ma_mask || i < 1) | 
| Guido van Rossum | ba6ab84 | 2000-12-12 22:02:18 +0000 | [diff] [blame] | 1878 | 			i = 1;	/* skip slot 0 */ | 
 | 1879 | 		while ((ep = &mp->ma_table[i])->me_value == NULL) { | 
 | 1880 | 			i++; | 
| Tim Peters | afb6ae8 | 2001-06-04 21:00:21 +0000 | [diff] [blame] | 1881 | 			if (i > mp->ma_mask) | 
| Guido van Rossum | ba6ab84 | 2000-12-12 22:02:18 +0000 | [diff] [blame] | 1882 | 				i = 1; | 
 | 1883 | 		} | 
 | 1884 | 	} | 
| Guido van Rossum | a4dd011 | 2001-04-15 22:16:26 +0000 | [diff] [blame] | 1885 | 	PyTuple_SET_ITEM(res, 0, ep->me_key); | 
 | 1886 | 	PyTuple_SET_ITEM(res, 1, ep->me_value); | 
 | 1887 | 	Py_INCREF(dummy); | 
 | 1888 | 	ep->me_key = dummy; | 
 | 1889 | 	ep->me_value = NULL; | 
 | 1890 | 	mp->ma_used--; | 
 | 1891 | 	assert(mp->ma_table[0].me_value == NULL); | 
 | 1892 | 	mp->ma_table[0].me_hash = i + 1;  /* next place to start */ | 
| Guido van Rossum | ba6ab84 | 2000-12-12 22:02:18 +0000 | [diff] [blame] | 1893 | 	return res; | 
 | 1894 | } | 
 | 1895 |  | 
| Jeremy Hylton | 8caad49 | 2000-06-23 14:18:11 +0000 | [diff] [blame] | 1896 | static int | 
 | 1897 | dict_traverse(PyObject *op, visitproc visit, void *arg) | 
 | 1898 | { | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 1899 | 	Py_ssize_t i = 0; | 
| Jeremy Hylton | 8caad49 | 2000-06-23 14:18:11 +0000 | [diff] [blame] | 1900 | 	PyObject *pk; | 
 | 1901 | 	PyObject *pv; | 
 | 1902 |  | 
 | 1903 | 	while (PyDict_Next(op, &i, &pk, &pv)) { | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1904 | 		Py_VISIT(pk); | 
 | 1905 | 		Py_VISIT(pv); | 
| Jeremy Hylton | 8caad49 | 2000-06-23 14:18:11 +0000 | [diff] [blame] | 1906 | 	} | 
 | 1907 | 	return 0; | 
 | 1908 | } | 
 | 1909 |  | 
 | 1910 | static int | 
 | 1911 | dict_tp_clear(PyObject *op) | 
 | 1912 | { | 
 | 1913 | 	PyDict_Clear(op); | 
 | 1914 | 	return 0; | 
 | 1915 | } | 
 | 1916 |  | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 1917 | static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); | 
| Guido van Rossum | 09e563a | 2001-05-01 12:10:21 +0000 | [diff] [blame] | 1918 |  | 
| Martin v. Löwis | 00709aa | 2008-06-04 14:18:43 +0000 | [diff] [blame] | 1919 | static PyObject * | 
 | 1920 | dict_sizeof(PyDictObject *mp) | 
 | 1921 | { | 
 | 1922 | 	Py_ssize_t res; | 
 | 1923 |  | 
| Robert Schuppenies | 4d45bfe | 2008-06-28 23:58:47 +0000 | [diff] [blame] | 1924 | 	res = sizeof(PyDictObject); | 
| Martin v. Löwis | 00709aa | 2008-06-04 14:18:43 +0000 | [diff] [blame] | 1925 | 	if (mp->ma_table != mp->ma_smalltable) | 
 | 1926 | 		res = res + (mp->ma_mask + 1) * sizeof(PyDictEntry); | 
 | 1927 | 	return PyLong_FromSsize_t(res); | 
 | 1928 | } | 
 | 1929 |  | 
| Raymond Hettinger | 8f5cdaa | 2003-12-13 11:26:12 +0000 | [diff] [blame] | 1930 | PyDoc_STRVAR(contains__doc__, | 
 | 1931 | "D.__contains__(k) -> True if D has a key k, else False"); | 
 | 1932 |  | 
 | 1933 | PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); | 
 | 1934 |  | 
| Martin v. Löwis | 00709aa | 2008-06-04 14:18:43 +0000 | [diff] [blame] | 1935 | PyDoc_STRVAR(sizeof__doc__, | 
 | 1936 | "D.__sizeof__() -> size of D in memory, in bytes"); | 
 | 1937 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1938 | PyDoc_STRVAR(get__doc__, | 
| Guido van Rossum | efae886 | 2002-09-04 11:29:45 +0000 | [diff] [blame] | 1939 | "D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None."); | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1940 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1941 | PyDoc_STRVAR(setdefault_doc__, | 
| Guido van Rossum | efae886 | 2002-09-04 11:29:45 +0000 | [diff] [blame] | 1942 | "D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D"); | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1943 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1944 | PyDoc_STRVAR(pop__doc__, | 
| Benjamin Peterson | f10a79a | 2008-10-11 00:49:57 +0000 | [diff] [blame] | 1945 | "D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n\ | 
| Raymond Hettinger | a3e1e4c | 2003-03-06 23:54:28 +0000 | [diff] [blame] | 1946 | If key is not found, d is returned if given, otherwise KeyError is raised"); | 
| Guido van Rossum | e027d98 | 2002-04-12 15:11:59 +0000 | [diff] [blame] | 1947 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1948 | PyDoc_STRVAR(popitem__doc__, | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1949 | "D.popitem() -> (k, v), remove and return some (key, value) pair as a\n\ | 
| Benjamin Peterson | f10a79a | 2008-10-11 00:49:57 +0000 | [diff] [blame] | 1950 | 2-tuple; but raise KeyError if D is empty."); | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1951 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1952 | PyDoc_STRVAR(update__doc__, | 
| Benjamin Peterson | f10a79a | 2008-10-11 00:49:57 +0000 | [diff] [blame] | 1953 | "D.update(E, **F) -> None.  Update D from dict/iterable E and F.\n" | 
 | 1954 | "If E has a .keys() method, does:     for k in E: D[k] = E[k]\n\ | 
 | 1955 | If E lacks .keys() method, does:     for (k, v) in E: D[k] = v\n\ | 
 | 1956 | In either case, this is followed by: for k in F: D[k] = F[k]"); | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1957 |  | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 1958 | PyDoc_STRVAR(fromkeys__doc__, | 
 | 1959 | "dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\ | 
 | 1960 | v defaults to None."); | 
 | 1961 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1962 | PyDoc_STRVAR(clear__doc__, | 
 | 1963 | "D.clear() -> None.  Remove all items from D."); | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1964 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1965 | PyDoc_STRVAR(copy__doc__, | 
 | 1966 | "D.copy() -> a shallow copy of D"); | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1967 |  | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 1968 | /* Forward */ | 
 | 1969 | static PyObject *dictkeys_new(PyObject *); | 
 | 1970 | static PyObject *dictitems_new(PyObject *); | 
 | 1971 | static PyObject *dictvalues_new(PyObject *); | 
 | 1972 |  | 
| Guido van Rossum | 45c85d1 | 2007-07-27 16:31:40 +0000 | [diff] [blame] | 1973 | PyDoc_STRVAR(keys__doc__, | 
 | 1974 | 	     "D.keys() -> a set-like object providing a view on D's keys"); | 
 | 1975 | PyDoc_STRVAR(items__doc__, | 
 | 1976 | 	     "D.items() -> a set-like object providing a view on D's items"); | 
 | 1977 | PyDoc_STRVAR(values__doc__, | 
 | 1978 | 	     "D.values() -> an object providing a view on D's values"); | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 1979 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1980 | static PyMethodDef mapp_methods[] = { | 
| Guido van Rossum | e2b70bc | 2006-08-18 22:13:04 +0000 | [diff] [blame] | 1981 | 	{"__contains__",(PyCFunction)dict_contains,     METH_O | METH_COEXIST, | 
| Raymond Hettinger | 8f5cdaa | 2003-12-13 11:26:12 +0000 | [diff] [blame] | 1982 | 	 contains__doc__}, | 
| Raymond Hettinger | 0c66967 | 2003-12-13 13:31:55 +0000 | [diff] [blame] | 1983 | 	{"__getitem__", (PyCFunction)dict_subscript,	METH_O | METH_COEXIST, | 
| Raymond Hettinger | 8f5cdaa | 2003-12-13 11:26:12 +0000 | [diff] [blame] | 1984 | 	 getitem__doc__}, | 
| Martin v. Löwis | 00709aa | 2008-06-04 14:18:43 +0000 | [diff] [blame] | 1985 | 	{"__sizeof__",	(PyCFunction)dict_sizeof,	METH_NOARGS, | 
 | 1986 | 	 sizeof__doc__}, | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1987 | 	{"get",         (PyCFunction)dict_get,          METH_VARARGS, | 
 | 1988 | 	 get__doc__}, | 
 | 1989 | 	{"setdefault",  (PyCFunction)dict_setdefault,   METH_VARARGS, | 
 | 1990 | 	 setdefault_doc__}, | 
| Raymond Hettinger | a3e1e4c | 2003-03-06 23:54:28 +0000 | [diff] [blame] | 1991 | 	{"pop",         (PyCFunction)dict_pop,          METH_VARARGS, | 
| Just van Rossum | a797d81 | 2002-11-23 09:45:04 +0000 | [diff] [blame] | 1992 | 	 pop__doc__}, | 
| Martin v. Löwis | e3eb1f2 | 2001-08-16 13:15:00 +0000 | [diff] [blame] | 1993 | 	{"popitem",	(PyCFunction)dict_popitem,	METH_NOARGS, | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 1994 | 	 popitem__doc__}, | 
| Guido van Rossum | cc2b016 | 2007-02-11 06:12:03 +0000 | [diff] [blame] | 1995 | 	{"keys",	(PyCFunction)dictkeys_new,	METH_NOARGS, | 
| Guido van Rossum | eff072c | 2007-02-27 05:47:18 +0000 | [diff] [blame] | 1996 | 	keys__doc__}, | 
| Guido van Rossum | cc2b016 | 2007-02-11 06:12:03 +0000 | [diff] [blame] | 1997 | 	{"items",	(PyCFunction)dictitems_new,	METH_NOARGS, | 
| Guido van Rossum | eff072c | 2007-02-27 05:47:18 +0000 | [diff] [blame] | 1998 | 	items__doc__}, | 
| Guido van Rossum | cc2b016 | 2007-02-11 06:12:03 +0000 | [diff] [blame] | 1999 | 	{"values",	(PyCFunction)dictvalues_new,	METH_NOARGS, | 
| Guido van Rossum | eff072c | 2007-02-27 05:47:18 +0000 | [diff] [blame] | 2000 | 	values__doc__}, | 
| Raymond Hettinger | 31017ae | 2004-03-04 08:25:44 +0000 | [diff] [blame] | 2001 | 	{"update",	(PyCFunction)dict_update,	METH_VARARGS | METH_KEYWORDS, | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 2002 | 	 update__doc__}, | 
| Raymond Hettinger | e33d3df | 2002-11-27 07:29:33 +0000 | [diff] [blame] | 2003 | 	{"fromkeys",	(PyCFunction)dict_fromkeys,	METH_VARARGS | METH_CLASS, | 
 | 2004 | 	 fromkeys__doc__}, | 
| Martin v. Löwis | e3eb1f2 | 2001-08-16 13:15:00 +0000 | [diff] [blame] | 2005 | 	{"clear",	(PyCFunction)dict_clear,	METH_NOARGS, | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 2006 | 	 clear__doc__}, | 
| Martin v. Löwis | e3eb1f2 | 2001-08-16 13:15:00 +0000 | [diff] [blame] | 2007 | 	{"copy",	(PyCFunction)dict_copy,		METH_NOARGS, | 
| Tim Peters | f7f88b1 | 2000-12-13 23:18:45 +0000 | [diff] [blame] | 2008 | 	 copy__doc__}, | 
 | 2009 | 	{NULL,		NULL}	/* sentinel */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 2010 | }; | 
 | 2011 |  | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 2012 | /* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */ | 
| Raymond Hettinger | bc0f2ab | 2003-11-25 21:12:14 +0000 | [diff] [blame] | 2013 | int | 
 | 2014 | PyDict_Contains(PyObject *op, PyObject *key) | 
| Guido van Rossum | 0dbb4fb | 2001-04-20 16:50:40 +0000 | [diff] [blame] | 2015 | { | 
 | 2016 | 	long hash; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2017 | 	PyDictObject *mp = (PyDictObject *)op; | 
 | 2018 | 	PyDictEntry *ep; | 
| Guido van Rossum | 0dbb4fb | 2001-04-20 16:50:40 +0000 | [diff] [blame] | 2019 |  | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 2020 | 	if (!PyUnicode_CheckExact(key) || | 
 | 2021 | 	    (hash = ((PyUnicodeObject *) key)->hash) == -1) { | 
| Guido van Rossum | 0dbb4fb | 2001-04-20 16:50:40 +0000 | [diff] [blame] | 2022 | 		hash = PyObject_Hash(key); | 
 | 2023 | 		if (hash == -1) | 
 | 2024 | 			return -1; | 
 | 2025 | 	} | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 2026 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
 | 2027 | 	return ep == NULL ? -1 : (ep->me_value != NULL); | 
| Guido van Rossum | 0dbb4fb | 2001-04-20 16:50:40 +0000 | [diff] [blame] | 2028 | } | 
 | 2029 |  | 
| Thomas Wouters | cf297e4 | 2007-02-23 15:07:44 +0000 | [diff] [blame] | 2030 | /* Internal version of PyDict_Contains used when the hash value is already known */ | 
 | 2031 | int | 
 | 2032 | _PyDict_Contains(PyObject *op, PyObject *key, long hash) | 
 | 2033 | { | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2034 | 	PyDictObject *mp = (PyDictObject *)op; | 
 | 2035 | 	PyDictEntry *ep; | 
| Thomas Wouters | cf297e4 | 2007-02-23 15:07:44 +0000 | [diff] [blame] | 2036 |  | 
 | 2037 | 	ep = (mp->ma_lookup)(mp, key, hash); | 
 | 2038 | 	return ep == NULL ? -1 : (ep->me_value != NULL); | 
 | 2039 | } | 
 | 2040 |  | 
| Guido van Rossum | 0dbb4fb | 2001-04-20 16:50:40 +0000 | [diff] [blame] | 2041 | /* Hack to implement "key in dict" */ | 
 | 2042 | static PySequenceMethods dict_as_sequence = { | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2043 | 	0,			/* sq_length */ | 
 | 2044 | 	0,			/* sq_concat */ | 
 | 2045 | 	0,			/* sq_repeat */ | 
 | 2046 | 	0,			/* sq_item */ | 
 | 2047 | 	0,			/* sq_slice */ | 
 | 2048 | 	0,			/* sq_ass_item */ | 
 | 2049 | 	0,			/* sq_ass_slice */ | 
 | 2050 | 	PyDict_Contains,	/* sq_contains */ | 
 | 2051 | 	0,			/* sq_inplace_concat */ | 
 | 2052 | 	0,			/* sq_inplace_repeat */ | 
| Guido van Rossum | 0dbb4fb | 2001-04-20 16:50:40 +0000 | [diff] [blame] | 2053 | }; | 
 | 2054 |  | 
| Guido van Rossum | 09e563a | 2001-05-01 12:10:21 +0000 | [diff] [blame] | 2055 | static PyObject * | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2056 | dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
 | 2057 | { | 
 | 2058 | 	PyObject *self; | 
 | 2059 |  | 
 | 2060 | 	assert(type != NULL && type->tp_alloc != NULL); | 
 | 2061 | 	self = type->tp_alloc(type, 0); | 
 | 2062 | 	if (self != NULL) { | 
 | 2063 | 		PyDictObject *d = (PyDictObject *)self; | 
 | 2064 | 		/* It's guaranteed that tp->alloc zeroed out the struct. */ | 
 | 2065 | 		assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0); | 
 | 2066 | 		INIT_NONZERO_DICT_SLOTS(d); | 
| Guido van Rossum | 89d8c60 | 2007-09-18 17:26:56 +0000 | [diff] [blame] | 2067 | 		d->ma_lookup = lookdict_unicode; | 
| Antoine Pitrou | 3a652b1 | 2009-03-23 18:52:06 +0000 | [diff] [blame] | 2068 | 		/* The object has been implicitely tracked by tp_alloc */ | 
 | 2069 | 		if (type == &PyDict_Type) | 
 | 2070 | 			_PyObject_GC_UNTRACK(d); | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2071 | #ifdef SHOW_CONVERSION_COUNTS | 
 | 2072 | 		++created; | 
 | 2073 | #endif | 
| Antoine Pitrou | 3a652b1 | 2009-03-23 18:52:06 +0000 | [diff] [blame] | 2074 | #ifdef SHOW_TRACK_COUNT | 
 | 2075 | 		if (_PyObject_GC_IS_TRACKED(d)) | 
 | 2076 | 			count_tracked++; | 
 | 2077 | 		else | 
 | 2078 | 			count_untracked++; | 
 | 2079 | #endif | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2080 | 	} | 
 | 2081 | 	return self; | 
 | 2082 | } | 
 | 2083 |  | 
| Tim Peters | 25786c0 | 2001-09-02 08:22:48 +0000 | [diff] [blame] | 2084 | static int | 
 | 2085 | dict_init(PyObject *self, PyObject *args, PyObject *kwds) | 
 | 2086 | { | 
| Raymond Hettinger | 31017ae | 2004-03-04 08:25:44 +0000 | [diff] [blame] | 2087 | 	return dict_update_common(self, args, kwds, "dict"); | 
| Tim Peters | 25786c0 | 2001-09-02 08:22:48 +0000 | [diff] [blame] | 2088 | } | 
 | 2089 |  | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2090 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2091 | dict_iter(PyDictObject *dict) | 
| Guido van Rossum | 09e563a | 2001-05-01 12:10:21 +0000 | [diff] [blame] | 2092 | { | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2093 | 	return dictiter_new(dict, &PyDictIterKey_Type); | 
| Guido van Rossum | 09e563a | 2001-05-01 12:10:21 +0000 | [diff] [blame] | 2094 | } | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2095 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 2096 | PyDoc_STRVAR(dictionary_doc, | 
| Tim Peters | a427a2b | 2001-10-29 22:25:45 +0000 | [diff] [blame] | 2097 | "dict() -> new empty dictionary.\n" | 
 | 2098 | "dict(mapping) -> new dictionary initialized from a mapping object's\n" | 
| Tim Peters | 1fc240e | 2001-10-26 05:06:50 +0000 | [diff] [blame] | 2099 | "    (key, value) pairs.\n" | 
| Tim Peters | a427a2b | 2001-10-29 22:25:45 +0000 | [diff] [blame] | 2100 | "dict(seq) -> new dictionary initialized as if via:\n" | 
| Tim Peters | 4d85953 | 2001-10-27 18:27:48 +0000 | [diff] [blame] | 2101 | "    d = {}\n" | 
 | 2102 | "    for k, v in seq:\n" | 
| Just van Rossum | a797d81 | 2002-11-23 09:45:04 +0000 | [diff] [blame] | 2103 | "        d[k] = v\n" | 
 | 2104 | "dict(**kwargs) -> new dictionary initialized with the name=value pairs\n" | 
 | 2105 | "    in the keyword argument list.  For example:  dict(one=1, two=2)"); | 
| Tim Peters | 25786c0 | 2001-09-02 08:22:48 +0000 | [diff] [blame] | 2106 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 2107 | PyTypeObject PyDict_Type = { | 
| Martin v. Löwis | 9f2e346 | 2007-07-21 17:22:18 +0000 | [diff] [blame] | 2108 | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
| Tim Peters | a427a2b | 2001-10-29 22:25:45 +0000 | [diff] [blame] | 2109 | 	"dict", | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2110 | 	sizeof(PyDictObject), | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 2111 | 	0, | 
| Guido van Rossum | b932420 | 2001-01-18 00:39:02 +0000 | [diff] [blame] | 2112 | 	(destructor)dict_dealloc,		/* tp_dealloc */ | 
| Guido van Rossum | 04dbf3b | 2007-08-07 19:51:00 +0000 | [diff] [blame] | 2113 | 	0,					/* tp_print */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2114 | 	0,					/* tp_getattr */ | 
| Guido van Rossum | b932420 | 2001-01-18 00:39:02 +0000 | [diff] [blame] | 2115 | 	0,					/* tp_setattr */ | 
| Mark Dickinson | e94c679 | 2009-02-02 20:36:42 +0000 | [diff] [blame] | 2116 | 	0,					/* tp_reserved */ | 
| Guido van Rossum | b932420 | 2001-01-18 00:39:02 +0000 | [diff] [blame] | 2117 | 	(reprfunc)dict_repr,			/* tp_repr */ | 
 | 2118 | 	0,					/* tp_as_number */ | 
| Guido van Rossum | 0dbb4fb | 2001-04-20 16:50:40 +0000 | [diff] [blame] | 2119 | 	&dict_as_sequence,			/* tp_as_sequence */ | 
| Guido van Rossum | b932420 | 2001-01-18 00:39:02 +0000 | [diff] [blame] | 2120 | 	&dict_as_mapping,			/* tp_as_mapping */ | 
| Nick Coghlan | d1abd25 | 2008-07-15 15:46:38 +0000 | [diff] [blame] | 2121 | 	(hashfunc)PyObject_HashNotImplemented,	/* tp_hash */ | 
| Guido van Rossum | b932420 | 2001-01-18 00:39:02 +0000 | [diff] [blame] | 2122 | 	0,					/* tp_call */ | 
 | 2123 | 	0,					/* tp_str */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2124 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
| Guido van Rossum | b932420 | 2001-01-18 00:39:02 +0000 | [diff] [blame] | 2125 | 	0,					/* tp_setattro */ | 
 | 2126 | 	0,					/* tp_as_buffer */ | 
| Neil Schemenauer | e83c00e | 2001-08-29 23:54:21 +0000 | [diff] [blame] | 2127 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | 
| Thomas Wouters | 27d517b | 2007-02-25 20:39:11 +0000 | [diff] [blame] | 2128 | 		Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS,	/* tp_flags */ | 
| Tim Peters | 25786c0 | 2001-09-02 08:22:48 +0000 | [diff] [blame] | 2129 | 	dictionary_doc,				/* tp_doc */ | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2130 | 	dict_traverse,				/* tp_traverse */ | 
 | 2131 | 	dict_tp_clear,				/* tp_clear */ | 
| Tim Peters | e63415e | 2001-05-08 04:38:29 +0000 | [diff] [blame] | 2132 | 	dict_richcompare,			/* tp_richcompare */ | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2133 | 	0,					/* tp_weaklistoffset */ | 
| Guido van Rossum | 09e563a | 2001-05-01 12:10:21 +0000 | [diff] [blame] | 2134 | 	(getiterfunc)dict_iter,			/* tp_iter */ | 
| Guido van Rossum | 213c7a6 | 2001-04-23 14:08:49 +0000 | [diff] [blame] | 2135 | 	0,					/* tp_iternext */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2136 | 	mapp_methods,				/* tp_methods */ | 
 | 2137 | 	0,					/* tp_members */ | 
 | 2138 | 	0,					/* tp_getset */ | 
 | 2139 | 	0,					/* tp_base */ | 
 | 2140 | 	0,					/* tp_dict */ | 
 | 2141 | 	0,					/* tp_descr_get */ | 
 | 2142 | 	0,					/* tp_descr_set */ | 
 | 2143 | 	0,					/* tp_dictoffset */ | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 2144 | 	dict_init,				/* tp_init */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2145 | 	PyType_GenericAlloc,			/* tp_alloc */ | 
 | 2146 | 	dict_new,				/* tp_new */ | 
| Neil Schemenauer | 6189b89 | 2002-04-12 02:43:00 +0000 | [diff] [blame] | 2147 | 	PyObject_GC_Del,        		/* tp_free */ | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 2148 | }; | 
 | 2149 |  | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2150 | /* For backward compatibility with old dictionary interface */ | 
 | 2151 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 2152 | PyObject * | 
| Martin v. Löwis | 32b4a1b | 2002-12-11 13:21:12 +0000 | [diff] [blame] | 2153 | PyDict_GetItemString(PyObject *v, const char *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 2154 | { | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2155 | 	PyObject *kv, *rv; | 
| Martin v. Löwis | 5b22213 | 2007-06-10 09:51:05 +0000 | [diff] [blame] | 2156 | 	kv = PyUnicode_FromString(key); | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2157 | 	if (kv == NULL) | 
 | 2158 | 		return NULL; | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2159 | 	rv = PyDict_GetItem(v, kv); | 
 | 2160 | 	Py_DECREF(kv); | 
 | 2161 | 	return rv; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 2162 | } | 
 | 2163 |  | 
 | 2164 | int | 
| Martin v. Löwis | 32b4a1b | 2002-12-11 13:21:12 +0000 | [diff] [blame] | 2165 | PyDict_SetItemString(PyObject *v, const char *key, PyObject *item) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 2166 | { | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2167 | 	PyObject *kv; | 
 | 2168 | 	int err; | 
| Martin v. Löwis | 5b22213 | 2007-06-10 09:51:05 +0000 | [diff] [blame] | 2169 | 	kv = PyUnicode_FromString(key); | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2170 | 	if (kv == NULL) | 
| Guido van Rossum | 037b220 | 1997-05-20 18:35:19 +0000 | [diff] [blame] | 2171 | 		return -1; | 
| Martin v. Löwis | 5b22213 | 2007-06-10 09:51:05 +0000 | [diff] [blame] | 2172 | 	PyUnicode_InternInPlace(&kv); /* XXX Should we really? */ | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2173 | 	err = PyDict_SetItem(v, kv, item); | 
 | 2174 | 	Py_DECREF(kv); | 
 | 2175 | 	return err; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 2176 | } | 
 | 2177 |  | 
 | 2178 | int | 
| Martin v. Löwis | 32b4a1b | 2002-12-11 13:21:12 +0000 | [diff] [blame] | 2179 | PyDict_DelItemString(PyObject *v, const char *key) | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 2180 | { | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2181 | 	PyObject *kv; | 
 | 2182 | 	int err; | 
| Martin v. Löwis | 5b22213 | 2007-06-10 09:51:05 +0000 | [diff] [blame] | 2183 | 	kv = PyUnicode_FromString(key); | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2184 | 	if (kv == NULL) | 
| Guido van Rossum | 037b220 | 1997-05-20 18:35:19 +0000 | [diff] [blame] | 2185 | 		return -1; | 
| Guido van Rossum | 3cca245 | 1997-05-16 14:23:33 +0000 | [diff] [blame] | 2186 | 	err = PyDict_DelItem(v, kv); | 
 | 2187 | 	Py_DECREF(kv); | 
 | 2188 | 	return err; | 
| Guido van Rossum | 4b1302b | 1993-03-27 18:11:32 +0000 | [diff] [blame] | 2189 | } | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2190 |  | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2191 | /* Dictionary iterator types */ | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2192 |  | 
 | 2193 | typedef struct { | 
 | 2194 | 	PyObject_HEAD | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2195 | 	PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */ | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 2196 | 	Py_ssize_t di_used; | 
 | 2197 | 	Py_ssize_t di_pos; | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2198 | 	PyObject* di_result; /* reusable result tuple for iteritems */ | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 2199 | 	Py_ssize_t len; | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2200 | } dictiterobject; | 
 | 2201 |  | 
 | 2202 | static PyObject * | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2203 | dictiter_new(PyDictObject *dict, PyTypeObject *itertype) | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2204 | { | 
 | 2205 | 	dictiterobject *di; | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2206 | 	di = PyObject_GC_New(dictiterobject, itertype); | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2207 | 	if (di == NULL) | 
 | 2208 | 		return NULL; | 
 | 2209 | 	Py_INCREF(dict); | 
 | 2210 | 	di->di_dict = dict; | 
| Guido van Rossum | b1f35bf | 2001-05-02 15:13:44 +0000 | [diff] [blame] | 2211 | 	di->di_used = dict->ma_used; | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2212 | 	di->di_pos = 0; | 
| Raymond Hettinger | 0ce6dc8 | 2004-03-18 08:38:00 +0000 | [diff] [blame] | 2213 | 	di->len = dict->ma_used; | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2214 | 	if (itertype == &PyDictIterItem_Type) { | 
 | 2215 | 		di->di_result = PyTuple_Pack(2, Py_None, Py_None); | 
 | 2216 | 		if (di->di_result == NULL) { | 
 | 2217 | 			Py_DECREF(di); | 
 | 2218 | 			return NULL; | 
 | 2219 | 		} | 
 | 2220 | 	} | 
 | 2221 | 	else | 
 | 2222 | 		di->di_result = NULL; | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2223 | 	_PyObject_GC_TRACK(di); | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2224 | 	return (PyObject *)di; | 
 | 2225 | } | 
 | 2226 |  | 
 | 2227 | static void | 
 | 2228 | dictiter_dealloc(dictiterobject *di) | 
 | 2229 | { | 
| Guido van Rossum | 2147df7 | 2002-07-16 20:30:22 +0000 | [diff] [blame] | 2230 | 	Py_XDECREF(di->di_dict); | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2231 | 	Py_XDECREF(di->di_result); | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2232 | 	PyObject_GC_Del(di); | 
 | 2233 | } | 
 | 2234 |  | 
 | 2235 | static int | 
 | 2236 | dictiter_traverse(dictiterobject *di, visitproc visit, void *arg) | 
 | 2237 | { | 
 | 2238 | 	Py_VISIT(di->di_dict); | 
 | 2239 | 	Py_VISIT(di->di_result); | 
 | 2240 | 	return 0; | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2241 | } | 
 | 2242 |  | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2243 | static PyObject * | 
| Raymond Hettinger | 0ce6dc8 | 2004-03-18 08:38:00 +0000 | [diff] [blame] | 2244 | dictiter_len(dictiterobject *di) | 
 | 2245 | { | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 2246 | 	Py_ssize_t len = 0; | 
| Raymond Hettinger | 7892b1c | 2004-04-12 18:10:01 +0000 | [diff] [blame] | 2247 | 	if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used) | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2248 | 		len = di->len; | 
| Christian Heimes | 217cfd1 | 2007-12-02 14:31:20 +0000 | [diff] [blame] | 2249 | 	return PyLong_FromSize_t(len); | 
| Raymond Hettinger | 0ce6dc8 | 2004-03-18 08:38:00 +0000 | [diff] [blame] | 2250 | } | 
 | 2251 |  | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2252 | PyDoc_STRVAR(length_hint_doc, | 
 | 2253 |              "Private method returning an estimate of len(list(it))."); | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2254 |  | 
 | 2255 | static PyMethodDef dictiter_methods[] = { | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2256 | 	{"__length_hint__", (PyCFunction)dictiter_len, METH_NOARGS, | 
 | 2257 |          length_hint_doc}, | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2258 |  	{NULL,		NULL}		/* sentinel */ | 
| Raymond Hettinger | 0ce6dc8 | 2004-03-18 08:38:00 +0000 | [diff] [blame] | 2259 | }; | 
 | 2260 |  | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2261 | static PyObject *dictiter_iternextkey(dictiterobject *di) | 
| Guido van Rossum | 213c7a6 | 2001-04-23 14:08:49 +0000 | [diff] [blame] | 2262 | { | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2263 | 	PyObject *key; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 2264 | 	register Py_ssize_t i, mask; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2265 | 	register PyDictEntry *ep; | 
 | 2266 | 	PyDictObject *d = di->di_dict; | 
| Guido van Rossum | 213c7a6 | 2001-04-23 14:08:49 +0000 | [diff] [blame] | 2267 |  | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2268 | 	if (d == NULL) | 
| Guido van Rossum | 2147df7 | 2002-07-16 20:30:22 +0000 | [diff] [blame] | 2269 | 		return NULL; | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2270 | 	assert (PyDict_Check(d)); | 
| Guido van Rossum | 2147df7 | 2002-07-16 20:30:22 +0000 | [diff] [blame] | 2271 |  | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2272 | 	if (di->di_used != d->ma_used) { | 
| Guido van Rossum | 213c7a6 | 2001-04-23 14:08:49 +0000 | [diff] [blame] | 2273 | 		PyErr_SetString(PyExc_RuntimeError, | 
 | 2274 | 				"dictionary changed size during iteration"); | 
| Guido van Rossum | 2147df7 | 2002-07-16 20:30:22 +0000 | [diff] [blame] | 2275 | 		di->di_used = -1; /* Make this state sticky */ | 
| Guido van Rossum | 213c7a6 | 2001-04-23 14:08:49 +0000 | [diff] [blame] | 2276 | 		return NULL; | 
 | 2277 | 	} | 
| Guido van Rossum | 2147df7 | 2002-07-16 20:30:22 +0000 | [diff] [blame] | 2278 |  | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2279 | 	i = di->di_pos; | 
 | 2280 | 	if (i < 0) | 
 | 2281 | 		goto fail; | 
 | 2282 | 	ep = d->ma_table; | 
 | 2283 | 	mask = d->ma_mask; | 
 | 2284 | 	while (i <= mask && ep[i].me_value == NULL) | 
 | 2285 | 		i++; | 
 | 2286 | 	di->di_pos = i+1; | 
 | 2287 | 	if (i > mask) | 
 | 2288 | 		goto fail; | 
| Raymond Hettinger | 0ce6dc8 | 2004-03-18 08:38:00 +0000 | [diff] [blame] | 2289 | 	di->len--; | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2290 | 	key = ep[i].me_key; | 
 | 2291 | 	Py_INCREF(key); | 
 | 2292 | 	return key; | 
 | 2293 |  | 
 | 2294 | fail: | 
 | 2295 | 	Py_DECREF(d); | 
| Guido van Rossum | 2147df7 | 2002-07-16 20:30:22 +0000 | [diff] [blame] | 2296 | 	di->di_dict = NULL; | 
| Guido van Rossum | 213c7a6 | 2001-04-23 14:08:49 +0000 | [diff] [blame] | 2297 | 	return NULL; | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2298 | } | 
 | 2299 |  | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2300 | PyTypeObject PyDictIterKey_Type = { | 
| Martin v. Löwis | 9f2e346 | 2007-07-21 17:22:18 +0000 | [diff] [blame] | 2301 | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
| Christian Heimes | f83be4e | 2007-11-28 09:44:38 +0000 | [diff] [blame] | 2302 | 	"dict_keyiterator",			/* tp_name */ | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2303 | 	sizeof(dictiterobject),			/* tp_basicsize */ | 
 | 2304 | 	0,					/* tp_itemsize */ | 
 | 2305 | 	/* methods */ | 
 | 2306 | 	(destructor)dictiter_dealloc, 		/* tp_dealloc */ | 
 | 2307 | 	0,					/* tp_print */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2308 | 	0,					/* tp_getattr */ | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2309 | 	0,					/* tp_setattr */ | 
| Mark Dickinson | e94c679 | 2009-02-02 20:36:42 +0000 | [diff] [blame] | 2310 | 	0,					/* tp_reserved */ | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2311 | 	0,					/* tp_repr */ | 
 | 2312 | 	0,					/* tp_as_number */ | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2313 | 	0,					/* tp_as_sequence */ | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2314 | 	0,					/* tp_as_mapping */ | 
 | 2315 | 	0,					/* tp_hash */ | 
 | 2316 | 	0,					/* tp_call */ | 
 | 2317 | 	0,					/* tp_str */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 2318 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2319 | 	0,					/* tp_setattro */ | 
 | 2320 | 	0,					/* tp_as_buffer */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2321 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2322 |  	0,					/* tp_doc */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2323 |  	(traverseproc)dictiter_traverse,	/* tp_traverse */ | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2324 |  	0,					/* tp_clear */ | 
 | 2325 | 	0,					/* tp_richcompare */ | 
 | 2326 | 	0,					/* tp_weaklistoffset */ | 
| Raymond Hettinger | 1da1dbf | 2003-03-17 19:46:11 +0000 | [diff] [blame] | 2327 | 	PyObject_SelfIter,			/* tp_iter */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2328 | 	(iternextfunc)dictiter_iternextkey,	/* tp_iternext */ | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2329 | 	dictiter_methods,			/* tp_methods */ | 
 | 2330 | 	0, | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2331 | }; | 
 | 2332 |  | 
 | 2333 | static PyObject *dictiter_iternextvalue(dictiterobject *di) | 
 | 2334 | { | 
 | 2335 | 	PyObject *value; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 2336 | 	register Py_ssize_t i, mask; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2337 | 	register PyDictEntry *ep; | 
 | 2338 | 	PyDictObject *d = di->di_dict; | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2339 |  | 
 | 2340 | 	if (d == NULL) | 
 | 2341 | 		return NULL; | 
 | 2342 | 	assert (PyDict_Check(d)); | 
 | 2343 |  | 
 | 2344 | 	if (di->di_used != d->ma_used) { | 
 | 2345 | 		PyErr_SetString(PyExc_RuntimeError, | 
 | 2346 | 				"dictionary changed size during iteration"); | 
 | 2347 | 		di->di_used = -1; /* Make this state sticky */ | 
 | 2348 | 		return NULL; | 
 | 2349 | 	} | 
 | 2350 |  | 
 | 2351 | 	i = di->di_pos; | 
| Guido van Rossum | 09240f6 | 2004-03-20 19:11:58 +0000 | [diff] [blame] | 2352 | 	mask = d->ma_mask; | 
 | 2353 | 	if (i < 0 || i > mask) | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2354 | 		goto fail; | 
 | 2355 | 	ep = d->ma_table; | 
| Guido van Rossum | 09240f6 | 2004-03-20 19:11:58 +0000 | [diff] [blame] | 2356 | 	while ((value=ep[i].me_value) == NULL) { | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2357 | 		i++; | 
| Guido van Rossum | 09240f6 | 2004-03-20 19:11:58 +0000 | [diff] [blame] | 2358 | 		if (i > mask) | 
 | 2359 | 			goto fail; | 
 | 2360 | 	} | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2361 | 	di->di_pos = i+1; | 
| Raymond Hettinger | 0ce6dc8 | 2004-03-18 08:38:00 +0000 | [diff] [blame] | 2362 | 	di->len--; | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2363 | 	Py_INCREF(value); | 
 | 2364 | 	return value; | 
 | 2365 |  | 
 | 2366 | fail: | 
 | 2367 | 	Py_DECREF(d); | 
 | 2368 | 	di->di_dict = NULL; | 
 | 2369 | 	return NULL; | 
 | 2370 | } | 
 | 2371 |  | 
 | 2372 | PyTypeObject PyDictIterValue_Type = { | 
| Martin v. Löwis | 9f2e346 | 2007-07-21 17:22:18 +0000 | [diff] [blame] | 2373 | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
| Christian Heimes | f83be4e | 2007-11-28 09:44:38 +0000 | [diff] [blame] | 2374 | 	"dict_valueiterator",			/* tp_name */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2375 | 	sizeof(dictiterobject),			/* tp_basicsize */ | 
 | 2376 | 	0,					/* tp_itemsize */ | 
 | 2377 | 	/* methods */ | 
 | 2378 | 	(destructor)dictiter_dealloc, 		/* tp_dealloc */ | 
 | 2379 | 	0,					/* tp_print */ | 
 | 2380 | 	0,					/* tp_getattr */ | 
 | 2381 | 	0,					/* tp_setattr */ | 
| Mark Dickinson | e94c679 | 2009-02-02 20:36:42 +0000 | [diff] [blame] | 2382 | 	0,					/* tp_reserved */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2383 | 	0,					/* tp_repr */ | 
 | 2384 | 	0,					/* tp_as_number */ | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2385 | 	0,					/* tp_as_sequence */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2386 | 	0,					/* tp_as_mapping */ | 
 | 2387 | 	0,					/* tp_hash */ | 
 | 2388 | 	0,					/* tp_call */ | 
 | 2389 | 	0,					/* tp_str */ | 
 | 2390 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 2391 | 	0,					/* tp_setattro */ | 
 | 2392 | 	0,					/* tp_as_buffer */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2393 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2394 |  	0,					/* tp_doc */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2395 |  	(traverseproc)dictiter_traverse,	/* tp_traverse */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2396 |  	0,					/* tp_clear */ | 
 | 2397 | 	0,					/* tp_richcompare */ | 
 | 2398 | 	0,					/* tp_weaklistoffset */ | 
 | 2399 | 	PyObject_SelfIter,			/* tp_iter */ | 
 | 2400 | 	(iternextfunc)dictiter_iternextvalue,	/* tp_iternext */ | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2401 | 	dictiter_methods,			/* tp_methods */ | 
 | 2402 | 	0, | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2403 | }; | 
 | 2404 |  | 
 | 2405 | static PyObject *dictiter_iternextitem(dictiterobject *di) | 
 | 2406 | { | 
 | 2407 | 	PyObject *key, *value, *result = di->di_result; | 
| Thomas Wouters | 4d70c3d | 2006-06-08 14:42:34 +0000 | [diff] [blame] | 2408 | 	register Py_ssize_t i, mask; | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2409 | 	register PyDictEntry *ep; | 
 | 2410 | 	PyDictObject *d = di->di_dict; | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2411 |  | 
 | 2412 | 	if (d == NULL) | 
 | 2413 | 		return NULL; | 
 | 2414 | 	assert (PyDict_Check(d)); | 
 | 2415 |  | 
 | 2416 | 	if (di->di_used != d->ma_used) { | 
 | 2417 | 		PyErr_SetString(PyExc_RuntimeError, | 
 | 2418 | 				"dictionary changed size during iteration"); | 
 | 2419 | 		di->di_used = -1; /* Make this state sticky */ | 
 | 2420 | 		return NULL; | 
 | 2421 | 	} | 
 | 2422 |  | 
 | 2423 | 	i = di->di_pos; | 
 | 2424 | 	if (i < 0) | 
 | 2425 | 		goto fail; | 
 | 2426 | 	ep = d->ma_table; | 
 | 2427 | 	mask = d->ma_mask; | 
 | 2428 | 	while (i <= mask && ep[i].me_value == NULL) | 
 | 2429 | 		i++; | 
 | 2430 | 	di->di_pos = i+1; | 
 | 2431 | 	if (i > mask) | 
 | 2432 | 		goto fail; | 
 | 2433 |  | 
 | 2434 | 	if (result->ob_refcnt == 1) { | 
 | 2435 | 		Py_INCREF(result); | 
 | 2436 | 		Py_DECREF(PyTuple_GET_ITEM(result, 0)); | 
 | 2437 | 		Py_DECREF(PyTuple_GET_ITEM(result, 1)); | 
 | 2438 | 	} else { | 
 | 2439 | 		result = PyTuple_New(2); | 
| Tim Peters | 60b2996 | 2006-01-01 01:19:23 +0000 | [diff] [blame] | 2440 | 		if (result == NULL) | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2441 | 			return NULL; | 
 | 2442 | 	} | 
| Raymond Hettinger | 0ce6dc8 | 2004-03-18 08:38:00 +0000 | [diff] [blame] | 2443 | 	di->len--; | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2444 | 	key = ep[i].me_key; | 
 | 2445 | 	value = ep[i].me_value; | 
 | 2446 | 	Py_INCREF(key); | 
 | 2447 | 	Py_INCREF(value); | 
 | 2448 | 	PyTuple_SET_ITEM(result, 0, key); | 
 | 2449 | 	PyTuple_SET_ITEM(result, 1, value); | 
 | 2450 | 	return result; | 
 | 2451 |  | 
 | 2452 | fail: | 
 | 2453 | 	Py_DECREF(d); | 
 | 2454 | 	di->di_dict = NULL; | 
 | 2455 | 	return NULL; | 
 | 2456 | } | 
 | 2457 |  | 
 | 2458 | PyTypeObject PyDictIterItem_Type = { | 
| Martin v. Löwis | 9f2e346 | 2007-07-21 17:22:18 +0000 | [diff] [blame] | 2459 | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
| Christian Heimes | f83be4e | 2007-11-28 09:44:38 +0000 | [diff] [blame] | 2460 | 	"dict_itemiterator",			/* tp_name */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2461 | 	sizeof(dictiterobject),			/* tp_basicsize */ | 
 | 2462 | 	0,					/* tp_itemsize */ | 
 | 2463 | 	/* methods */ | 
 | 2464 | 	(destructor)dictiter_dealloc, 		/* tp_dealloc */ | 
 | 2465 | 	0,					/* tp_print */ | 
 | 2466 | 	0,					/* tp_getattr */ | 
 | 2467 | 	0,					/* tp_setattr */ | 
| Mark Dickinson | e94c679 | 2009-02-02 20:36:42 +0000 | [diff] [blame] | 2468 | 	0,					/* tp_reserved */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2469 | 	0,					/* tp_repr */ | 
 | 2470 | 	0,					/* tp_as_number */ | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2471 | 	0,					/* tp_as_sequence */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2472 | 	0,					/* tp_as_mapping */ | 
 | 2473 | 	0,					/* tp_hash */ | 
 | 2474 | 	0,					/* tp_call */ | 
 | 2475 | 	0,					/* tp_str */ | 
 | 2476 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 2477 | 	0,					/* tp_setattro */ | 
 | 2478 | 	0,					/* tp_as_buffer */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2479 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2480 |  	0,					/* tp_doc */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2481 |  	(traverseproc)dictiter_traverse,	/* tp_traverse */ | 
| Raymond Hettinger | 019a148 | 2004-03-18 02:41:19 +0000 | [diff] [blame] | 2482 |  	0,					/* tp_clear */ | 
 | 2483 | 	0,					/* tp_richcompare */ | 
 | 2484 | 	0,					/* tp_weaklistoffset */ | 
 | 2485 | 	PyObject_SelfIter,			/* tp_iter */ | 
 | 2486 | 	(iternextfunc)dictiter_iternextitem,	/* tp_iternext */ | 
| Raymond Hettinger | 6b27cda | 2005-09-24 21:23:05 +0000 | [diff] [blame] | 2487 | 	dictiter_methods,			/* tp_methods */ | 
 | 2488 | 	0, | 
| Guido van Rossum | 59d1d2b | 2001-04-20 19:13:02 +0000 | [diff] [blame] | 2489 | }; | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2490 |  | 
 | 2491 |  | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2492 | /***********************************************/ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2493 | /* View objects for keys(), items(), values(). */ | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2494 | /***********************************************/ | 
 | 2495 |  | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2496 | /* The instance lay-out is the same for all three; but the type differs. */ | 
 | 2497 |  | 
 | 2498 | typedef struct { | 
 | 2499 | 	PyObject_HEAD | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2500 | 	PyDictObject *dv_dict; | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2501 | } dictviewobject; | 
 | 2502 |  | 
 | 2503 |  | 
 | 2504 | static void | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2505 | dictview_dealloc(dictviewobject *dv) | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2506 | { | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2507 | 	Py_XDECREF(dv->dv_dict); | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2508 | 	PyObject_GC_Del(dv); | 
 | 2509 | } | 
 | 2510 |  | 
 | 2511 | static int | 
 | 2512 | dictview_traverse(dictviewobject *dv, visitproc visit, void *arg) | 
 | 2513 | { | 
 | 2514 | 	Py_VISIT(dv->dv_dict); | 
 | 2515 | 	return 0; | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2516 | } | 
 | 2517 |  | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2518 | static Py_ssize_t | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2519 | dictview_len(dictviewobject *dv) | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2520 | { | 
 | 2521 | 	Py_ssize_t len = 0; | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2522 | 	if (dv->dv_dict != NULL) | 
 | 2523 | 		len = dv->dv_dict->ma_used; | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2524 | 	return len; | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2525 | } | 
 | 2526 |  | 
 | 2527 | static PyObject * | 
 | 2528 | dictview_new(PyObject *dict, PyTypeObject *type) | 
 | 2529 | { | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2530 | 	dictviewobject *dv; | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2531 | 	if (dict == NULL) { | 
 | 2532 | 		PyErr_BadInternalCall(); | 
 | 2533 | 		return NULL; | 
 | 2534 | 	} | 
 | 2535 | 	if (!PyDict_Check(dict)) { | 
 | 2536 | 		/* XXX Get rid of this restriction later */ | 
 | 2537 | 		PyErr_Format(PyExc_TypeError, | 
 | 2538 | 			     "%s() requires a dict argument, not '%s'", | 
 | 2539 | 			     type->tp_name, dict->ob_type->tp_name); | 
 | 2540 | 		return NULL; | 
 | 2541 | 	} | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2542 | 	dv = PyObject_GC_New(dictviewobject, type); | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2543 | 	if (dv == NULL) | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2544 | 		return NULL; | 
 | 2545 | 	Py_INCREF(dict); | 
| Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +0000 | [diff] [blame] | 2546 | 	dv->dv_dict = (PyDictObject *)dict; | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2547 | 	_PyObject_GC_TRACK(dv); | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2548 | 	return (PyObject *)dv; | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2549 | } | 
 | 2550 |  | 
| Neal Norwitz | e36f2ba | 2007-02-26 23:12:28 +0000 | [diff] [blame] | 2551 | /* TODO(guido): The views objects are not complete: | 
 | 2552 |  | 
 | 2553 |  * support more set operations | 
 | 2554 |  * support arbitrary mappings? | 
 | 2555 |    - either these should be static or exported in dictobject.h | 
 | 2556 |    - if public then they should probably be in builtins | 
 | 2557 | */ | 
 | 2558 |  | 
| Guido van Rossum | aac530c | 2007-08-24 22:33:45 +0000 | [diff] [blame] | 2559 | /* Return 1 if self is a subset of other, iterating over self; | 
 | 2560 |    0 if not; -1 if an error occurred. */ | 
| Guido van Rossum | d9214d1 | 2007-02-12 02:23:40 +0000 | [diff] [blame] | 2561 | static int | 
 | 2562 | all_contained_in(PyObject *self, PyObject *other) | 
 | 2563 | { | 
 | 2564 | 	PyObject *iter = PyObject_GetIter(self); | 
 | 2565 | 	int ok = 1; | 
 | 2566 |  | 
 | 2567 | 	if (iter == NULL) | 
 | 2568 | 		return -1; | 
 | 2569 | 	for (;;) { | 
 | 2570 | 		PyObject *next = PyIter_Next(iter); | 
 | 2571 | 		if (next == NULL) { | 
 | 2572 | 			if (PyErr_Occurred()) | 
 | 2573 | 				ok = -1; | 
 | 2574 | 			break; | 
 | 2575 | 		} | 
 | 2576 | 		ok = PySequence_Contains(other, next); | 
 | 2577 | 		Py_DECREF(next); | 
 | 2578 | 		if (ok <= 0) | 
 | 2579 | 			break; | 
 | 2580 | 	} | 
 | 2581 | 	Py_DECREF(iter); | 
 | 2582 | 	return ok; | 
 | 2583 | } | 
 | 2584 |  | 
 | 2585 | static PyObject * | 
 | 2586 | dictview_richcompare(PyObject *self, PyObject *other, int op) | 
 | 2587 | { | 
| Guido van Rossum | aac530c | 2007-08-24 22:33:45 +0000 | [diff] [blame] | 2588 | 	Py_ssize_t len_self, len_other; | 
 | 2589 | 	int ok; | 
 | 2590 | 	PyObject *result; | 
 | 2591 |  | 
| Guido van Rossum | d9214d1 | 2007-02-12 02:23:40 +0000 | [diff] [blame] | 2592 | 	assert(self != NULL); | 
 | 2593 | 	assert(PyDictViewSet_Check(self)); | 
 | 2594 | 	assert(other != NULL); | 
| Guido van Rossum | d9214d1 | 2007-02-12 02:23:40 +0000 | [diff] [blame] | 2595 |  | 
| Guido van Rossum | aac530c | 2007-08-24 22:33:45 +0000 | [diff] [blame] | 2596 | 	if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other)) { | 
| Guido van Rossum | d9214d1 | 2007-02-12 02:23:40 +0000 | [diff] [blame] | 2597 | 		Py_INCREF(Py_NotImplemented); | 
 | 2598 | 		return Py_NotImplemented; | 
 | 2599 | 	} | 
| Guido van Rossum | aac530c | 2007-08-24 22:33:45 +0000 | [diff] [blame] | 2600 |  | 
 | 2601 | 	len_self = PyObject_Size(self); | 
 | 2602 | 	if (len_self < 0) | 
 | 2603 | 		return NULL; | 
 | 2604 | 	len_other = PyObject_Size(other); | 
 | 2605 | 	if (len_other < 0) | 
 | 2606 | 		return NULL; | 
 | 2607 |  | 
 | 2608 | 	ok = 0; | 
 | 2609 | 	switch(op) { | 
 | 2610 |  | 
 | 2611 | 	case Py_NE: | 
 | 2612 | 	case Py_EQ: | 
 | 2613 | 		if (len_self == len_other) | 
 | 2614 | 			ok = all_contained_in(self, other); | 
 | 2615 | 		if (op == Py_NE && ok >= 0) | 
 | 2616 | 			ok = !ok; | 
 | 2617 | 		break; | 
 | 2618 |  | 
 | 2619 | 	case Py_LT: | 
 | 2620 | 		if (len_self < len_other) | 
 | 2621 | 			ok = all_contained_in(self, other); | 
 | 2622 | 		break; | 
 | 2623 |  | 
 | 2624 | 	  case Py_LE: | 
 | 2625 | 		  if (len_self <= len_other) | 
 | 2626 | 			  ok = all_contained_in(self, other); | 
 | 2627 | 		  break; | 
 | 2628 |  | 
 | 2629 | 	case Py_GT: | 
 | 2630 | 		if (len_self > len_other) | 
 | 2631 | 			ok = all_contained_in(other, self); | 
 | 2632 | 		break; | 
 | 2633 |  | 
 | 2634 | 	case Py_GE: | 
 | 2635 | 		if (len_self >= len_other) | 
 | 2636 | 			ok = all_contained_in(other, self); | 
 | 2637 | 		break; | 
 | 2638 |  | 
 | 2639 | 	} | 
 | 2640 | 	if (ok < 0) | 
 | 2641 | 		return NULL; | 
 | 2642 | 	result = ok ? Py_True : Py_False; | 
 | 2643 | 	Py_INCREF(result); | 
 | 2644 | 	return result; | 
| Guido van Rossum | d9214d1 | 2007-02-12 02:23:40 +0000 | [diff] [blame] | 2645 | } | 
 | 2646 |  | 
| Raymond Hettinger | b0d56af | 2009-03-03 10:52:49 +0000 | [diff] [blame] | 2647 | static PyObject * | 
 | 2648 | dictview_repr(dictviewobject *dv) | 
 | 2649 | { | 
 | 2650 | 	PyObject *seq; | 
 | 2651 | 	PyObject *result; | 
 | 2652 | 	 | 
 | 2653 | 	seq = PySequence_List((PyObject *)dv); | 
 | 2654 | 	if (seq == NULL) | 
 | 2655 | 		return NULL; | 
 | 2656 |  | 
 | 2657 | 	result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq); | 
 | 2658 | 	Py_DECREF(seq); | 
 | 2659 | 	return result; | 
 | 2660 | } | 
 | 2661 |  | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2662 | /*** dict_keys ***/ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2663 |  | 
 | 2664 | static PyObject * | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2665 | dictkeys_iter(dictviewobject *dv) | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2666 | { | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2667 | 	if (dv->dv_dict == NULL) { | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2668 | 		Py_RETURN_NONE; | 
 | 2669 | 	} | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2670 | 	return dictiter_new(dv->dv_dict, &PyDictIterKey_Type); | 
 | 2671 | } | 
 | 2672 |  | 
 | 2673 | static int | 
 | 2674 | dictkeys_contains(dictviewobject *dv, PyObject *obj) | 
 | 2675 | { | 
 | 2676 | 	if (dv->dv_dict == NULL) | 
 | 2677 | 		return 0; | 
 | 2678 | 	return PyDict_Contains((PyObject *)dv->dv_dict, obj); | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2679 | } | 
 | 2680 |  | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2681 | static PySequenceMethods dictkeys_as_sequence = { | 
 | 2682 | 	(lenfunc)dictview_len,		/* sq_length */ | 
 | 2683 | 	0,				/* sq_concat */ | 
 | 2684 | 	0,				/* sq_repeat */ | 
 | 2685 | 	0,				/* sq_item */ | 
 | 2686 | 	0,				/* sq_slice */ | 
 | 2687 | 	0,				/* sq_ass_item */ | 
 | 2688 | 	0,				/* sq_ass_slice */ | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2689 | 	(objobjproc)dictkeys_contains,	/* sq_contains */ | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2690 | }; | 
 | 2691 |  | 
| Guido van Rossum | 523259b | 2007-08-24 23:41:22 +0000 | [diff] [blame] | 2692 | static PyObject* | 
 | 2693 | dictviews_sub(PyObject* self, PyObject *other) | 
 | 2694 | { | 
 | 2695 | 	PyObject *result = PySet_New(self); | 
 | 2696 | 	PyObject *tmp; | 
 | 2697 | 	if (result == NULL) | 
 | 2698 | 		return NULL; | 
 | 2699 |  | 
 | 2700 | 	tmp = PyObject_CallMethod(result, "difference_update", "O", other); | 
 | 2701 | 	if (tmp == NULL) { | 
 | 2702 | 		Py_DECREF(result); | 
 | 2703 | 		return NULL; | 
 | 2704 | 	} | 
 | 2705 |  | 
 | 2706 | 	Py_DECREF(tmp); | 
 | 2707 | 	return result; | 
 | 2708 | } | 
 | 2709 |  | 
 | 2710 | static PyObject* | 
 | 2711 | dictviews_and(PyObject* self, PyObject *other) | 
 | 2712 | { | 
 | 2713 | 	PyObject *result = PySet_New(self); | 
 | 2714 | 	PyObject *tmp; | 
 | 2715 | 	if (result == NULL) | 
 | 2716 | 		return NULL; | 
 | 2717 |  | 
 | 2718 | 	tmp = PyObject_CallMethod(result, "intersection_update", "O", other); | 
 | 2719 | 	if (tmp == NULL) { | 
 | 2720 | 		Py_DECREF(result); | 
 | 2721 | 		return NULL; | 
 | 2722 | 	} | 
 | 2723 |  | 
 | 2724 | 	Py_DECREF(tmp); | 
 | 2725 | 	return result; | 
 | 2726 | } | 
 | 2727 |  | 
 | 2728 | static PyObject* | 
 | 2729 | dictviews_or(PyObject* self, PyObject *other) | 
 | 2730 | { | 
 | 2731 | 	PyObject *result = PySet_New(self); | 
 | 2732 | 	PyObject *tmp; | 
 | 2733 | 	if (result == NULL) | 
 | 2734 | 		return NULL; | 
 | 2735 |  | 
 | 2736 | 	tmp = PyObject_CallMethod(result, "update", "O", other); | 
 | 2737 | 	if (tmp == NULL) { | 
 | 2738 | 		Py_DECREF(result); | 
 | 2739 | 		return NULL; | 
 | 2740 | 	} | 
 | 2741 |  | 
 | 2742 | 	Py_DECREF(tmp); | 
 | 2743 | 	return result; | 
 | 2744 | } | 
 | 2745 |  | 
 | 2746 | static PyObject* | 
 | 2747 | dictviews_xor(PyObject* self, PyObject *other) | 
 | 2748 | { | 
 | 2749 | 	PyObject *result = PySet_New(self); | 
 | 2750 | 	PyObject *tmp; | 
 | 2751 | 	if (result == NULL) | 
 | 2752 | 		return NULL; | 
 | 2753 |  | 
 | 2754 | 	tmp = PyObject_CallMethod(result, "symmetric_difference_update", "O", | 
 | 2755 | 				  other); | 
 | 2756 | 	if (tmp == NULL) { | 
 | 2757 | 		Py_DECREF(result); | 
 | 2758 | 		return NULL; | 
 | 2759 | 	} | 
 | 2760 |  | 
 | 2761 | 	Py_DECREF(tmp); | 
 | 2762 | 	return result; | 
 | 2763 | } | 
 | 2764 |  | 
 | 2765 | static PyNumberMethods dictviews_as_number = { | 
 | 2766 | 	0,				/*nb_add*/ | 
 | 2767 | 	(binaryfunc)dictviews_sub,	/*nb_subtract*/ | 
 | 2768 | 	0,				/*nb_multiply*/ | 
 | 2769 | 	0,				/*nb_remainder*/ | 
 | 2770 | 	0,				/*nb_divmod*/ | 
 | 2771 | 	0,				/*nb_power*/ | 
 | 2772 | 	0,				/*nb_negative*/ | 
 | 2773 | 	0,				/*nb_positive*/ | 
 | 2774 | 	0,				/*nb_absolute*/ | 
 | 2775 | 	0,				/*nb_bool*/ | 
 | 2776 | 	0,				/*nb_invert*/ | 
 | 2777 | 	0,				/*nb_lshift*/ | 
 | 2778 | 	0,				/*nb_rshift*/ | 
 | 2779 | 	(binaryfunc)dictviews_and,	/*nb_and*/ | 
 | 2780 | 	(binaryfunc)dictviews_xor,	/*nb_xor*/ | 
 | 2781 | 	(binaryfunc)dictviews_or,	/*nb_or*/ | 
 | 2782 | }; | 
 | 2783 |  | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2784 | static PyMethodDef dictkeys_methods[] = { | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2785 |  	{NULL,		NULL}		/* sentinel */ | 
 | 2786 | }; | 
 | 2787 |  | 
 | 2788 | PyTypeObject PyDictKeys_Type = { | 
| Martin v. Löwis | 9f2e346 | 2007-07-21 17:22:18 +0000 | [diff] [blame] | 2789 | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2790 | 	"dict_keys",				/* tp_name */ | 
 | 2791 | 	sizeof(dictviewobject),			/* tp_basicsize */ | 
 | 2792 | 	0,					/* tp_itemsize */ | 
 | 2793 | 	/* methods */ | 
 | 2794 | 	(destructor)dictview_dealloc, 		/* tp_dealloc */ | 
 | 2795 | 	0,					/* tp_print */ | 
 | 2796 | 	0,					/* tp_getattr */ | 
 | 2797 | 	0,					/* tp_setattr */ | 
| Mark Dickinson | e94c679 | 2009-02-02 20:36:42 +0000 | [diff] [blame] | 2798 | 	0,					/* tp_reserved */ | 
| Raymond Hettinger | b0d56af | 2009-03-03 10:52:49 +0000 | [diff] [blame] | 2799 | 	(reprfunc)dictview_repr,		/* tp_repr */ | 
| Guido van Rossum | 523259b | 2007-08-24 23:41:22 +0000 | [diff] [blame] | 2800 | 	&dictviews_as_number,			/* tp_as_number */ | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2801 | 	&dictkeys_as_sequence,			/* tp_as_sequence */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2802 | 	0,					/* tp_as_mapping */ | 
 | 2803 | 	0,					/* tp_hash */ | 
 | 2804 | 	0,					/* tp_call */ | 
 | 2805 | 	0,					/* tp_str */ | 
 | 2806 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 2807 | 	0,					/* tp_setattro */ | 
 | 2808 | 	0,					/* tp_as_buffer */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2809 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2810 |  	0,					/* tp_doc */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2811 |  	(traverseproc)dictview_traverse,	/* tp_traverse */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2812 |  	0,					/* tp_clear */ | 
| Guido van Rossum | d9214d1 | 2007-02-12 02:23:40 +0000 | [diff] [blame] | 2813 | 	dictview_richcompare,			/* tp_richcompare */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2814 | 	0,					/* tp_weaklistoffset */ | 
 | 2815 | 	(getiterfunc)dictkeys_iter,		/* tp_iter */ | 
 | 2816 | 	0,					/* tp_iternext */ | 
 | 2817 | 	dictkeys_methods,			/* tp_methods */ | 
 | 2818 | 	0, | 
 | 2819 | }; | 
 | 2820 |  | 
 | 2821 | static PyObject * | 
 | 2822 | dictkeys_new(PyObject *dict) | 
 | 2823 | { | 
 | 2824 | 	return dictview_new(dict, &PyDictKeys_Type); | 
 | 2825 | } | 
 | 2826 |  | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2827 | /*** dict_items ***/ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2828 |  | 
 | 2829 | static PyObject * | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2830 | dictitems_iter(dictviewobject *dv) | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2831 | { | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2832 | 	if (dv->dv_dict == NULL) { | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2833 | 		Py_RETURN_NONE; | 
 | 2834 | 	} | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2835 | 	return dictiter_new(dv->dv_dict, &PyDictIterItem_Type); | 
 | 2836 | } | 
 | 2837 |  | 
 | 2838 | static int | 
 | 2839 | dictitems_contains(dictviewobject *dv, PyObject *obj) | 
 | 2840 | { | 
 | 2841 | 	PyObject *key, *value, *found; | 
 | 2842 | 	if (dv->dv_dict == NULL) | 
 | 2843 | 		return 0; | 
 | 2844 | 	if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2) | 
 | 2845 | 		return 0; | 
 | 2846 | 	key = PyTuple_GET_ITEM(obj, 0); | 
 | 2847 | 	value = PyTuple_GET_ITEM(obj, 1); | 
 | 2848 | 	found = PyDict_GetItem((PyObject *)dv->dv_dict, key); | 
 | 2849 | 	if (found == NULL) { | 
 | 2850 | 		if (PyErr_Occurred()) | 
 | 2851 | 			return -1; | 
 | 2852 | 		return 0; | 
 | 2853 | 	} | 
 | 2854 | 	return PyObject_RichCompareBool(value, found, Py_EQ); | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2855 | } | 
 | 2856 |  | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2857 | static PySequenceMethods dictitems_as_sequence = { | 
 | 2858 | 	(lenfunc)dictview_len,		/* sq_length */ | 
 | 2859 | 	0,				/* sq_concat */ | 
 | 2860 | 	0,				/* sq_repeat */ | 
 | 2861 | 	0,				/* sq_item */ | 
 | 2862 | 	0,				/* sq_slice */ | 
 | 2863 | 	0,				/* sq_ass_item */ | 
 | 2864 | 	0,				/* sq_ass_slice */ | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2865 | 	(objobjproc)dictitems_contains,	/* sq_contains */ | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2866 | }; | 
 | 2867 |  | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2868 | static PyMethodDef dictitems_methods[] = { | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2869 |  	{NULL,		NULL}		/* sentinel */ | 
 | 2870 | }; | 
 | 2871 |  | 
 | 2872 | PyTypeObject PyDictItems_Type = { | 
| Martin v. Löwis | 9f2e346 | 2007-07-21 17:22:18 +0000 | [diff] [blame] | 2873 | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2874 | 	"dict_items",				/* tp_name */ | 
 | 2875 | 	sizeof(dictviewobject),			/* tp_basicsize */ | 
 | 2876 | 	0,					/* tp_itemsize */ | 
 | 2877 | 	/* methods */ | 
 | 2878 | 	(destructor)dictview_dealloc, 		/* tp_dealloc */ | 
 | 2879 | 	0,					/* tp_print */ | 
 | 2880 | 	0,					/* tp_getattr */ | 
 | 2881 | 	0,					/* tp_setattr */ | 
| Mark Dickinson | e94c679 | 2009-02-02 20:36:42 +0000 | [diff] [blame] | 2882 | 	0,					/* tp_reserved */ | 
| Raymond Hettinger | b0d56af | 2009-03-03 10:52:49 +0000 | [diff] [blame] | 2883 | 	(reprfunc)dictview_repr,		/* tp_repr */ | 
| Guido van Rossum | 523259b | 2007-08-24 23:41:22 +0000 | [diff] [blame] | 2884 | 	&dictviews_as_number,			/* tp_as_number */ | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2885 | 	&dictitems_as_sequence,			/* tp_as_sequence */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2886 | 	0,					/* tp_as_mapping */ | 
 | 2887 | 	0,					/* tp_hash */ | 
 | 2888 | 	0,					/* tp_call */ | 
 | 2889 | 	0,					/* tp_str */ | 
 | 2890 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 2891 | 	0,					/* tp_setattro */ | 
 | 2892 | 	0,					/* tp_as_buffer */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2893 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2894 |  	0,					/* tp_doc */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2895 |  	(traverseproc)dictview_traverse,	/* tp_traverse */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2896 |  	0,					/* tp_clear */ | 
| Guido van Rossum | d9214d1 | 2007-02-12 02:23:40 +0000 | [diff] [blame] | 2897 | 	dictview_richcompare,			/* tp_richcompare */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2898 | 	0,					/* tp_weaklistoffset */ | 
 | 2899 | 	(getiterfunc)dictitems_iter,		/* tp_iter */ | 
 | 2900 | 	0,					/* tp_iternext */ | 
 | 2901 | 	dictitems_methods,			/* tp_methods */ | 
 | 2902 | 	0, | 
 | 2903 | }; | 
 | 2904 |  | 
 | 2905 | static PyObject * | 
 | 2906 | dictitems_new(PyObject *dict) | 
 | 2907 | { | 
 | 2908 | 	return dictview_new(dict, &PyDictItems_Type); | 
 | 2909 | } | 
 | 2910 |  | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2911 | /*** dict_values ***/ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2912 |  | 
 | 2913 | static PyObject * | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2914 | dictvalues_iter(dictviewobject *dv) | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2915 | { | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2916 | 	if (dv->dv_dict == NULL) { | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2917 | 		Py_RETURN_NONE; | 
 | 2918 | 	} | 
| Guido van Rossum | 3ac6741 | 2007-02-10 18:55:06 +0000 | [diff] [blame] | 2919 | 	return dictiter_new(dv->dv_dict, &PyDictIterValue_Type); | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2920 | } | 
 | 2921 |  | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2922 | static PySequenceMethods dictvalues_as_sequence = { | 
 | 2923 | 	(lenfunc)dictview_len,		/* sq_length */ | 
 | 2924 | 	0,				/* sq_concat */ | 
 | 2925 | 	0,				/* sq_repeat */ | 
 | 2926 | 	0,				/* sq_item */ | 
 | 2927 | 	0,				/* sq_slice */ | 
 | 2928 | 	0,				/* sq_ass_item */ | 
 | 2929 | 	0,				/* sq_ass_slice */ | 
 | 2930 | 	(objobjproc)0,			/* sq_contains */ | 
 | 2931 | }; | 
 | 2932 |  | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2933 | static PyMethodDef dictvalues_methods[] = { | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2934 |  	{NULL,		NULL}		/* sentinel */ | 
 | 2935 | }; | 
 | 2936 |  | 
 | 2937 | PyTypeObject PyDictValues_Type = { | 
| Martin v. Löwis | 9f2e346 | 2007-07-21 17:22:18 +0000 | [diff] [blame] | 2938 | 	PyVarObject_HEAD_INIT(&PyType_Type, 0) | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2939 | 	"dict_values",				/* tp_name */ | 
 | 2940 | 	sizeof(dictviewobject),			/* tp_basicsize */ | 
 | 2941 | 	0,					/* tp_itemsize */ | 
 | 2942 | 	/* methods */ | 
 | 2943 | 	(destructor)dictview_dealloc, 		/* tp_dealloc */ | 
 | 2944 | 	0,					/* tp_print */ | 
 | 2945 | 	0,					/* tp_getattr */ | 
 | 2946 | 	0,					/* tp_setattr */ | 
| Mark Dickinson | e94c679 | 2009-02-02 20:36:42 +0000 | [diff] [blame] | 2947 | 	0,					/* tp_reserved */ | 
| Raymond Hettinger | b0d56af | 2009-03-03 10:52:49 +0000 | [diff] [blame] | 2948 | 	(reprfunc)dictview_repr,		/* tp_repr */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2949 | 	0,					/* tp_as_number */ | 
| Guido van Rossum | 83825ac | 2007-02-10 04:54:19 +0000 | [diff] [blame] | 2950 | 	&dictvalues_as_sequence,		/* tp_as_sequence */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2951 | 	0,					/* tp_as_mapping */ | 
 | 2952 | 	0,					/* tp_hash */ | 
 | 2953 | 	0,					/* tp_call */ | 
 | 2954 | 	0,					/* tp_str */ | 
 | 2955 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 2956 | 	0,					/* tp_setattro */ | 
 | 2957 | 	0,					/* tp_as_buffer */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2958 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2959 |  	0,					/* tp_doc */ | 
| Antoine Pitrou | 7ddda78 | 2009-01-01 15:35:33 +0000 | [diff] [blame] | 2960 |  	(traverseproc)dictview_traverse,	/* tp_traverse */ | 
| Guido van Rossum | b90c848 | 2007-02-10 01:11:45 +0000 | [diff] [blame] | 2961 |  	0,					/* tp_clear */ | 
 | 2962 | 	0,					/* tp_richcompare */ | 
 | 2963 | 	0,					/* tp_weaklistoffset */ | 
 | 2964 | 	(getiterfunc)dictvalues_iter,		/* tp_iter */ | 
 | 2965 | 	0,					/* tp_iternext */ | 
 | 2966 | 	dictvalues_methods,			/* tp_methods */ | 
 | 2967 | 	0, | 
 | 2968 | }; | 
 | 2969 |  | 
 | 2970 | static PyObject * | 
 | 2971 | dictvalues_new(PyObject *dict) | 
 | 2972 | { | 
 | 2973 | 	return dictview_new(dict, &PyDictValues_Type); | 
 | 2974 | } |