Issue #20440: Massive replacing unsafe attribute setting code with special
macro Py_SETREF.
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index 408efc3..9cebaf4 100644
--- 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();
 }