bpo-39573: Use Py_REFCNT() macro (GH-18388)

Replace direct acccess to PyObject.ob_refcnt with usage of the
Py_REFCNT() macro.
diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
index 987087b..50d8c58 100644
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -649,7 +649,7 @@
     for (;;) {
         PyObject *op2;
 
-        if (args->ob_refcnt > 1) {
+        if (Py_REFCNT(args) > 1) {
             Py_DECREF(args);
             if ((args = PyTuple_New(2)) == NULL)
                 goto Fail;
@@ -666,7 +666,7 @@
             result = op2;
         else {
             /* Update the args tuple in-place */
-            assert(args->ob_refcnt == 1);
+            assert(Py_REFCNT(args) == 1);
             Py_XSETREF(_PyTuple_ITEMS(args)[0], result);
             Py_XSETREF(_PyTuple_ITEMS(args)[1], op2);
             if ((result = PyObject_Call(func, args, NULL)) == NULL) {
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index c5812f8..27db86a 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -3550,8 +3550,8 @@
     PyObject *error_type, *error_value, *error_traceback;
 
     /* Temporarily resurrect the object. */
-    assert(self->ob_refcnt == 0);
-    self->ob_refcnt = 1;
+    assert(Py_REFCNT(self) == 0);
+    Py_REFCNT(self) = 1;
 
     /* Save the current exception, if any. */
     PyErr_Fetch(&error_type, &error_value, &error_traceback);
@@ -3573,17 +3573,19 @@
     /* Undo the temporary resurrection; can't use DECREF here, it would
      * cause a recursive call.
      */
-    assert(self->ob_refcnt > 0);
-    if (--self->ob_refcnt == 0)
-        return;         /* this is the normal path out */
+    assert(Py_REFCNT(self) > 0);
+    if (--Py_REFCNT(self) == 0) {
+        /* this is the normal path out */
+        return;
+    }
 
     /* __del__ resurrected it!  Make it look like the original Py_DECREF
      * never happened.
      */
     {
-        Py_ssize_t refcnt = self->ob_refcnt;
+        Py_ssize_t refcnt = Py_REFCNT(self);
         _Py_NewReference(self);
-        self->ob_refcnt = refcnt;
+        Py_REFCNT(self) = refcnt;
     }
     assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self));
     /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
diff --git a/Objects/enumobject.c b/Objects/enumobject.c
index 4786297..75703be 100644
--- a/Objects/enumobject.c
+++ b/Objects/enumobject.c
@@ -122,7 +122,7 @@
     }
     en->en_longindex = stepped_up;
 
-    if (result->ob_refcnt == 1) {
+    if (Py_REFCNT(result) == 1) {
         Py_INCREF(result);
         old_index = PyTuple_GET_ITEM(result, 0);
         old_item = PyTuple_GET_ITEM(result, 1);
@@ -167,7 +167,7 @@
     }
     en->en_index++;
 
-    if (result->ob_refcnt == 1) {
+    if (Py_REFCNT(result) == 1) {
         Py_INCREF(result);
         old_index = PyTuple_GET_ITEM(result, 0);
         old_item = PyTuple_GET_ITEM(result, 1);
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 527693c..c0eff8b 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -85,7 +85,7 @@
                             "EOF when reading a line");
         }
         else if (s[len-1] == '\n') {
-            if (result->ob_refcnt == 1)
+            if (Py_REFCNT(result) == 1)
                 _PyBytes_Resize(&result, len-1);
             else {
                 PyObject *v;
diff --git a/Objects/object.c b/Objects/object.c
index 9eaa163..f9682fe 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -58,7 +58,7 @@
     Py_ssize_t total = _Py_RefTotal;
     o = _PySet_Dummy;
     if (o != NULL)
-        total -= o->ob_refcnt;
+        total -= Py_REFCNT(o);
     return total;
 }
 
@@ -206,32 +206,32 @@
 int
 PyObject_CallFinalizerFromDealloc(PyObject *self)
 {
-    if (self->ob_refcnt != 0) {
+    if (Py_REFCNT(self) != 0) {
         _PyObject_ASSERT_FAILED_MSG(self,
                                     "PyObject_CallFinalizerFromDealloc called "
                                     "on object with a non-zero refcount");
     }
 
     /* Temporarily resurrect the object. */
-    self->ob_refcnt = 1;
+    Py_REFCNT(self) = 1;
 
     PyObject_CallFinalizer(self);
 
     _PyObject_ASSERT_WITH_MSG(self,
-                              self->ob_refcnt > 0,
+                              Py_REFCNT(self) > 0,
                               "refcount is too small");
 
     /* Undo the temporary resurrection; can't use DECREF here, it would
      * cause a recursive call. */
-    if (--self->ob_refcnt == 0) {
+    if (--Py_REFCNT(self) == 0) {
         return 0;         /* this is the normal path out */
     }
 
     /* tp_finalize resurrected it!  Make it look like the original Py_DECREF
      * never happened. */
-    Py_ssize_t refcnt = self->ob_refcnt;
+    Py_ssize_t refcnt = Py_REFCNT(self);
     _Py_NewReference(self);
-    self->ob_refcnt = refcnt;
+    Py_REFCNT(self) = refcnt;
 
     _PyObject_ASSERT(self,
                      (!PyType_IS_GC(Py_TYPE(self))
@@ -263,12 +263,12 @@
         Py_END_ALLOW_THREADS
     }
     else {
-        if (op->ob_refcnt <= 0) {
+        if (Py_REFCNT(op) <= 0) {
             /* XXX(twouters) cast refcount to long until %zd is
                universally available */
             Py_BEGIN_ALLOW_THREADS
             fprintf(fp, "<refcnt %ld at %p>",
-                (long)op->ob_refcnt, (void *)op);
+                (long)Py_REFCNT(op), (void *)op);
             Py_END_ALLOW_THREADS
         }
         else {
@@ -363,7 +363,7 @@
     fprintf(stderr, "object address  : %p\n", (void *)op);
     /* XXX(twouters) cast refcount to long until %zd is
        universally available */
-    fprintf(stderr, "object refcount : %ld\n", (long)op->ob_refcnt);
+    fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op));
     fflush(stderr);
 
     PyTypeObject *type = Py_TYPE(op);
@@ -1010,7 +1010,7 @@
         return err;
     }
     Py_DECREF(name);
-    _PyObject_ASSERT(name, name->ob_refcnt >= 1);
+    _PyObject_ASSERT(name, Py_REFCNT(name) >= 1);
     if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
         PyErr_Format(PyExc_TypeError,
                      "'%.100s' object has no attributes "
@@ -1829,7 +1829,7 @@
 void
 _Py_ForgetReference(PyObject *op)
 {
-    if (op->ob_refcnt < 0) {
+    if (Py_REFCNT(op) < 0) {
         _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt");
     }
 
@@ -1867,7 +1867,7 @@
     PyObject *op;
     fprintf(fp, "Remaining objects:\n");
     for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
-        fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", (void *)op, op->ob_refcnt);
+        fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", (void *)op, Py_REFCNT(op));
         if (PyObject_Print(op, fp, 0) != 0)
             PyErr_Clear();
         putc('\n', fp);
@@ -1884,7 +1884,7 @@
     fprintf(fp, "Remaining object addresses:\n");
     for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
         fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", (void *)op,
-            op->ob_refcnt, Py_TYPE(op)->tp_name);
+            Py_REFCNT(op), Py_TYPE(op)->tp_name);
 }
 
 PyObject *
@@ -2025,7 +2025,7 @@
 
     _PyObject_ASSERT(op, PyObject_IS_GC(op));
     _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op));
-    _PyObject_ASSERT(op, op->ob_refcnt == 0);
+    _PyObject_ASSERT(op, Py_REFCNT(op) == 0);
     _PyGCHead_SET_PREV(_Py_AS_GC(op), gcstate->trash_delete_later);
     gcstate->trash_delete_later = op;
 }
@@ -2037,7 +2037,7 @@
     PyThreadState *tstate = _PyThreadState_GET();
     _PyObject_ASSERT(op, PyObject_IS_GC(op));
     _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op));
-    _PyObject_ASSERT(op, op->ob_refcnt == 0);
+    _PyObject_ASSERT(op, Py_REFCNT(op) == 0);
     _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later);
     tstate->trash_delete_later = op;
 }
