diff --git a/gdb/python/py-continueevent.c b/gdb/python/py-continueevent.c
index 759b4831366..9708c0d4059 100644
--- a/gdb/python/py-continueevent.c
+++ b/gdb/python/py-continueevent.c
@@ -32,12 +32,13 @@
 static gdbpy_ref<>
 create_continue_event_object (ptid_t ptid)
 {
-  PyObject *py_thr = py_get_event_thread (ptid);
+  gdbpy_ref<> py_thr = py_get_event_thread (ptid);
 
   if (py_thr == nullptr)
     return nullptr;
 
-  return create_thread_event_object (&continue_event_object_type, py_thr);
+  return create_thread_event_object (&continue_event_object_type,
+				     py_thr.get ());
 }
 
 /* Callback function which notifies observers when a continue event occurs.
diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h
index 56003e8785f..96be83b44c5 100644
--- a/gdb/python/py-event.h
+++ b/gdb/python/py-event.h
@@ -68,9 +68,8 @@ extern gdbpy_ref<> create_event_object (PyTypeObject *py_type);
    running in non-stop mode then the event is thread specific, otherwise
    it is process wide.
    This function returns the currently stopped thread in non-stop mode and
-   Py_None otherwise.  In each case it returns a borrowed reference.  */
-extern PyObject *py_get_event_thread (ptid_t ptid)
-  CPYCHECKER_RETURNS_BORROWED_REF;
+   Py_None otherwise.  */
+extern gdbpy_ref<> py_get_event_thread (ptid_t ptid);
 
 extern gdbpy_ref<> create_thread_event_object (PyTypeObject *py_type,
 					       PyObject *thread);
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 1cf37296973..bf8ac75a316 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -306,7 +306,7 @@ find_inferior_object (int pid)
   return NULL;
 }
 
-thread_object *
+gdbpy_ref<>
 thread_to_thread_object (thread_info *thr)
 {
   gdbpy_ref<inferior_object> inf_obj (inferior_to_inferior_object (thr->inf));
@@ -317,7 +317,7 @@ thread_to_thread_object (thread_info *thr)
        thread != NULL;
        thread = thread->next)
     if (thread->thread_obj->thread == thr)
-      return thread->thread_obj;
+      return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj);
 
   return NULL;
 }
@@ -817,7 +817,7 @@ infpy_is_valid (PyObject *self, PyObject *args)
 PyObject *
 infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
 {
-  PyObject *handle_obj, *result;
+  PyObject *handle_obj;
   inferior_object *inf_obj = (inferior_object *) self;
   static const char *keywords[] = { "thread_handle", NULL };
 
@@ -826,8 +826,6 @@ infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
   if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
     return NULL;
 
-  result = Py_None;
-
   if (!gdbpy_is_value_object (handle_obj))
     {
       PyErr_SetString (PyExc_TypeError,
@@ -835,29 +833,27 @@ infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
 
       return NULL;
     }
-  else
+
+  gdbpy_ref<> result;
+  TRY
+    {
+      struct thread_info *thread_info;
+      struct value *val = value_object_to_value (handle_obj);
+
+      thread_info = find_thread_by_handle (val, inf_obj->inferior);
+      if (thread_info != NULL)
+	result = thread_to_thread_object (thread_info);
+    }
+  CATCH (except, RETURN_MASK_ALL)
     {
-      TRY
-	{
-	  struct thread_info *thread_info;
-	  struct value *val = value_object_to_value (handle_obj);
-
-	  thread_info = find_thread_by_handle (val, inf_obj->inferior);
-	  if (thread_info != NULL)
-	    {
-	      result = (PyObject *) thread_to_thread_object (thread_info);
-	      if (result != NULL)
-		Py_INCREF (result);
-	    }
-	}
-      CATCH (except, RETURN_MASK_ALL)
-	{
-	  GDB_PY_HANDLE_EXCEPTION (except);
-	}
-      END_CATCH
+      GDB_PY_HANDLE_EXCEPTION (except);
     }
+  END_CATCH
 
-  return result;
+  if (result == NULL)
+    result = gdbpy_ref<>::new_reference (Py_None);
+
+  return result.release ();
 }
 
 
diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c
index 36ae71b6358..4b2705a0af6 100644
--- a/gdb/python/py-infthread.c
+++ b/gdb/python/py-infthread.c
@@ -284,15 +284,7 @@ PyObject *
 gdbpy_selected_thread (PyObject *self, PyObject *args)
 {
   if (inferior_ptid != null_ptid)
-    {
-      PyObject *thread_obj
-	= (PyObject *) thread_to_thread_object (inferior_thread ());
-      if (thread_obj != NULL)
-	{
-	  Py_INCREF (thread_obj);
-	  return thread_obj;
-	}
-    }
+    return thread_to_thread_object (inferior_thread ()).release ();
 
   Py_RETURN_NONE;
 }
diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c
index f6bd207f3b8..cbdf7b7e7e0 100644
--- a/gdb/python/py-stopevent.c
+++ b/gdb/python/py-stopevent.c
@@ -23,8 +23,8 @@
 gdbpy_ref<>
 create_stop_event_object (PyTypeObject *py_type)
 {
-  return create_thread_event_object (py_type,
-				     py_get_event_thread (inferior_ptid));
+  gdbpy_ref<> thread = py_get_event_thread (inferior_ptid);
+  return create_thread_event_object (py_type, thread.get ());
 }
 
 /* Callback observers when a stop event occurs.  This function will create a
diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c
index 4f822b4ae09..13af1c840ba 100644
--- a/gdb/python/py-threadevent.c
+++ b/gdb/python/py-threadevent.c
@@ -22,19 +22,19 @@
 
 /* See py-event.h.  */
 
-PyObject *
+gdbpy_ref<>
 py_get_event_thread (ptid_t ptid)
 {
-  PyObject *pythread = nullptr;
+  gdbpy_ref<> pythread;
 
   if (non_stop)
     {
       thread_info *thread = find_thread_ptid (ptid);
       if (thread != nullptr)
-	pythread = (PyObject *) thread_to_thread_object (thread);
+	pythread = thread_to_thread_object (thread);
     }
   else
-    pythread = Py_None;
+    pythread = gdbpy_ref<>::new_reference (Py_None);
 
   if (pythread == nullptr)
     {
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index cbba3ff8ef6..dc8d7cdd32a 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -533,8 +533,7 @@ PyObject *gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw);
 PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch);
 
 thread_object *create_thread_object (struct thread_info *tp);
-thread_object *thread_to_thread_object (thread_info *thr)
-  CPYCHECKER_RETURNS_BORROWED_REF;
+gdbpy_ref<> thread_to_thread_object (thread_info *thr);;
 inferior_object *inferior_to_inferior_object (inferior *inf);
 
 const struct block *block_object_to_block (PyObject *obj);
