diff -r 23a760bdd4b1 Include/object.h --- a/Include/object.h Fri Jan 17 09:29:24 2014 -0600 +++ b/Include/object.h Sat Jan 18 00:03:42 2014 +0200 @@ -822,6 +822,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 23a760bdd4b1 Modules/_csv.c --- a/Modules/_csv.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/_csv.c Sat Jan 18 00:03:42 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 23a760bdd4b1 Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/_ctypes/_ctypes.c Sat Jan 18 00:03:42 2014 +0200 @@ -384,8 +384,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); @@ -863,8 +862,7 @@ return -1; } Py_INCREF(proto); - Py_XDECREF(stgdict->proto); - stgdict->proto = proto; + Py_XREPLACE(stgdict->proto, proto); return 0; } @@ -947,8 +945,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; } @@ -1420,8 +1417,7 @@ Py_DECREF((PyObject *)stgdict); return NULL; } - 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! @@ -1844,8 +1840,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; } @@ -2353,8 +2348,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); @@ -2496,8 +2490,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); @@ -3094,8 +3087,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; diff -r 23a760bdd4b1 Modules/_curses_panel.c --- a/Modules/_curses_panel.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/_curses_panel.c Sat Jan 18 00:03:42 2014 +0200 @@ -283,8 +283,7 @@ PyErr_SetString(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 23a760bdd4b1 Modules/_json.c --- a/Modules/_json.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/_json.c Sat Jan 18 00:03:42 2014 +0200 @@ -1699,8 +1699,7 @@ } else if (PyUnicode_Check(s->encoding)) { PyObject *tmp = PyUnicode_AsEncodedString(s->encoding, NULL, NULL); - Py_DECREF(s->encoding); - s->encoding = tmp; + Py_REPLACE(s->encoding, tmp); } if (s->encoding == NULL) goto bail; diff -r 23a760bdd4b1 Modules/_sqlite/connection.c --- a/Modules/_sqlite/connection.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/_sqlite/connection.c Sat Jan 18 00:03:42 2014 +0200 @@ -228,8 +228,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; } @@ -817,8 +817,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) @@ -849,8 +848,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 23a760bdd4b1 Modules/_sqlite/cursor.c --- a/Modules/_sqlite/cursor.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/_sqlite/cursor.c Sat Jan 18 00:03:42 2014 +0200 @@ -172,8 +172,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; @@ -573,8 +572,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; } @@ -685,8 +684,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 23a760bdd4b1 Modules/_sre.c --- a/Modules/_sre.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/_sre.c Sat Jan 18 00:03:42 2014 +0200 @@ -1992,8 +1992,7 @@ if (!copy) return 0; - Py_DECREF(*object); - *object = copy; + Py_REPLACE(*object, copy); return 1; /* success */ } diff -r 23a760bdd4b1 Modules/bz2module.c --- a/Modules/bz2module.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/bz2module.c Sat Jan 18 00:03:42 2014 +0200 @@ -1952,9 +1952,8 @@ self->running = 0; input_left += bzs->avail_in; if (input_left != 0) { - Py_DECREF(self->unused_data); - self->unused_data = - PyString_FromStringAndSize(bzs->next_in, input_left); + Py_REPLACE(self->unused_data, + PyString_FromStringAndSize(bzs->next_in, input_left)); if (self->unused_data == NULL) goto error; } diff -r 23a760bdd4b1 Modules/cPickle.c --- a/Modules/cPickle.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/cPickle.c Sat Jan 18 00:03:42 2014 +0200 @@ -690,8 +690,7 @@ } if (! str) return -1; - Py_XDECREF(self->last_string); - self->last_string = str; + Py_XREPLACE(self->last_string, str); if (! (*s = PyString_AsString(str))) return -1; @@ -717,8 +716,7 @@ if ((str_size = PyString_Size(str)) < 0) return -1; - Py_XDECREF(self->last_string); - self->last_string = str; + Py_XREPLACE(self->last_string, str); if (! (*s = PyString_AsString(str))) return -1; @@ -5633,15 +5631,13 @@ { if (!strcmp(name, "persistent_load")) { - Py_XDECREF(self->pers_func); - self->pers_func = value; + Py_XREPLACE(self->pers_func, value); Py_XINCREF(value); return 0; } if (!strcmp(name, "find_global")) { - Py_XDECREF(self->find_class); - self->find_class = value; + Py_XREPLACE(self->find_class, value); Py_XINCREF(value); return 0; } @@ -5658,8 +5654,7 @@ "memo must be a dictionary"); return -1; } - Py_XDECREF(self->memo); - self->memo = value; + Py_XREPLACE(self->memo, value); Py_INCREF(value); return 0; } diff -r 23a760bdd4b1 Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/itertoolsmodule.c Sat Jan 18 00:03:42 2014 +0200 @@ -494,8 +494,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 23a760bdd4b1 Modules/signalmodule.c --- a/Modules/signalmodule.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/signalmodule.c Sat Jan 18 00:03:42 2014 +0200 @@ -621,8 +621,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 23a760bdd4b1 Modules/zipimport.c --- a/Modules/zipimport.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/zipimport.c Sat Jan 18 00:03:42 2014 +0200 @@ -830,8 +830,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 23a760bdd4b1 Modules/zlibmodule.c --- a/Modules/zlibmodule.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Modules/zlibmodule.c Sat Jan 18 00:03:42 2014 +0200 @@ -491,8 +491,7 @@ PyString_AS_STRING(self->unused_data), old_size); Py_MEMCPY(PyString_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; } } @@ -504,8 +503,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 23a760bdd4b1 Objects/descrobject.c --- a/Objects/descrobject.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Objects/descrobject.c Sat Jan 18 00:03:42 2014 +0200 @@ -1332,8 +1332,7 @@ PyObject *get_doc = PyObject_GetAttrString(get, "__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 23a760bdd4b1 Objects/exceptions.c --- a/Objects/exceptions.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Objects/exceptions.c Sat Jan 18 00:03:42 2014 +0200 @@ -58,8 +58,7 @@ if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) return -1; - Py_DECREF(self->args); - self->args = args; + Py_REPLACE(self->args, args); Py_INCREF(self->args); if (PyTuple_GET_SIZE(self->args) == 1) { @@ -627,8 +626,7 @@ if (!subslice) return -1; - Py_DECREF(self->args); /* replacing args */ - self->args = subslice; + Py_REPLACE(self->args, subslice); } return 0; } diff -r 23a760bdd4b1 Objects/fileobject.c --- a/Objects/fileobject.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Objects/fileobject.c Sat Jan 18 00:03:42 2014 +0200 @@ -574,10 +574,8 @@ oerrors = Py_None; Py_INCREF(Py_None); } - Py_DECREF(file->f_encoding); - file->f_encoding = str; - Py_DECREF(file->f_errors); - file->f_errors = oerrors; + Py_REPLACE(file->f_encoding, str); + Py_REPLACE(file->f_errors, oerrors); return 1; } diff -r 23a760bdd4b1 Objects/frameobject.c --- a/Objects/frameobject.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Objects/frameobject.c Sat Jan 18 00:03:42 2014 +0200 @@ -859,8 +859,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 23a760bdd4b1 Objects/funcobject.c --- a/Objects/funcobject.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Objects/funcobject.c Sat Jan 18 00:03:42 2014 +0200 @@ -116,8 +116,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; } @@ -149,8 +148,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; } @@ -430,8 +428,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 23a760bdd4b1 Objects/stringobject.c --- a/Objects/stringobject.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Objects/stringobject.c Sat Jan 18 00:03:42 2014 +0200 @@ -3862,8 +3862,7 @@ return; } v = string_concat((PyStringObject *) *pv, w); - Py_DECREF(*pv); - *pv = v; + Py_REPLACE(*pv, v); } void @@ -4748,8 +4747,7 @@ t = PyDict_GetItem(interned, (PyObject *)s); if (t) { Py_INCREF(t); - Py_DECREF(*p); - *p = t; + Py_REPLACE(*p, t); return; } diff -r 23a760bdd4b1 Objects/typeobject.c --- a/Objects/typeobject.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Objects/typeobject.c Sat Jan 18 00:03:42 2014 +0200 @@ -166,8 +166,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 */ @@ -2528,8 +2527,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 23a760bdd4b1 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Objects/unicodeobject.c Sat Jan 18 00:03:42 2014 +0200 @@ -436,8 +436,7 @@ return -1; Py_UNICODE_COPY(w->str, v->str, length < v->length ? length : v->length); - Py_DECREF(*unicode); - *unicode = w; + Py_REPLACE(*unicode, w); return 0; } diff -r 23a760bdd4b1 Python/_warnings.c --- a/Python/_warnings.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Python/_warnings.c Sat Jan 18 00:03:42 2014 +0200 @@ -528,8 +528,7 @@ goto handle_error; } else if (!is_true) { - Py_DECREF(*filename); - *filename = PyString_FromString("__main__"); + Py_REPLACE(*filename, PyString_FromString("__main__")); if (*filename == NULL) goto handle_error; } diff -r 23a760bdd4b1 Python/ceval.c --- a/Python/ceval.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Python/ceval.c Sat Jan 18 00:03:42 2014 +0200 @@ -2695,8 +2695,7 @@ Py_INCREF(self); func = PyMethod_GET_FUNCTION(func); Py_INCREF(func); - Py_DECREF(*pfunc); - *pfunc = self; + Py_REPLACE(*pfunc, self); na++; } else Py_INCREF(func); @@ -4031,8 +4030,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 23a760bdd4b1 Python/compile.c --- a/Python/compile.c Fri Jan 17 09:29:24 2014 -0600 +++ b/Python/compile.c Sat Jan 18 00:03:42 2014 +0200 @@ -1455,8 +1455,7 @@ if (!compiler_enter_scope(c, s->v.ClassDef.name, (void *)s, s->lineno)) return 0; - Py_XDECREF(c->u->u_private); - c->u->u_private = s->v.ClassDef.name; + Py_XREPLACE(c->u->u_private, s->v.ClassDef.name); Py_INCREF(c->u->u_private); str = PyString_InternFromString("__name__"); if (!str || !compiler_nameop(c, str, Load)) {