[Python-checkins] cpython (2.7): Issue #20440: Massive replacing unsafe attribute setting code with special

serhiy.storchaka python-checkins at python.org
Thu Dec 24 03:40:34 EST 2015


https://hg.python.org/cpython/rev/23296440b654
changeset:   99668:23296440b654
branch:      2.7
parent:      99657:d7b5c2f99a99
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Thu Dec 24 10:35:35 2015 +0200
summary:
  Issue #20440: Massive replacing unsafe attribute setting code with special
macro Py_SETREF.

files:
  Include/object.h             |  23 ++++++++++++++++
  Misc/NEWS                    |   3 ++
  Modules/_bsddb.c             |  15 +++-------
  Modules/_csv.c               |   6 +--
  Modules/_ctypes/_ctypes.c    |  33 ++++++++----------------
  Modules/_curses_panel.c      |   5 +--
  Modules/_json.c              |   3 +-
  Modules/_sqlite/connection.c |  13 +++-----
  Modules/_sqlite/cursor.c     |  13 +++-----
  Modules/_sre.c               |   3 +-
  Modules/_ssl.c               |   3 +-
  Modules/bz2module.c          |   5 +--
  Modules/cPickle.c            |  24 +++++-----------
  Modules/cdmodule.c           |   6 +--
  Modules/itertoolsmodule.c    |   3 +-
  Modules/signalmodule.c       |   3 +-
  Modules/zlibmodule.c         |   6 +--
  Objects/descrobject.c        |   3 +-
  Objects/exceptions.c         |   8 ++---
  Objects/fileobject.c         |   6 +--
  Objects/frameobject.c        |   3 +-
  Objects/funcobject.c         |   9 ++----
  Objects/stringobject.c       |   6 +--
  Objects/typeobject.c         |   6 +--
  Objects/unicodeobject.c      |   3 +-
  Python/_warnings.c           |   3 +-
  Python/ceval.c               |   3 +-
  Python/compile.c             |   5 +--
  28 files changed, 94 insertions(+), 128 deletions(-)


diff --git a/Include/object.h b/Include/object.h
--- a/Include/object.h
+++ b/Include/object.h
@@ -824,6 +824,29 @@
 #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_XDECREF(op);
+ *     op = op2;
+ *
+ * The safe way is:
+ *
+ *      Py_SETREF(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.
+ */
+
+#define Py_SETREF(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 --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
 Core and Builtins
 -----------------
 
+- Issue #20440: Massive replacing unsafe attribute setting code with special
+  macro Py_SETREF.
+
 - Issue #25421: __sizeof__ methods of builtin types now use dynamic basic size.
   This allows sys.getsize() to work correctly with their subclasses with
   __slots__ defined.
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -1607,9 +1607,8 @@
     }
 
     /* Save a reference to the callback in the secondary DB. */
-    Py_XDECREF(secondaryDB->associateCallback);
     Py_XINCREF(callback);
-    secondaryDB->associateCallback = callback;
+    Py_SETREF(secondaryDB->associateCallback, callback);
     secondaryDB->primaryDBType = _DB_get_type(self);
 
     /* PyEval_InitThreads is called here due to a quirk in python 1.5
@@ -2498,9 +2497,8 @@
 DB_set_private(DBObject* self, PyObject* private_obj)
 {
     /* We can set the private field even if db is closed */
-    Py_DECREF(self->private_obj);
     Py_INCREF(private_obj);
-    self->private_obj = private_obj;
+    Py_SETREF(self->private_obj, private_obj);
     RETURN_NONE();
 }
 
@@ -6998,9 +6996,8 @@
 DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
 {
     /* We can set the private field even if dbenv is closed */
-    Py_DECREF(self->private_obj);
     Py_INCREF(private_obj);
-    self->private_obj = private_obj;
+    Py_SETREF(self->private_obj, private_obj);
     RETURN_NONE();
 }
 
@@ -7253,9 +7250,8 @@
             return NULL;
     }
 
