diff -r 64401c6656b5 Include/object.h --- a/Include/object.h Fri Jan 17 12:08:49 2014 -0800 +++ b/Include/object.h Sat Jan 18 00:03:35 2014 +0200 @@ -824,6 +824,38 @@ #define Py_XINCREF(op) do { if ((op) == NULL) ; else Py_INCREF(op); } while (0) #define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0) +/* Safely decref `op` and set `op` to `op2`. + * + * As in case of Py_CLEAR "the obvious" code can be deadly: + * + * Py_DECREF(op); + * op = op2; + * + * The safe way is: + * + * Py_REPLACE(op, op2); + * + * That arranges to set `op` to `op2` _before_ decref'ing, so that any code + * triggered as a side-effect of `op` getting torn down no longer believes + * `op` points to a valid object. + * + * Py_XREPLACE is a variant of Py_REPLACE which calls Py_XDECREF. + */ + +#define Py_REPLACE(op, op2) \ + do { \ + PyObject *_py_tmp = (PyObject *)(op); \ + (op) = (op2); \ + Py_DECREF(_py_tmp); \ + } while (0) + +#define Py_XREPLACE(op, op2) \ + do { \ + PyObject *_py_tmp = (PyObject *)(op); \ + (op) = (op2); \ + Py_XDECREF(_py_tmp); \ + } while (0) + /* These are provided as conveniences to Python runtime embedders, so that they can have object code that is not dependent on Python compilation flags. diff -r 64401c6656b5 Modules/_csv.c --- a/Modules/_csv.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/_csv.c Sat Jan 18 00:03:35 2014 +0200 @@ -770,8 +770,7 @@ static int parse_reset(ReaderObj *self) { - Py_XDECREF(self->fields); - self->fields = PyList_New(0); + Py_XREPLACE(self->fields, PyList_New(0)); if (self->fields == NULL) return -1; self->field_len = 0; diff -r 64401c6656b5 Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/_ctypes/_ctypes.c Sat Jan 18 00:03:35 2014 +0200 @@ -349,8 +349,7 @@ Py_DECREF((PyObject *)dict); return NULL; } - Py_DECREF(result->tp_dict); - result->tp_dict = (PyObject *)dict; + Py_REPLACE(result->tp_dict, (PyObject *)dict); dict->format = _ctypes_alloc_format_string(NULL, "B"); if (dict->format == NULL) { Py_DECREF(result); @@ -825,8 +824,7 @@ return -1; } Py_INCREF(proto); - Py_XDECREF(stgdict->proto); - stgdict->proto = proto; + Py_XREPLACE(stgdict->proto, proto); return 0; } @@ -909,8 +907,7 @@ Py_DECREF((PyObject *)stgdict); return NULL; } - Py_DECREF(result->tp_dict); - result->tp_dict = (PyObject *)stgdict; + Py_REPLACE(result->tp_dict, (PyObject *)stgdict); return (PyObject *)result; } @@ -1358,8 +1355,7 @@ /* replace the class dict by our updated spam dict */ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) goto error; - Py_DECREF(result->tp_dict); - result->tp_dict = (PyObject *)stgdict; + Py_REPLACE(result->tp_dict, (PyObject *)stgdict); /* Special case for character arrays. A permanent annoyance: char arrays are also strings! @@ -1788,8 +1784,7 @@ Py_DECREF((PyObject *)stgdict); return NULL; } - Py_DECREF(result->tp_dict); - result->tp_dict = (PyObject *)stgdict; + Py_REPLACE(result->tp_dict, (PyObject *)stgdict); return (PyObject *)result; } @@ -1917,8 +1912,7 @@ Py_DECREF((PyObject *)stgdict); return NULL; } - Py_DECREF(result->tp_dict); - result->tp_dict = (PyObject *)stgdict; + Py_REPLACE(result->tp_dict, (PyObject *)stgdict); /* Install from_param class methods in ctypes base classes. Overrides the PyCSimpleType_from_param generic method. @@ -2277,8 +2271,7 @@ Py_DECREF((PyObject *)stgdict); return NULL; } - Py_DECREF(result->tp_dict); - result->tp_dict = (PyObject *)stgdict; + Py_REPLACE(result->tp_dict, (PyObject *)stgdict); if (-1 == make_funcptrtype_dict(stgdict)) { Py_DECREF(result); @@ -2412,8 +2405,7 @@ } ob = PyCData_GetContainer(target); if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) { - Py_XDECREF(ob->b_objects); - ob->b_objects = keep; /* refcount consumed */ + Py_XREPLACE(ob->b_objects, keep); /* refcount consumed */ return 0; } key = unique_key(target, index); @@ -2984,8 +2976,7 @@ converters = converters_from_argtypes(ob); if (!converters) return -1; - Py_XDECREF(self->converters); - self->converters = converters; + Py_XREPLACE(self->converters, converters); Py_XDECREF(self->argtypes); Py_INCREF(ob); self->argtypes = ob; @@ -5105,8 +5096,7 @@ return -1; bself = (PyBaseExceptionObject *)self; - Py_DECREF(bself->args); - bself->args = args; + Py_REPLACE(bself->args, args); Py_INCREF(bself->args); return 0; diff -r 64401c6656b5 Modules/_curses_panel.c --- a/Modules/_curses_panel.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/_curses_panel.c Sat Jan 18 00:03:35 2014 +0200 @@ -312,8 +312,7 @@ PyErr_SetString(_curses_panelstate_global->PyCursesError, "replace_panel() returned ERR"); return NULL; } - Py_DECREF(po->wo); - po->wo = temp; + Py_REPLACE(po->wo, temp); Py_INCREF(po->wo); Py_INCREF(Py_None); return Py_None; diff -r 64401c6656b5 Modules/_sqlite/connection.c --- a/Modules/_sqlite/connection.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/_sqlite/connection.c Sat Jan 18 00:03:35 2014 +0200 @@ -185,8 +185,8 @@ node = node->next; } - Py_DECREF(self->statement_cache); - self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "O", self); + Py_REPLACE(self->statement_cache, + (pysqlite_Cache *)PyObject_CallFunction((PyObject *)&pysqlite_CacheType, "O", self)); Py_DECREF(self); self->statement_cache->decref_factory = 0; } @@ -751,8 +751,7 @@ } } - Py_DECREF(self->statements); - self->statements = new_list; + Py_REPLACE(self->statements, new_list); } static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self) @@ -783,8 +782,7 @@ } } - Py_DECREF(self->cursors); - self->cursors = new_list; + Py_REPLACE(self->cursors, new_list); } PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) diff -r 64401c6656b5 Modules/_sqlite/cursor.c --- a/Modules/_sqlite/cursor.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/_sqlite/cursor.c Sat Jan 18 00:03:35 2014 +0200 @@ -171,8 +171,7 @@ return 0; } - Py_XDECREF(self->row_cast_map); - self->row_cast_map = PyList_New(0); + Py_XREPLACE(self->row_cast_map, PyList_New(0)); for (i = 0; i < sqlite3_column_count(self->statement->st); i++) { converter = NULL; @@ -541,8 +540,8 @@ } if (self->statement->in_use) { - Py_DECREF(self->statement); - self->statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType); + Py_REPLACE(self->statement, + PyObject_New(pysqlite_Statement, &pysqlite_StatementType)); if (!self->statement) { goto error; } @@ -654,8 +653,7 @@ numcols = sqlite3_column_count(self->statement->st); Py_END_ALLOW_THREADS - Py_DECREF(self->description); - self->description = PyTuple_New(numcols); + Py_REPLACE(self->description, PyTuple_New(numcols)); if (!self->description) { goto error; } diff -r 64401c6656b5 Modules/_sre.c --- a/Modules/_sre.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/_sre.c Sat Jan 18 00:03:35 2014 +0200 @@ -1989,8 +1989,7 @@ if (!copy) return 0; - Py_DECREF(*object); - *object = copy; + Py_REPLACE(*object, copy); return 1; /* success */ } diff -r 64401c6656b5 Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/itertoolsmodule.c Sat Jan 18 00:03:35 2014 +0200 @@ -636,8 +636,7 @@ link = teedataobject_jumplink(to->dataobj); if (link == NULL) return NULL; - Py_DECREF(to->dataobj); - to->dataobj = (teedataobject *)link; + Py_REPLACE(to->dataobj, (teedataobject *)link); to->index = 0; } value = teedataobject_getitem(to->dataobj, to->index); diff -r 64401c6656b5 Modules/signalmodule.c --- a/Modules/signalmodule.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/signalmodule.c Sat Jan 18 00:03:35 2014 +0200 @@ -1041,8 +1041,7 @@ if (Handlers[SIGINT].func == DefaultHandler) { /* Install default int handler */ Py_INCREF(IntHandler); - Py_DECREF(Handlers[SIGINT].func); - Handlers[SIGINT].func = IntHandler; + Py_REPLACE(Handlers[SIGINT].func, IntHandler); old_siginthandler = PyOS_setsig(SIGINT, signal_handler); } diff -r 64401c6656b5 Modules/zipimport.c --- a/Modules/zipimport.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/zipimport.c Sat Jan 18 00:03:35 2014 +0200 @@ -188,8 +188,7 @@ tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP); if (tmp == NULL) goto error; - Py_DECREF(self->prefix); - self->prefix = tmp; + Py_REPLACE(self->prefix, tmp); } } else @@ -956,8 +955,7 @@ fclose(fp); return NULL; } - Py_XDECREF(self->files); /* free the old value. */ - self->files = files; + Py_XREPLACE(self->files, files); } Py_DECREF(stat_now); } /* stat succeeded */ diff -r 64401c6656b5 Modules/zlibmodule.c --- a/Modules/zlibmodule.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Modules/zlibmodule.c Sat Jan 18 00:03:35 2014 +0200 @@ -585,8 +585,7 @@ PyBytes_AS_STRING(self->unused_data), old_size); Py_MEMCPY(PyBytes_AS_STRING(new_data) + old_size, self->zst.next_in, self->zst.avail_in); - Py_DECREF(self->unused_data); - self->unused_data = new_data; + Py_REPLACE(self->unused_data, new_data); self->zst.avail_in = 0; } } @@ -598,8 +597,7 @@ (char *)self->zst.next_in, self->zst.avail_in); if (new_data == NULL) return -1; - Py_DECREF(self->unconsumed_tail); - self->unconsumed_tail = new_data; + Py_REPLACE(self->unconsumed_tail, new_data); } return 0; } diff -r 64401c6656b5 Objects/bytesobject.c --- a/Objects/bytesobject.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Objects/bytesobject.c Sat Jan 18 00:03:35 2014 +0200 @@ -2849,8 +2849,7 @@ return; } v = bytes_concat(*pv, w); - Py_DECREF(*pv); - *pv = v; + Py_REPLACE(*pv, v); } void diff -r 64401c6656b5 Objects/descrobject.c --- a/Objects/descrobject.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Objects/descrobject.c Sat Jan 18 00:03:35 2014 +0200 @@ -1444,8 +1444,7 @@ PyObject *get_doc = _PyObject_GetAttrId(get, &PyId___doc__); if (get_doc) { if (Py_TYPE(self) == &PyProperty_Type) { - Py_XDECREF(prop->prop_doc); - prop->prop_doc = get_doc; + Py_XREPLACE(prop->prop_doc, get_doc); } else { /* If this is a property subclass, put __doc__ diff -r 64401c6656b5 Objects/exceptions.c --- a/Objects/exceptions.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Objects/exceptions.c Sat Jan 18 00:03:35 2014 +0200 @@ -239,8 +239,7 @@ } Py_XINCREF(tb); - Py_XDECREF(self->traceback); - self->traceback = tb; + Py_XREPLACE(self->traceback, tb); return 0; } diff -r 64401c6656b5 Objects/frameobject.c --- a/Objects/frameobject.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Objects/frameobject.c Sat Jan 18 00:03:35 2014 +0200 @@ -832,8 +832,7 @@ } } else if (values[j] != value) { Py_XINCREF(value); - Py_XDECREF(values[j]); - values[j] = value; + Py_XREPLACE(values[j], value); } Py_XDECREF(value); } diff -r 64401c6656b5 Objects/funcobject.c --- a/Objects/funcobject.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Objects/funcobject.c Sat Jan 18 00:03:35 2014 +0200 @@ -128,8 +128,7 @@ PyErr_SetString(PyExc_SystemError, "non-tuple default args"); return -1; } - Py_XDECREF(((PyFunctionObject *) op) -> func_defaults); - ((PyFunctionObject *) op) -> func_defaults = defaults; + Py_XREPLACE(((PyFunctionObject *)op)->func_defaults, defaults); return 0; } @@ -160,8 +159,7 @@ "non-dict keyword only default args"); return -1; } - Py_XDECREF(((PyFunctionObject *)op) -> func_kwdefaults); - ((PyFunctionObject *) op) -> func_kwdefaults = defaults; + Py_XREPLACE(((PyFunctionObject *)op)->func_kwdefaults, defaults); return 0; } @@ -193,8 +191,7 @@ closure->ob_type->tp_name); return -1; } - Py_XDECREF(((PyFunctionObject *) op) -> func_closure); - ((PyFunctionObject *) op) -> func_closure = closure; + Py_XREPLACE(((PyFunctionObject *)op)->func_closure, closure); return 0; } @@ -225,8 +222,7 @@ "non-dict annotations"); return -1; } - Py_XDECREF(((PyFunctionObject *)op) -> func_annotations); - ((PyFunctionObject *) op) -> func_annotations = annotations; + Py_XREPLACE(((PyFunctionObject *)op)->func_annotations, annotations); return 0; } @@ -532,8 +528,7 @@ if (name != Py_None) { Py_INCREF(name); - Py_DECREF(newfunc->func_name); - newfunc->func_name = name; + Py_REPLACE(newfunc->func_name, name); } if (defaults != Py_None) { Py_INCREF(defaults); diff -r 64401c6656b5 Objects/rangeobject.c --- a/Objects/rangeobject.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Objects/rangeobject.c Sat Jan 18 00:03:35 2014 +0200 @@ -1229,8 +1229,7 @@ result = PyNumber_Add(r->start, product); Py_DECREF(product); if (result) { - Py_DECREF(r->index); - r->index = new_index; + Py_REPLACE(r->index, new_index); } else { Py_DECREF(new_index); diff -r 64401c6656b5 Objects/typeobject.c --- a/Objects/typeobject.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Objects/typeobject.c Sat Jan 18 00:03:35 2014 +0200 @@ -181,8 +181,7 @@ are borrowed reference */ for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { method_cache[i].value = NULL; - Py_XDECREF(method_cache[i].name); - method_cache[i].name = Py_None; + Py_XREPLACE(method_cache[i].name, Py_None); Py_INCREF(Py_None); } /* mark all version tags as invalid */ @@ -328,8 +327,7 @@ et = (PyHeapTypeObject*)type; Py_INCREF(value); - Py_DECREF(et->ht_qualname); - et->ht_qualname = value; + Py_REPLACE(et->ht_qualname, value); return 0; } @@ -2573,8 +2571,7 @@ method_cache[h].version = type->tp_version_tag; method_cache[h].value = res; /* borrowed */ Py_INCREF(name); - Py_DECREF(method_cache[h].name); - method_cache[h].name = name; + Py_REPLACE(method_cache[h].name, name); } return res; } diff -r 64401c6656b5 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Objects/unicodeobject.c Sat Jan 18 00:03:35 2014 +0200 @@ -1603,8 +1603,7 @@ _Py_INCREF_UNICODE_EMPTY(); if (!unicode_empty) return -1; - Py_DECREF(*p_unicode); - *p_unicode = unicode_empty; + Py_REPLACE(*p_unicode, unicode_empty); return 0; } @@ -1612,8 +1611,7 @@ PyObject *copy = resize_copy(unicode, length); if (copy == NULL) return -1; - Py_DECREF(*p_unicode); - *p_unicode = copy; + Py_REPLACE(*p_unicode, copy); return 0; } @@ -1658,8 +1656,7 @@ if (result == NULL) return -1; _PyUnicode_FastCopyCharacters(result, 0, *p_unicode, 0, length); - Py_DECREF(*p_unicode); - *p_unicode = result; + Py_REPLACE(*p_unicode, result); return 0; } @@ -12879,8 +12876,7 @@ return -1; _PyUnicode_FastCopyCharacters(newbuffer, 0, writer->buffer, 0, writer->pos); - Py_DECREF(writer->buffer); - writer->buffer = newbuffer; + Py_REPLACE(writer->buffer, newbuffer); _PyUnicodeWriter_Update(writer); } return 0; diff -r 64401c6656b5 Python/_warnings.c --- a/Python/_warnings.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Python/_warnings.c Sat Jan 18 00:03:35 2014 +0200 @@ -545,8 +545,7 @@ goto handle_error; } else if (!is_true) { - Py_DECREF(*filename); - *filename = PyUnicode_FromString("__main__"); + Py_REPLACE(*filename, PyUnicode_FromString("__main__")); if (*filename == NULL) goto handle_error; } diff -r 64401c6656b5 Python/ceval.c --- a/Python/ceval.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Python/ceval.c Sat Jan 18 00:03:35 2014 +0200 @@ -2709,8 +2709,7 @@ Py_INCREF(self); func = PyMethod_GET_FUNCTION(func); Py_INCREF(func); - Py_DECREF(*pfunc); - *pfunc = self; + Py_REPLACE(*pfunc, self); na++; /* n++; */ } else @@ -4079,8 +4078,7 @@ Py_INCREF(self); func = PyMethod_GET_FUNCTION(func); Py_INCREF(func); - Py_DECREF(*pfunc); - *pfunc = self; + Py_REPLACE(*pfunc, self); na++; n++; } else diff -r 64401c6656b5 Python/compile.c --- a/Python/compile.c Fri Jan 17 12:08:49 2014 -0800 +++ b/Python/compile.c Sat Jan 18 00:03:35 2014 +0200 @@ -1659,8 +1659,7 @@ { /* use the class name for name mangling */ Py_INCREF(s->v.ClassDef.name); - Py_XDECREF(c->u->u_private); - c->u->u_private = s->v.ClassDef.name; + Py_XREPLACE(c->u->u_private, s->v.ClassDef.name); /* force it to have one mandatory argument */ c->u->u_argcount = 1; /* load the first argument (__locals__) ... */