diff -r 64afd5cab40a Include/dictobject.h --- a/Include/dictobject.h Tue Dec 13 19:03:51 2016 -0500 +++ b/Include/dictobject.h Wed Dec 14 11:47:12 2016 +0200 @@ -21,10 +21,7 @@ typedef struct _dictkeysobject PyDictKey * or points to an array of PyObject* for a split table */ typedef struct { - PyObject_HEAD - - /* Number of items in the dictionary */ - Py_ssize_t ma_used; + PyObject_VAR_HEAD /* Dictionary version: globally unique, value change each time the dictionary is modified */ @@ -106,6 +103,8 @@ PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObj PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); #ifndef Py_LIMITED_API +/* Get the number of items of a dictionary. */ +#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),Py_SIZE(mp)) PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash); PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); diff -r 64afd5cab40a Include/odictobject.h --- a/Include/odictobject.h Tue Dec 13 19:03:51 2016 -0500 +++ b/Include/odictobject.h Wed Dec 14 11:47:12 2016 +0200 @@ -21,7 +21,7 @@ PyAPI_DATA(PyTypeObject) PyODictValues_T #define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) #define PyODict_CheckExact(op) (Py_TYPE(op) == &PyODict_Type) -#define PyODict_SIZE(op) ((PyDictObject *)op)->ma_used +#define PyODict_SIZE(op) PyDict_GET_SIZE((op)) #define PyODict_HasKey(od, key) (PyMapping_HasKey(PyObject *)od, key) PyAPI_FUNC(PyObject *) PyODict_New(void); diff -r 64afd5cab40a Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/_ctypes/_ctypes.c Wed Dec 14 11:47:12 2016 +0200 @@ -3684,7 +3684,7 @@ static PyObject * must be the same as len(inargs) + len(kwds), otherwise we have either too much or not enough arguments. */ - actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0); + actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_GET_SIZE(kwds) : 0); if (actual_args != inargs_index) { /* When we have default values or named parameters, this error message is misleading. See unittests/test_paramflags.py diff -r 64afd5cab40a Modules/_datetimemodule.c --- a/Modules/_datetimemodule.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/_datetimemodule.c Wed Dec 14 11:47:12 2016 +0200 @@ -3169,7 +3169,8 @@ tzinfo_reduce(PyObject *self) PyErr_Clear(); state = Py_None; dictptr = _PyObject_GetDictPtr(self); - if (dictptr && *dictptr && PyDict_Size(*dictptr)) { + if (dictptr && *dictptr && + (!PyDict_Check(*dictptr) || PyDict_GET_SIZE(*dictptr))) { state = *dictptr; } Py_INCREF(state); diff -r 64afd5cab40a Modules/_decimal/_decimal.c --- a/Modules/_decimal/_decimal.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/_decimal/_decimal.c Wed Dec 14 11:47:12 2016 +0200 @@ -428,7 +428,7 @@ dict_as_flags(PyObject *val) return DEC_INVALID_SIGNALS; } - if (PyDict_Size(val) != SIGNAL_MAP_LEN) { + if (PyDict_GET_SIZE(val) != SIGNAL_MAP_LEN) { PyErr_SetString(PyExc_KeyError, "invalid signal dict"); return DEC_INVALID_SIGNALS; diff -r 64afd5cab40a Modules/_elementtree.c --- a/Modules/_elementtree.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/_elementtree.c Wed Dec 14 11:47:12 2016 +0200 @@ -150,7 +150,7 @@ list_join(PyObject* list) static int is_empty_dict(PyObject *obj) { - return PyDict_CheckExact(obj) && PyDict_Size(obj) == 0; + return PyDict_CheckExact(obj) && PyDict_GET_SIZE(obj) == 0; } diff -r 64afd5cab40a Modules/_functoolsmodule.c --- a/Modules/_functoolsmodule.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/_functoolsmodule.c Wed Dec 14 11:47:12 2016 +0200 @@ -84,7 +84,7 @@ partial_new(PyTypeObject *type, PyObject } Py_DECREF(nargs); - if (pkw == NULL || PyDict_Size(pkw) == 0) { + if (pkw == NULL || PyDict_GET_SIZE(pkw) == 0) { if (kw == NULL) { pto->kw = PyDict_New(); } @@ -155,7 +155,7 @@ partial_call(partialobject *pto, PyObjec assert(PyTuple_Check(argappl)); } - if (PyDict_Size(pto->kw) == 0) { + if (PyDict_GET_SIZE(pto->kw) == 0) { kwappl = kw; Py_XINCREF(kwappl); } @@ -713,7 +713,7 @@ lru_cache_make_key(PyObject *args, PyObj return args; } - if (kwds && PyDict_Size(kwds) > 0) { + if (kwds && PyDict_GET_SIZE(kwds) > 0) { sorted_items = PyDict_Items(kwds); if (!sorted_items) return NULL; @@ -933,7 +933,7 @@ bounded_lru_cache_wrapper(lru_cache_obje } lru_cache_append_link(self, link); Py_INCREF(result); /* for return */ - self->full = (PyDict_Size(self->cache) >= self->maxsize); + self->full = (PyDict_GET_SIZE(self->cache) >= self->maxsize); } self->misses++; return result; @@ -1062,7 +1062,7 @@ lru_cache_cache_info(lru_cache_object *s { return PyObject_CallFunction(self->cache_info_type, "nnOn", self->hits, self->misses, self->maxsize_O, - PyDict_Size(self->cache)); + PyDict_GET_SIZE(self->cache)); } static PyObject * diff -r 64afd5cab40a Modules/_operator.c --- a/Modules/_operator.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/_operator.c Wed Dec 14 11:47:12 2016 +0200 @@ -1016,16 +1016,7 @@ methodcaller_repr(methodcallerobject *mc return PyUnicode_FromFormat("%s(...)", Py_TYPE(mc)->tp_name); } - if (mc->kwds != NULL) { - numkwdargs = PyDict_Size(mc->kwds); - if (numkwdargs < 0) { - Py_ReprLeave((PyObject *)mc); - return NULL; - } - } else { - numkwdargs = 0; - } - + numkwdargs = mc->kwds != NULL ? PyDict_GET_SIZE(mc->kwds) : 0; numposargs = PyTuple_GET_SIZE(mc->args); numtotalargs = numposargs + numkwdargs; @@ -1092,7 +1083,7 @@ static PyObject * methodcaller_reduce(methodcallerobject *mc) { PyObject *newargs; - if (!mc->kwds || PyDict_Size(mc->kwds) == 0) { + if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) { Py_ssize_t i; Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args); newargs = PyTuple_New(1 + callargcount); diff -r 64afd5cab40a Modules/_pickle.c --- a/Modules/_pickle.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/_pickle.c Wed Dec 14 11:47:12 2016 +0200 @@ -2787,10 +2787,10 @@ batch_dict_exact(PicklerObject *self, Py const char setitem_op = SETITEM; const char setitems_op = SETITEMS; - assert(obj != NULL); + assert(obj != NULL && PyDict_CheckExact(obj)); assert(self->proto > 0); - dict_size = PyDict_Size(obj); + dict_size = PyDict_GET_SIZE(obj); /* Special-case len(d) == 1 to save space. */ if (dict_size == 1) { @@ -2819,7 +2819,7 @@ batch_dict_exact(PicklerObject *self, Py } if (_Pickler_Write(self, &setitems_op, 1) < 0) return -1; - if (PyDict_Size(obj) != dict_size) { + if (PyDict_GET_SIZE(obj) != dict_size) { PyErr_Format( PyExc_RuntimeError, "dictionary changed size during iteration"); @@ -2837,6 +2837,7 @@ save_dict(PicklerObject *self, PyObject char header[3]; Py_ssize_t len; int status = 0; + assert(PyDict_Check(obj)); if (self->fast && !fast_save_enter(self, obj)) goto error; @@ -2855,14 +2856,10 @@ save_dict(PicklerObject *self, PyObject if (_Pickler_Write(self, header, len) < 0) goto error; - /* Get dict size, and bow out early if empty. */ - if ((len = PyDict_Size(obj)) < 0) - goto error; - if (memo_put(self, obj) < 0) goto error; - if (len != 0) { + if (PyDict_GET_SIZE(obj)) { /* Save the dict items. */ if (PyDict_CheckExact(obj) && self->proto > 0) { /* We can take certain shortcuts if we know this is a dict and @@ -6878,7 +6875,7 @@ Unpickler_set_memo(UnpicklerObject *self Py_ssize_t i = 0; PyObject *key, *value; - new_memo_size = PyDict_Size(obj); + new_memo_size = PyDict_GET_SIZE(obj); new_memo = _Unpickler_NewMemo(new_memo_size); if (new_memo == NULL) return -1; diff -r 64afd5cab40a Modules/_sqlite/cache.c --- a/Modules/_sqlite/cache.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/_sqlite/cache.c Wed Dec 14 11:47:12 2016 +0200 @@ -162,7 +162,7 @@ PyObject* pysqlite_cache_get(pysqlite_Ca * entry in the cache, and make space if necessary by throwing the * least used item out of the cache. */ - if (PyDict_Size(self->mapping) == self->size) { + if (PyDict_GET_SIZE(self->mapping) == self->size) { if (self->last) { node = self->last; diff -r 64afd5cab40a Modules/_struct.c --- a/Modules/_struct.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/_struct.c Wed Dec 14 11:47:12 2016 +0200 @@ -2048,7 +2048,7 @@ cache_struct(PyObject *fmt) s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL); if (s_object != NULL) { - if (PyDict_Size(cache) >= MAXCACHE) + if (PyDict_GET_SIZE(cache) >= MAXCACHE) PyDict_Clear(cache); /* Attempt to cache the result */ if (PyDict_SetItem(cache, fmt, s_object) == -1) diff -r 64afd5cab40a Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/itertoolsmodule.c Wed Dec 14 11:47:12 2016 +0200 @@ -4180,7 +4180,7 @@ repeat_new(PyTypeObject *type, PyObject return NULL; if (kwds != NULL) - n_kwds = PyDict_Size(kwds); + n_kwds = PyDict_GET_SIZE(kwds); /* Does user supply times argument? */ if ((PyTuple_Size(args) + n_kwds == 2) && cnt < 0) cnt = 0; @@ -4331,9 +4331,9 @@ zip_longest_new(PyTypeObject *type, PyOb PyObject *fillvalue = Py_None; Py_ssize_t tuplesize = PySequence_Length(args); - if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_Size(kwds) > 0) { + if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_GET_SIZE(kwds) > 0) { fillvalue = PyDict_GetItemString(kwds, "fillvalue"); - if (fillvalue == NULL || PyDict_Size(kwds) > 1) { + if (fillvalue == NULL || PyDict_GET_SIZE(kwds) > 1) { PyErr_SetString(PyExc_TypeError, "zip_longest() got an unexpected keyword argument"); return NULL; diff -r 64afd5cab40a Modules/selectmodule.c --- a/Modules/selectmodule.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Modules/selectmodule.c Wed Dec 14 11:47:12 2016 +0200 @@ -353,7 +353,7 @@ update_ufd_array(pollObject *self) PyObject *key, *value; struct pollfd *old_ufds = self->ufds; - self->ufd_len = PyDict_Size(self->dict); + self->ufd_len = PyDict_GET_SIZE(self->dict); PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len); if (self->ufds == NULL) { self->ufds = old_ufds; diff -r 64afd5cab40a Objects/abstract.c --- a/Objects/abstract.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/abstract.c Wed Dec 14 11:47:12 2016 +0200 @@ -2409,8 +2409,7 @@ PyObject ** assert(nargs >= 0); assert(kwargs == NULL || PyDict_CheckExact(kwargs)); - nkwargs = (kwargs != NULL) ? PyDict_Size(kwargs) : 0; - if (!nkwargs) { + if (kwargs == NULL || (nkwargs = PyDict_GET_SIZE(kwargs)) == 0) { *p_kwnames = NULL; return args; } diff -r 64afd5cab40a Objects/descrobject.c --- a/Objects/descrobject.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/descrobject.c Wed Dec 14 11:47:12 2016 +0200 @@ -1173,7 +1173,7 @@ wrapper_call(wrapperobject *wp, PyObject return (*wk)(self, args, wp->descr->d_wrapped, kwds); } - if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) { + if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) { PyErr_Format(PyExc_TypeError, "wrapper %s doesn't take keyword arguments", wp->descr->d_base->name); diff -r 64afd5cab40a Objects/dictobject.c --- a/Objects/dictobject.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/dictobject.c Wed Dec 14 11:47:12 2016 +0200 @@ -97,7 +97,7 @@ dk_indices, we can't increment dk_usable decremented. In split table, inserting into pending entry is allowed only for dk_entries[ix] -where ix == mp->ma_used. Inserting into other index and deleting item cause +where ix == PyDict_GET_SIZE(mp). Inserting into other index and deleting item cause converting the dict to the combined table. */ @@ -409,7 +409,7 @@ dk_set_index(PyDictKeysObject *keys, Py_ * GROWTH_RATE was set to used*4 up to version 3.2. * GROWTH_RATE was set to used*2 in version 3.3.0 */ -#define GROWTH_RATE(d) (((d)->ma_used*2)+((d)->ma_keys->dk_size>>1)) +#define GROWTH_RATE(d) (PyDict_GET_SIZE(d)*2+((d)->ma_keys->dk_size>>1)) #define ENSURE_ALLOWS_DELETIONS(d) \ if ((d)->ma_keys->dk_lookup == lookdict_unicode_nodummy) { \ @@ -449,7 +449,7 @@ static int Py_ssize_t i; #endif - assert(0 <= mp->ma_used && mp->ma_used <= usable); + assert(0 <= PyDict_GET_SIZE(mp) && PyDict_GET_SIZE(mp) <= usable); assert(IS_POWER_OF_2(keys->dk_size)); assert(0 <= keys->dk_usable && keys->dk_usable <= usable); @@ -494,7 +494,7 @@ static int if (splitted) { /* splitted table */ - for (i=0; i < mp->ma_used; i++) { + for (i=0; i < PyDict_GET_SIZE(mp); i++) { assert(mp->ma_values[i] != NULL); } } @@ -593,7 +593,7 @@ new_dict(PyDictKeysObject *keys, PyObjec } mp->ma_keys = keys; mp->ma_values = values; - mp->ma_used = 0; + Py_SIZE(mp) = 0; mp->ma_version_tag = DICT_NEXT_VERSION(); assert(_PyDict_CheckConsistency(mp)); return (PyObject *)mp; @@ -1124,8 +1124,8 @@ insertdict(PyDictObject *mp, PyObject *k * the key anymore. Convert this instance to combine table. */ if (_PyDict_HasSplitTable(mp) && - ((ix >= 0 && old_value == NULL && mp->ma_used != ix) || - (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) { + ((ix >= 0 && old_value == NULL && PyDict_GET_SIZE(mp) != ix) || + (ix == DKIX_EMPTY && PyDict_GET_SIZE(mp) != mp->ma_keys->dk_nentries))) { if (insertion_resize(mp) < 0) { Py_DECREF(value); return -1; @@ -1157,7 +1157,7 @@ insertdict(PyDictObject *mp, PyObject *k else { ep->me_value = value; } - mp->ma_used++; + Py_SIZE(mp)++; mp->ma_version_tag = DICT_NEXT_VERSION(); mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; @@ -1170,8 +1170,8 @@ insertdict(PyDictObject *mp, PyObject *k mp->ma_values[ix] = value; if (old_value == NULL) { /* pending state */ - assert(ix == mp->ma_used); - mp->ma_used++; + assert(ix == PyDict_GET_SIZE(mp)); + Py_SIZE(mp)++; } } else { @@ -1247,7 +1247,7 @@ dictresize(PyDictObject *mp, Py_ssize_t if (oldkeys->dk_lookup == lookdict) mp->ma_keys->dk_lookup = lookdict; - numentries = mp->ma_used; + numentries = PyDict_GET_SIZE(mp); oldentries = DK_ENTRIES(oldkeys); newentries = DK_ENTRIES(mp->ma_keys); oldvalues = mp->ma_values; @@ -1631,7 +1631,7 @@ int } assert(old_value != NULL); - mp->ma_used--; + Py_SIZE(mp)--; mp->ma_version_tag = DICT_NEXT_VERSION(); ep = &DK_ENTRIES(mp->ma_keys)[ix]; dk_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); @@ -1665,7 +1665,7 @@ PyDict_Clear(PyObject *op) DK_INCREF(Py_EMPTY_KEYS); mp->ma_keys = Py_EMPTY_KEYS; mp->ma_values = empty_values; - mp->ma_used = 0; + Py_SIZE(mp) = 0; mp->ma_version_tag = DICT_NEXT_VERSION(); /* ...then clear the keys and values */ if (oldvalues != NULL) { @@ -1701,7 +1701,7 @@ int mp = (PyDictObject *)op; i = *ppos; if (mp->ma_values) { - if (i < 0 || i >= mp->ma_used) + if (i < 0 || i >= PyDict_GET_SIZE(mp)) return 0; /* values of split table is always dense */ entry_ptr = &DK_ENTRIES(mp->ma_keys)[i]; @@ -1768,7 +1768,7 @@ PyObject * assert(PyDict_Check(dict)); mp = (PyDictObject *)dict; - if (mp->ma_used == 0) { + if (PyDict_GET_SIZE(mp) == 0) { if (deflt) { Py_INCREF(deflt); return deflt; @@ -1804,7 +1804,7 @@ PyObject * } assert(old_value != NULL); - mp->ma_used--; + Py_SIZE(mp)--; mp->ma_version_tag = DICT_NEXT_VERSION(); dk_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); ep = &DK_ENTRIES(mp->ma_keys)[ix]; @@ -1831,7 +1831,7 @@ PyObject * if (d == NULL) return NULL; - if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) { + if (PyDict_CheckExact(d) && PyDict_GET_SIZE(d) == 0) { if (PyDict_CheckExact(iterable)) { PyDictObject *mp = (PyDictObject *)d; PyObject *oldvalue; @@ -1950,7 +1950,7 @@ dict_repr(PyDictObject *mp) return i > 0 ? PyUnicode_FromString("{...}") : NULL; } - if (mp->ma_used == 0) { + if (PyDict_GET_SIZE(mp) == 0) { Py_ReprLeave((PyObject *)mp); return PyUnicode_FromString("{}"); } @@ -1958,7 +1958,7 @@ dict_repr(PyDictObject *mp) _PyUnicodeWriter_Init(&writer); writer.overallocate = 1; /* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */ - writer.min_length = 1 + 4 + (2 + 4) * (mp->ma_used - 1) + 1; + writer.min_length = 1 + 4 + (2 + 4) * (PyDict_GET_SIZE(mp) - 1) + 1; if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0) goto error; @@ -2023,7 +2023,7 @@ error: static Py_ssize_t dict_length(PyDictObject *mp) { - return mp->ma_used; + return PyDict_GET_SIZE(mp); } static PyObject * @@ -2089,11 +2089,11 @@ dict_keys(PyDictObject *mp) PyObject **value_ptr; again: - n = mp->ma_used; + n = PyDict_GET_SIZE(mp); v = PyList_New(n); if (v == NULL) return NULL; - if (n != mp->ma_used) { + if (n != PyDict_GET_SIZE(mp)) { /* Durnit. The allocations caused the dict to resize. * Just start over, this shouldn't normally happen. */ @@ -2133,11 +2133,11 @@ dict_values(PyDictObject *mp) PyObject **value_ptr; again: - n = mp->ma_used; + n = PyDict_GET_SIZE(mp); v = PyList_New(n); if (v == NULL) return NULL; - if (n != mp->ma_used) { + if (n != PyDict_GET_SIZE(mp)) { /* Durnit. The allocations caused the dict to resize. * Just start over, this shouldn't normally happen. */ @@ -2182,7 +2182,7 @@ dict_items(PyDictObject *mp) * could resize the dict. :-( */ again: - n = mp->ma_used; + n = PyDict_GET_SIZE(mp); v = PyList_New(n); if (v == NULL) return NULL; @@ -2194,7 +2194,7 @@ dict_items(PyDictObject *mp) } PyList_SET_ITEM(v, i, item); } - if (n != mp->ma_used) { + if (n != PyDict_GET_SIZE(mp)) { /* Durnit. The allocations caused the dict to resize. * Just start over, this shouldn't normally happen. */ @@ -2382,10 +2382,10 @@ dict_merge(PyObject *a, PyObject *b, int mp = (PyDictObject*)a; if (PyDict_Check(b)) { other = (PyDictObject*)b; - if (other == mp || other->ma_used == 0) + if (other == mp || PyDict_GET_SIZE(other) == 0) /* a.update(a) or a.update({}); nothing to do */ return 0; - if (mp->ma_used == 0) + if (PyDict_GET_SIZE(mp) == 0) /* Since the target dict is empty, PyDict_GetItem() * always returns NULL. Setting override to 1 * skips the unnecessary test. @@ -2395,8 +2395,8 @@ dict_merge(PyObject *a, PyObject *b, int * incrementally resizing as we insert new items. Expect * that there will be no (or few) overlapping keys. */ - if (USABLE_FRACTION(mp->ma_keys->dk_size) < other->ma_used) { - if (dictresize(mp, ESTIMATE_SIZE(mp->ma_used + other->ma_used))) { + if (USABLE_FRACTION(mp->ma_keys->dk_size) < PyDict_GET_SIZE(other)) { + if (dictresize(mp, ESTIMATE_SIZE(PyDict_GET_SIZE(mp) + PyDict_GET_SIZE(other)))) { return -1; } } @@ -2550,7 +2550,7 @@ PyDict_Copy(PyObject *o) } split_copy->ma_values = newvalues; split_copy->ma_keys = mp->ma_keys; - split_copy->ma_used = mp->ma_used; + Py_SIZE(split_copy) = Py_SIZE(mp); DK_INCREF(mp->ma_keys); for (i = 0, n = size; i < n; i++) { PyObject *value = mp->ma_values[i]; @@ -2577,7 +2577,7 @@ PyDict_Size(PyObject *mp) PyErr_BadInternalCall(); return -1; } - return ((PyDictObject *)mp)->ma_used; + return PyDict_GET_SIZE(mp); } PyObject * @@ -2619,7 +2619,7 @@ dict_equal(PyDictObject *a, PyDictObject { Py_ssize_t i; - if (a->ma_used != b->ma_used) + if (PyDict_GET_SIZE(a) != PyDict_GET_SIZE(b)) /* can't be equal if # of entries differ */ return 0; /* Same # of entries -- check all of 'em. Exit early on any diff. */ @@ -2770,8 +2770,8 @@ PyDict_SetDefault(PyObject *d, PyObject return NULL; if (_PyDict_HasSplitTable(mp) && - ((ix >= 0 && value == NULL && mp->ma_used != ix) || - (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) { + ((ix >= 0 && value == NULL && PyDict_GET_SIZE(mp) != ix) || + (ix == DKIX_EMPTY && PyDict_GET_SIZE(mp) != mp->ma_keys->dk_nentries))) { if (insertion_resize(mp) < 0) { return NULL; } @@ -2803,7 +2803,7 @@ PyDict_SetDefault(PyObject *d, PyObject else { ep->me_value = value; } - mp->ma_used++; + Py_SIZE(mp)++; mp->ma_version_tag = DICT_NEXT_VERSION(); mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; @@ -2812,11 +2812,11 @@ PyDict_SetDefault(PyObject *d, PyObject else if (value == NULL) { value = defaultobj; assert(_PyDict_HasSplitTable(mp)); - assert(ix == mp->ma_used); + assert(ix == PyDict_GET_SIZE(mp)); Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); mp->ma_values[ix] = value; - mp->ma_used++; + Py_SIZE(mp)++; mp->ma_version_tag = DICT_NEXT_VERSION(); } @@ -2875,7 +2875,7 @@ dict_popitem(PyDictObject *mp) res = PyTuple_New(2); if (res == NULL) return NULL; - if (mp->ma_used == 0) { + if (PyDict_GET_SIZE(mp) == 0) { Py_DECREF(res); PyErr_SetString(PyExc_KeyError, "popitem(): dictionary is empty"); @@ -2910,7 +2910,7 @@ dict_popitem(PyDictObject *mp) ep->me_value = NULL; /* We can't dk_usable++ since there is DKIX_DUMMY in indices */ mp->ma_keys->dk_nentries = i; - mp->ma_used--; + Py_SIZE(mp)--; mp->ma_version_tag = DICT_NEXT_VERSION(); assert(_PyDict_CheckConsistency(mp)); return res; @@ -3130,7 +3130,7 @@ dict_new(PyTypeObject *type, PyObject *a if (type == &PyDict_Type) _PyObject_GC_UNTRACK(d); - d->ma_used = 0; + Py_SIZE(d) = 0; d->ma_version_tag = DICT_NEXT_VERSION(); d->ma_keys = new_keys_object(PyDict_MINSIZE); if (d->ma_keys == NULL) { @@ -3301,9 +3301,9 @@ dictiter_new(PyDictObject *dict, PyTypeO return NULL; Py_INCREF(dict); di->di_dict = dict; - di->di_used = dict->ma_used; + di->di_used = PyDict_GET_SIZE(dict); di->di_pos = 0; - di->len = dict->ma_used; + di->len = PyDict_GET_SIZE(dict); if (itertype == &PyDictIterItem_Type) { di->di_result = PyTuple_Pack(2, Py_None, Py_None); if (di->di_result == NULL) { @@ -3337,7 +3337,7 @@ static PyObject * dictiter_len(dictiterobject *di) { Py_ssize_t len = 0; - if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used) + if (di->di_dict != NULL && di->di_used == PyDict_GET_SIZE(di->di_dict)) len = di->len; return PyLong_FromSize_t(len); } @@ -3370,7 +3370,7 @@ dictiter_iternextkey(dictiterobject *di) return NULL; assert (PyDict_Check(d)); - if (di->di_used != d->ma_used) { + if (di->di_used != PyDict_GET_SIZE(d)) { PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); di->di_used = -1; /* Make this state sticky */ @@ -3381,7 +3381,7 @@ dictiter_iternextkey(dictiterobject *di) k = d->ma_keys; assert(i >= 0); if (d->ma_values) { - if (i >= d->ma_used) + if (i >= PyDict_GET_SIZE(d)) goto fail; key = DK_ENTRIES(k)[i].me_key; assert(d->ma_values[i] != NULL); @@ -3452,7 +3452,7 @@ dictiter_iternextvalue(dictiterobject *d return NULL; assert (PyDict_Check(d)); - if (di->di_used != d->ma_used) { + if (di->di_used != PyDict_GET_SIZE(d)) { PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); di->di_used = -1; /* Make this state sticky */ @@ -3462,7 +3462,7 @@ dictiter_iternextvalue(dictiterobject *d i = di->di_pos; assert(i >= 0); if (d->ma_values) { - if (i >= d->ma_used) + if (i >= PyDict_GET_SIZE(d)) goto fail; value = d->ma_values[i]; assert(value != NULL); @@ -3533,7 +3533,7 @@ dictiter_iternextitem(dictiterobject *di return NULL; assert (PyDict_Check(d)); - if (di->di_used != d->ma_used) { + if (di->di_used != PyDict_GET_SIZE(d)) { PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); di->di_used = -1; /* Make this state sticky */ @@ -3543,7 +3543,7 @@ dictiter_iternextitem(dictiterobject *di i = di->di_pos; assert(i >= 0); if (d->ma_values) { - if (i >= d->ma_used) + if (i >= PyDict_GET_SIZE(d)) goto fail; key = DK_ENTRIES(d->ma_keys)[i].me_key; value = d->ma_values[i]; @@ -3690,7 +3690,7 @@ dictview_len(_PyDictViewObject *dv) { Py_ssize_t len = 0; if (dv->dv_dict != NULL) - len = dv->dv_dict->ma_used; + len = PyDict_GET_SIZE(dv->dv_dict); return len; } diff -r 64afd5cab40a Objects/funcobject.c --- a/Objects/funcobject.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/funcobject.c Wed Dec 14 11:47:12 2016 +0200 @@ -583,7 +583,7 @@ function_call(PyObject *func, PyObject * if (kw != NULL && PyDict_Check(kw)) { Py_ssize_t pos, i; - nk = PyDict_Size(kw); + nk = PyDict_GET_SIZE(kw); kwtuple = PyTuple_New(2*nk); if (kwtuple == NULL) return NULL; diff -r 64afd5cab40a Objects/methodobject.c --- a/Objects/methodobject.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/methodobject.c Wed Dec 14 11:47:12 2016 +0200 @@ -87,6 +87,7 @@ PyCFunction_Call(PyObject *func, PyObjec Py_ssize_t size; int flags; + assert(kwds == NULL || PyDict_Check(kwds)); /* PyCFunction_Call() must not be called with an exception set, because it may clear it (directly or indirectly) and so the caller loses its exception */ @@ -103,7 +104,7 @@ PyCFunction_Call(PyObject *func, PyObjec res = _PyCFunction_FastCallDict(func, stack, nargs, kwds); } else { - if (kwds != NULL && PyDict_Size(kwds) != 0) { + if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", f->m_ml->ml_name); return NULL; @@ -176,7 +177,7 @@ PyObject * switch (flags) { case METH_NOARGS: - if (kwargs != NULL && PyDict_Size(kwargs) != 0) { + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", func->m_ml->ml_name); return NULL; @@ -193,7 +194,7 @@ PyObject * break; case METH_O: - if (kwargs != NULL && PyDict_Size(kwargs) != 0) { + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", func->m_ml->ml_name); return NULL; @@ -215,7 +216,7 @@ PyObject * /* Slow-path: create a temporary tuple */ PyObject *tuple; - if (!(flags & METH_KEYWORDS) && kwargs != NULL && PyDict_Size(kwargs) != 0) { + if (!(flags & METH_KEYWORDS) && kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", func->m_ml->ml_name); diff -r 64afd5cab40a Objects/object.c --- a/Objects/object.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/object.c Wed Dec 14 11:47:12 2016 +0200 @@ -1454,7 +1454,7 @@ none_dealloc(PyObject* ignore) static PyObject * none_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_Size(kwargs))) { + if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { PyErr_SetString(PyExc_TypeError, "NoneType takes no arguments"); return NULL; } @@ -1573,7 +1573,7 @@ static PyMethodDef notimplemented_method static PyObject * notimplemented_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_Size(kwargs))) { + if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { PyErr_SetString(PyExc_TypeError, "NotImplementedType takes no arguments"); return NULL; } diff -r 64afd5cab40a Objects/odictobject.c --- a/Objects/odictobject.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/odictobject.c Wed Dec 14 11:47:12 2016 +0200 @@ -2423,8 +2423,7 @@ mutablemapping_update(PyObject *self, Py /* now handle kwargs */ assert(kwargs == NULL || PyDict_Check(kwargs)); - len = (kwargs != NULL) ? PyDict_Size(kwargs) : 0; - if (len > 0) { + if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) { PyObject *items = PyDict_Items(kwargs); if (items == NULL) return NULL; diff -r 64afd5cab40a Objects/setobject.c --- a/Objects/setobject.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/setobject.c Wed Dec 14 11:47:12 2016 +0200 @@ -981,7 +981,7 @@ set_update_internal(PySetObject *so, PyO PyObject *value; Py_ssize_t pos = 0; Py_hash_t hash; - Py_ssize_t dictsize = PyDict_Size(other); + Py_ssize_t dictsize = PyDict_GET_SIZE(other); /* Do one big resize at the start, rather than * incrementally resizing as we insert new keys. Expect diff -r 64afd5cab40a Objects/sliceobject.c --- a/Objects/sliceobject.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/sliceobject.c Wed Dec 14 11:47:12 2016 +0200 @@ -19,7 +19,7 @@ this type and there is exactly one in ex static PyObject * ellipsis_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_Size(kwargs))) { + if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { PyErr_SetString(PyExc_TypeError, "EllipsisType takes no arguments"); return NULL; } diff -r 64afd5cab40a Objects/typeobject.c --- a/Objects/typeobject.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Objects/typeobject.c Wed Dec 14 11:47:12 2016 +0200 @@ -902,7 +902,7 @@ type_call(PyTypeObject *type, PyObject * if (type == &PyType_Type && PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && (kwds == NULL || - (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) + (PyDict_Check(kwds) && PyDict_GET_SIZE(kwds) == 0))) return obj; /* If the returned object is not an instance of type, @@ -1585,7 +1585,7 @@ set_mro_error(PyObject *to_merge, int *r } } } - n = PyDict_Size(set); + n = PyDict_GET_SIZE(set); off = PyOS_snprintf(buf, sizeof(buf), "Cannot create a \ consistent method resolution\norder (MRO) for bases"); @@ -2187,7 +2187,7 @@ type_init(PyObject *cls, PyObject *args, assert(kwds == NULL || PyDict_Check(kwds)); if (kwds != NULL && PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && - PyDict_Check(kwds) && PyDict_Size(kwds) != 0) { + PyDict_Check(kwds) && PyDict_GET_SIZE(kwds) != 0) { PyErr_SetString(PyExc_TypeError, "type.__init__() takes no keyword arguments"); return -1; @@ -2272,7 +2272,7 @@ type_new(PyTypeObject *metatype, PyObjec Note: We don't call PyType_CheckExact as that also allows subclasses */ if (metatype == &PyType_Type) { const Py_ssize_t nargs = PyTuple_GET_SIZE(args); - const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_Size(kwds); + const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_GET_SIZE(kwds); if (nargs == 1 && nkwds == 0) { PyObject *x = PyTuple_GET_ITEM(args, 0); @@ -3416,7 +3416,7 @@ static int excess_args(PyObject *args, PyObject *kwds) { return PyTuple_GET_SIZE(args) || - (kwds && PyDict_Check(kwds) && PyDict_Size(kwds)); + (kwds && PyDict_Check(kwds) && PyDict_GET_SIZE(kwds)); } static int @@ -3894,7 +3894,8 @@ static PyObject * We also return None if the dict is empty to make the behavior consistent regardless whether the dict was initialized or not. This make unit testing easier. */ - if (dict != NULL && *dict != NULL && PyDict_Size(*dict) > 0) { + if (dict != NULL && *dict != NULL && + (!PyDict_Check(*dict) || PyDict_GET_SIZE(*dict))) { state = *dict; } else { @@ -3983,7 +3984,7 @@ static PyObject * /* If we found some slot attributes, pack them in a tuple along the original attribute dictionary. */ - if (PyDict_Size(slots) > 0) { + if (PyDict_GET_SIZE(slots) > 0) { PyObject *state2; state2 = PyTuple_Pack(2, state, slots); @@ -4175,7 +4176,7 @@ reduce_newobj(PyObject *obj) return NULL; } hasargs = (args != NULL); - if (kwargs == NULL || PyDict_Size(kwargs) == 0) { + if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { _Py_IDENTIFIER(__newobj__); PyObject *cls; Py_ssize_t i, n; diff -r 64afd5cab40a Python/ceval.c --- a/Python/ceval.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Python/ceval.c Wed Dec 14 11:47:12 2016 +0200 @@ -5010,7 +5010,7 @@ PyObject * assert(kwargs == NULL || PyDict_Check(kwargs)); if (co->co_kwonlyargcount == 0 && - (kwargs == NULL || PyDict_Size(kwargs) == 0) && + (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) && co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { /* Fast paths */ @@ -5028,7 +5028,7 @@ PyObject * if (kwargs != NULL) { Py_ssize_t pos, i; - nk = PyDict_Size(kwargs); + nk = PyDict_GET_SIZE(kwargs); kwtuple = PyTuple_New(2 * nk); if (kwtuple == NULL) { diff -r 64afd5cab40a Python/compile.c --- a/Python/compile.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Python/compile.c Wed Dec 14 11:47:12 2016 +0200 @@ -564,7 +564,7 @@ compiler_enter_scope(struct compiler *c, PyObject *tuple, *name, *zero; int res; assert(u->u_scope_type == COMPILER_SCOPE_CLASS); - assert(PyDict_Size(u->u_cellvars) == 0); + assert(PyDict_GET_SIZE(u->u_cellvars) == 0); name = _PyUnicode_FromId(&PyId___class__); if (!name) { compiler_unit_free(u); @@ -591,7 +591,7 @@ compiler_enter_scope(struct compiler *c, } u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, - PyDict_Size(u->u_cellvars)); + PyDict_GET_SIZE(u->u_cellvars)); if (!u->u_freevars) { compiler_unit_free(u); return 0; @@ -1128,7 +1128,7 @@ compiler_add_o(struct compiler *c, PyObj Py_DECREF(t); return -1; } - arg = PyDict_Size(dict); + arg = PyDict_GET_SIZE(dict); v = PyLong_FromSsize_t(arg); if (!v) { Py_DECREF(t); @@ -1999,7 +1999,7 @@ compiler_class(struct compiler *c, stmt_ } else { /* No methods referenced __class__, so just return None */ - assert(PyDict_Size(c->u->u_cellvars) == 0); + assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0); ADDOP_O(c, LOAD_CONST, Py_None, consts); } ADDOP_IN_SCOPE(c, RETURN_VALUE); @@ -5179,7 +5179,7 @@ static PyObject * dict_keys_inorder(PyObject *dict, Py_ssize_t offset) { PyObject *tuple, *k, *v; - Py_ssize_t i, pos = 0, size = PyDict_Size(dict); + Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); tuple = PyTuple_New(size); if (tuple == NULL) @@ -5203,7 +5203,6 @@ compute_code_flags(struct compiler *c) { PySTEntryObject *ste = c->u->u_ste; int flags = 0; - Py_ssize_t n; if (ste->ste_type == FunctionBlock) { flags |= CO_NEWLOCALS | CO_OPTIMIZED; if (ste->ste_nested) @@ -5223,16 +5222,9 @@ compute_code_flags(struct compiler *c) /* (Only) inherit compilerflags in PyCF_MASK */ flags |= (c->c_flags->cf_flags & PyCF_MASK); - n = PyDict_Size(c->u->u_freevars); - if (n < 0) - return -1; - if (n == 0) { - n = PyDict_Size(c->u->u_cellvars); - if (n < 0) - return -1; - if (n == 0) { - flags |= CO_NOFREE; - } + if (!PyDict_GET_SIZE(c->u->u_freevars) && + !PyDict_GET_SIZE(c->u->u_cellvars)) { + flags |= CO_NOFREE; } return flags; @@ -5273,7 +5265,7 @@ makecode(struct compiler *c, struct asse if (!freevars) goto error; - nlocals = PyDict_Size(c->u->u_varnames); + nlocals = PyDict_GET_SIZE(c->u->u_varnames); assert(nlocals < INT_MAX); nlocals_int = Py_SAFE_DOWNCAST(nlocals, Py_ssize_t, int); diff -r 64afd5cab40a Python/getargs.c --- a/Python/getargs.c Tue Dec 13 19:03:51 2016 -0500 +++ b/Python/getargs.c Wed Dec 14 11:47:12 2016 +0200 @@ -1650,7 +1650,7 @@ vgetargskeywords(PyObject *args, PyObjec } nargs = PyTuple_GET_SIZE(args); - nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords); + nkeywords = (keywords == NULL) ? 0 : PyDict_GET_SIZE(keywords); if (nargs + nkeywords > len) { PyErr_Format(PyExc_TypeError, "%s%s takes at most %d argument%s (%zd given)", @@ -2034,7 +2034,7 @@ vgetargskeywordsfast_impl(PyObject **arg } if (keywords != NULL) { - nkeywords = PyDict_Size(keywords); + nkeywords = PyDict_GET_SIZE(keywords); } else if (kwnames != NULL) { nkeywords = PyTuple_GET_SIZE(kwnames); @@ -2421,7 +2421,7 @@ int PyErr_BadInternalCall(); return 0; } - if (PyDict_Size(kw) == 0) + if (PyDict_GET_SIZE(kw) == 0) return 1; PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",