-    Py_XDECREF(self->event_notifyCallback);
     Py_INCREF(notifyFunc);
-    self->event_notifyCallback = notifyFunc;
+    Py_SETREF(self->event_notifyCallback, notifyFunc);
 
     /* This is to workaround a problem with un-initialized threads (see
        comment in DB_associate) */
@@ -7413,9 +7409,8 @@
     MYDB_END_ALLOW_THREADS;
     RETURN_IF_ERR();
 
-    Py_DECREF(self->rep_transport);
     Py_INCREF(rep_transport);
-    self->rep_transport = rep_transport;
+    Py_SETREF(self->rep_transport, rep_transport);
     RETURN_NONE();
 }
 
diff --git a/Modules/_csv.c b/Modules/_csv.c
--- a/Modules/_csv.c
+++ b/Modules/_csv.c
@@ -276,9 +276,8 @@
             return -1;
         }
         else {
-            Py_XDECREF(*target);
             Py_INCREF(src);
-            *target = src;
+            Py_SETREF(*target, src);
         }
     }
     return 0;
@@ -770,8 +769,7 @@
 static int
 parse_reset(ReaderObj *self)
 {
-    Py_XDECREF(self->fields);
-    self->fields = PyList_New(0);
+    Py_SETREF(self->fields, PyList_New(0));
     if (self->fields == NULL)
         return -1;
     self->field_len = 0;
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -424,8 +424,7 @@
         Py_DECREF((PyObject *)dict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)dict;
+    Py_SETREF(result->tp_dict, (PyObject *)dict);
     dict->format = _ctypes_alloc_format_string(NULL, "B");
     if (dict->format == NULL) {
         Py_DECREF(result);
@@ -903,8 +902,7 @@
         return -1;
     }
     Py_INCREF(proto);
-    Py_XDECREF(stgdict->proto);
-    stgdict->proto = proto;
+    Py_SETREF(stgdict->proto, proto);
     return 0;
 }
 
@@ -994,8 +992,7 @@
         Py_DECREF((PyObject *)stgdict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)stgdict;
+    Py_SETREF(result->tp_dict, (PyObject *)stgdict);
 
     return (PyObject *)result;
 }
@@ -1460,8 +1457,7 @@
         Py_DECREF((PyObject *)stgdict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)stgdict;
+    Py_SETREF(result->tp_dict, (PyObject *)stgdict);
 
     /* Special case for character arrays.
        A permanent annoyance: char arrays are also strings!
@@ -1884,8 +1880,7 @@
         Py_DECREF((PyObject *)stgdict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)stgdict;
+    Py_SETREF(result->tp_dict, (PyObject *)stgdict);
 
     return (PyObject *)result;
 }
@@ -2393,8 +2388,7 @@
         Py_DECREF((PyObject *)stgdict);
         return NULL;
     }
-    Py_DECREF(result->tp_dict);
-    result->tp_dict = (PyObject *)stgdict;
+    Py_SETREF(result->tp_dict, (PyObject *)stgdict);
 
     if (-1 == make_funcptrtype_dict(stgdict)) {
         Py_DECREF(result);
@@ -2536,8 +2530,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_SETREF(ob->b_objects, keep); /* refcount consumed */
         return 0;
     }
     key = unique_key(target, index);
@@ -3059,9 +3052,8 @@
                         "the errcheck attribute must be callable");
         return -1;
     }
-    Py_XDECREF(self->errcheck);
     Py_XINCREF(ob);
-    self->errcheck = ob;
+    Py_SETREF(self->errcheck, ob);
     return 0;
 }
 
@@ -3090,9 +3082,8 @@
         return -1;
     }
     Py_XDECREF(self->checker);
-    Py_XDECREF(self->restype);
     Py_INCREF(ob);
-    self->restype = ob;
+    Py_SETREF(self->restype, ob);
     self->checker = PyObject_GetAttrString(ob, "_check_retval_");
     if (self->checker == NULL)
         PyErr_Clear();
@@ -3130,11 +3121,9 @@
         converters = converters_from_argtypes(ob);
         if (!converters)
             return -1;