@@ -2064,7 +2064,7 @@
          * assorted non-release builds calling Py_DECREF again ends
          * up distorting allocation statistics.
          */
-        _PyObject_ASSERT(op, op->ob_refcnt == 0);
+        _PyObject_ASSERT(op, Py_REFCNT(op) == 0);
         ++gcstate->trash_delete_nesting;
         (*dealloc)(op);
         --gcstate->trash_delete_nesting;
@@ -2102,7 +2102,7 @@
          * assorted non-release builds calling Py_DECREF again ends
          * up distorting allocation statistics.
          */
-        _PyObject_ASSERT(op, op->ob_refcnt == 0);
+        _PyObject_ASSERT(op, Py_REFCNT(op) == 0);
         (*dealloc)(op);
         assert(tstate->trash_delete_nesting == 1);
     }
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 8c8c66f..d114bd6 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -153,7 +153,7 @@
 PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem)
 {
     PyObject **p;
-    if (!PyTuple_Check(op) || op->ob_refcnt != 1) {
+    if (!PyTuple_Check(op) || Py_REFCNT(op) != 1) {
         Py_XDECREF(newitem);
         PyErr_BadInternalCall();
         return -1;
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 01def83..d85ff3c 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1173,8 +1173,9 @@
         }
         if (type->tp_del) {
             type->tp_del(self);
-            if (self->ob_refcnt > 0)
+            if (Py_REFCNT(self) > 0) {
                 return;
+            }
         }
 
         /* Find the nearest base with a different tp_dealloc */
@@ -1239,7 +1240,7 @@
     if (type->tp_del) {
         _PyObject_GC_TRACK(self);
         type->tp_del(self);
-        if (self->ob_refcnt > 0) {
+        if (Py_REFCNT(self) > 0) {
             /* Resurrected */
             goto endlabel;
         }
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index bf79e0c..d104b64 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -952,7 +952,8 @@
 
     if (object == NULL
         || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))
-        || object->ob_refcnt != 0) {
+        || Py_REFCNT(object) != 0)
+    {
         PyErr_BadInternalCall();
         return;
     }
@@ -975,8 +976,9 @@
             current->wr_callback = NULL;
             clear_weakref(current);
             if (callback != NULL) {
-                if (((PyObject *)current)->ob_refcnt > 0)
+                if (Py_REFCNT((PyObject *)current) > 0) {
                     handle_callback(current, callback);
+                }
                 Py_DECREF(callback);
             }
         }
@@ -993,8 +995,7 @@
             for (i = 0; i < count; ++i) {
                 PyWeakReference *next = current->wr_next;
 
-                if (((PyObject *)current)->ob_refcnt > 0)
-                {
+                if (Py_REFCNT((PyObject *)current) > 0) {
                     Py_INCREF(current);
                     PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
                     PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 1cb1030..d8d1874 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -1656,7 +1656,7 @@
 sys_getrefcount_impl(PyObject *module, PyObject *object)
 /*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/
 {
-    return object->ob_refcnt;
+    return Py_REFCNT(object);
 }
 
 #ifdef Py_REF_DEBUG