-        Py_XDECREF(self->converters);
-        self->converters = converters;
-        Py_XDECREF(self->argtypes);
+        Py_SETREF(self->converters, converters);
         Py_INCREF(ob);
-        self->argtypes = ob;
+        Py_SETREF(self->argtypes, ob);
     }
     return 0;
 }
diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c
--- a/Modules/_curses_panel.c
+++ b/Modules/_curses_panel.c
@@ -283,9 +283,8 @@
         PyErr_SetString(PyCursesError, "replace_panel() returned ERR");
         return NULL;
     }
-    Py_DECREF(po->wo);
-    po->wo = temp;
-    Py_INCREF(po->wo);
+    Py_INCREF(temp);
+    Py_SETREF(po->wo, temp);
     Py_INCREF(Py_None);
     return Py_None;
 }
diff --git a/Modules/_json.c b/Modules/_json.c
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -1717,8 +1717,7 @@
     }
     else if (PyUnicode_Check(s->encoding)) {
         PyObject *tmp = PyUnicode_AsEncodedString(s->encoding, NULL, NULL);
-        Py_DECREF(s->encoding);
-        s->encoding = tmp;
+        Py_SETREF(s->encoding, tmp);
     }
     if (s->encoding == NULL)
         goto bail;
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -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_SETREF(self->statement_cache,
+              (pysqlite_Cache *)PyObject_CallFunction((PyObject *)&pysqlite_CacheType, "O", self));
     Py_DECREF(self);
     self->statement_cache->decref_factory = 0;
 }
@@ -346,9 +346,8 @@
     _pysqlite_drop_unused_cursor_references(self);
 
     if (cursor && self->row_factory != Py_None) {
-        Py_XDECREF(((pysqlite_Cursor*)cursor)->row_factory);
         Py_INCREF(self->row_factory);
-        ((pysqlite_Cursor*)cursor)->row_factory = self->row_factory;
+        Py_SETREF(((pysqlite_Cursor *)cursor)->row_factory, self->row_factory);
     }
 
     return cursor;
@@ -816,8 +815,7 @@
         }
     }
 
-    Py_DECREF(self->statements);
-    self->statements = new_list;
+    Py_SETREF(self->statements, new_list);
 }
 
 static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self)
@@ -848,8 +846,7 @@
         }
     }
 
-    Py_DECREF(self->cursors);
-    self->cursors = new_list;
+    Py_SETREF(self->cursors, new_list);
 }
 
 PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs)
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -172,8 +172,7 @@
         return 0;
     }
 
-    Py_XDECREF(self->row_cast_map);
-    self->row_cast_map = PyList_New(0);
+    Py_SETREF(self->row_cast_map, PyList_New(0));
 
     for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
         converter = NULL;
@@ -544,9 +543,8 @@
     }
 
     /* reset description and rowcount */
-    Py_DECREF(self->description);
     Py_INCREF(Py_None);
-    self->description = Py_None;
+    Py_SETREF(self->description, Py_None);
     self->rowcount = -1L;
 
     func_args = PyTuple_New(1);
@@ -571,8 +569,8 @@
     }
 
     if (self->statement->in_use) {
-        Py_DECREF(self->statement);
-        self->statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType);
+        Py_SETREF(self->statement,
+                  PyObject_New(pysqlite_Statement, &pysqlite_StatementType));
         if (!self->statement) {
             goto error;
         }
@@ -683,8 +681,7 @@
                 numcols = sqlite3_column_count(self->statement->st);
                 Py_END_ALLOW_THREADS
 
-                Py_DECREF(self->description);
-                self->description = PyTuple_New(numcols);
+                Py_SETREF(self->description, PyTuple_New(numcols));
                 if (!self->description) {
                     goto error;
                 }
diff --git a/Modules/_sre.c b/Modules/_sre.c
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -2054,8 +2054,7 @@
     if (!copy)
         return 0;
 
-    Py_DECREF(*object);
-    *object = copy;
+    Py_SETREF(*object, copy);
 
     return 1; /* success */
 }
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -1467,8 +1467,7 @@
         return -1;
 #else
         Py_INCREF(value);
-        Py_DECREF(self->ctx);
-        self->ctx = (PySSLContext *) value;
+        Py_SETREF(self->ctx, (PySSLContext *)value);
         SSL_set_SSL_CTX(self->ssl, self->ctx->ctx);
 #endif
     } else {
diff --git a/Modules/bz2module.c b/Modules/bz2module.c
--- a/Modules/bz2module.c
+++ b/Modules/bz2module.c
@@ -1953,9 +1953,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_SETREF(self->unused_data,
+                          PyString_FromStringAndSize(bzs->next_in, input_left));
                 if (self->unused_data == NULL)
                     goto error;
             }
diff --git a/Modules/cPickle.c b/Modules/cPickle.c
--- a/Modules/cPickle.c
+++ b/Modules/cPickle.c
@@ -689,8 +689,7 @@
     }
     if (! str) return -1;
 
-    Py_XDECREF(self->last_string);
-    self->last_string = str;
+    Py_SETREF(self->last_string, str);
 
     if (! (*s = PyString_AsString(str))) return -1;
 
@@ -716,8 +715,7 @@
     if ((str_size = PyString_Size(str)) < 0)
         return -1;
 
-    Py_XDECREF(self->last_string);
-    self->last_string = str;
+    Py_SETREF(self->last_string, str);
 
     if (! (*s = PyString_AsString(str)))
         return -1;
@@ -3228,9 +3226,8 @@
                         "attribute deletion is not supported");
         return -1;
     }
-    Py_XDECREF(p->pers_func);
     Py_INCREF(v);
-    p->pers_func = v;
+    Py_SETREF(p->pers_func, v);
     return 0;
 }
 
@@ -3242,9 +3239,8 @@
                         "attribute deletion is not supported");
         return -1;
     }
-    Py_XDECREF(p->inst_pers_func);
     Py_INCREF(v);
-    p->inst_pers_func = v;
+    Py_SETREF(p->inst_pers_func, v);
     return 0;
 }
 
@@ -3270,9 +3266,8 @@
         PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
         return -1;
     }
-    Py_XDECREF(p->memo);
     Py_INCREF(v);
-    p->memo = v;
+    Py_SETREF(p->memo, v);
     return 0;
 }
 
@@ -5667,16 +5662,14 @@
 {
 
     if (!strcmp(name, "persistent_load")) {
-        Py_XDECREF(self->pers_func);
-        self->pers_func = value;
         Py_XINCREF(value);
+        Py_SETREF(self->pers_func, value);
         return 0;
     }
 
     if (!strcmp(name, "find_global")) {
-        Py_XDECREF(self->find_class);
-        self->find_class = value;
         Py_XINCREF(value);
+        Py_SETREF(self->find_class, value);
         return 0;
     }
 
@@ -5692,9 +5685,8 @@
                             "memo must be a dictionary");
             return -1;
         }
-        Py_XDECREF(self->memo);
-        self->memo = value;
         Py_INCREF(value);
+        Py_SETREF(self->memo, value);
         return 0;
     }
 
diff --git a/Modules/cdmodule.c b/Modules/cdmodule.c
--- a/Modules/cdmodule.c
+++ b/Modules/cdmodule.c
@@ -628,12 +628,10 @@
     CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback,
                   (void *) self);
 #endif
-    Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
     Py_INCREF(func);
-    self->ob_cdcallbacks[type].ob_cdcallback = func;
-    Py_XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
+    Py_SETREF(self->ob_cdcallbacks[type].ob_cdcallback, func);
     Py_INCREF(funcarg);
-    self->ob_cdcallbacks[type].ob_cdcallbackarg = funcarg;
+    Py_SETREF(self->ob_cdcallbacks[type].ob_cdcallbackarg, funcarg);
 
 /*
     if (type == cd_audio) {
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -494,8 +494,7 @@
         link = teedataobject_jumplink(to->dataobj);
         if (link == NULL)
             return NULL;
-        Py_DECREF(to->dataobj);
-        to->dataobj = (teedataobject *)link;
+        Py_SETREF(to->dataobj, (teedataobject *)link);
         to->index = 0;
     }
     value = teedataobject_getitem(to->dataobj, to->index);
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -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_SETREF(Handlers[SIGINT].func, IntHandler);
         old_siginthandler = PyOS_setsig(SIGINT, signal_handler);
     }
 
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -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_SETREF(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_SETREF(self->unconsumed_tail, new_data);
     }
     return 0;
 }
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -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_SETREF(prop->prop_doc, get_doc);
             }
             else {
                 /* If this is a property subclass, put __doc__
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -58,9 +58,8 @@
     if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
         return -1;
 
-    Py_DECREF(self->args);
-    self->args = args;
-    Py_INCREF(self->args);
+    Py_INCREF(args);
+    Py_SETREF(self->args, args);
 
     if (PyTuple_GET_SIZE(self->args) == 1) {
         Py_CLEAR(self->message);
@@ -627,8 +626,7 @@
         if (!subslice)
             return -1;
 
-        Py_DECREF(self->args);  /* replacing args */
-        self->args = subslice;
+        Py_SETREF(self->args, subslice);
     }
     return 0;
 }
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -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_SETREF(file->f_encoding, str);
+    Py_SETREF(file->f_errors, oerrors);
     return 1;
 }
 
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -859,8 +859,7 @@
             }
         } else if (values[j] != value) {
             Py_XINCREF(value);
-            Py_XDECREF(values[j]);
-            values[j] = value;
+            Py_SETREF(values[j], value);
         }
         Py_XDECREF(value);
     }
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -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_SETREF(((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_SETREF(((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_SETREF(newfunc->func_name, name);
     }
     if (defaults != Py_None) {
         Py_INCREF(defaults);
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -3865,8 +3865,7 @@
         return;
     }
     v = string_concat((PyStringObject *) *pv, w);
-    Py_DECREF(*pv);
-    *pv = v;
+    Py_SETREF(*pv, v);
 }
 
 void
@@ -4751,8 +4750,7 @@
     t = PyDict_GetItem(interned, (PyObject *)s);
     if (t) {
         Py_INCREF(t);
-        Py_DECREF(*p);
-        *p = t;
+        Py_SETREF(*p, t);
         return;
     }
 
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -166,9 +166,8 @@
            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_INCREF(Py_None);
+            Py_SETREF(method_cache[i].name, Py_None);
         }
         /* mark all version tags as invalid */
         PyType_Modified(&PyBaseObject_Type);
@@ -2527,8 +2526,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_SETREF(method_cache[h].name, name);
     }
     return res;
 }
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -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_SETREF(*unicode, w);
         return 0;
     }
 
diff --git a/Python/_warnings.c b/Python/_warnings.c
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -528,8 +528,7 @@
                     goto handle_error;
                 }
                 else if (!is_true) {
-                    Py_DECREF(*filename);
-                    *filename = PyString_FromString("__main__");
+                    Py_SETREF(*filename, PyString_FromString("__main__"));
                     if (*filename == NULL)
                         goto handle_error;
                 }
diff --git a/Python/ceval.c b/Python/ceval.c
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -4360,8 +4360,7 @@
             Py_INCREF(self);
             func = PyMethod_GET_FUNCTION(func);
             Py_INCREF(func);
-            Py_DECREF(*pfunc);
-            *pfunc = self;
+            Py_SETREF(*pfunc, self);
             na++;
             n++;
         } else
diff --git a/Python/compile.c b/Python/compile.c
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1455,9 +1455,8 @@
     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_INCREF(c->u->u_private);
+    Py_INCREF(s->v.ClassDef.name);
+    Py_SETREF(c->u->u_private, s->v.ClassDef.name);
     str = PyString_InternFromString("__name__");
     if (!str || !compiler_nameop(c, str, Load)) {
         Py_XDECREF(str);

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list