diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 08670fb..61e4ca4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,29 @@
 2017-01-15  Tom Tromey  <tom@tromey.com>
 
+	* python/py-cmd.c (cmdpy_destroyer): Use gdbpy_subclass.
+	* python/py-breakpoint.c (gdbpy_breakpoint_deleted): Use
+	gdbpy_subclass.
+	* python/py-type.c (field_new): Use gdbpy_subclass.
+	* python/py-symtab.c (symtab_and_line_to_sal_object): Use
+	gdbpy_subclass.
+	* python/py-progspace.c (pspy_new): Use gdbpy_subclass.
+	(py_free_pspace): Likewise.
+	(pspace_to_pspace_object): Likewise.
+	* python/py-objfile.c (objfpy_new): Use gdbpy_subclass.
+	(py_free_objfile): Likewise.
+	(objfile_to_objfile_object): Likewise.
+	* python/py-inferior.c (delete_thread_object): Use
+	gdbpy_subclass.
+	(infpy_read_memory): Likewise.
+	(py_free_inferior): Likewise.
+	* python/py-evtregistry.c (create_eventregistry_object): Use
+	gdbpy_subclass.
+	* python/py-event.c (create_event_object): Use gdbpy_subclass.
+	* python/py-ref.h (gdbpy_ref_policy): Now a template class.
+	(gdbpy_subclass): New typedef.
+
+2017-01-15  Tom Tromey  <tom@tromey.com>
+
 	* ui-file.h (mem_fileopen): Return ui_file_up.
 	(ui_file_up): New typedef.
 	(ui_file_deleter): New struct.
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index f086725..f95a396 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -913,25 +913,23 @@ gdbpy_breakpoint_deleted (struct breakpoint *b)
   int num = b->number;
   PyGILState_STATE state;
   struct breakpoint *bp = NULL;
-  gdbpy_breakpoint_object *bp_obj;
 
   state = PyGILState_Ensure ();
   bp = get_breakpoint (num);
   if (bp)
     {
-      bp_obj = bp->py_bp_object;
-      if (bp_obj)
+      gdbpy_subclass<gdbpy_breakpoint_object> bp_obj (bp->py_bp_object);
+      if (bp_obj != NULL)
 	{
 	  if (!evregpy_no_listeners_p (gdb_py_events.breakpoint_deleted))
 	    {
-	      if (evpy_emit_event ((PyObject *) bp_obj,
+	      if (evpy_emit_event ((PyObject *) bp_obj.get (),
 				   gdb_py_events.breakpoint_deleted) < 0)
 		gdbpy_print_stack ();
 	    }
 
 	  bp_obj->bp = NULL;
 	  --bppy_live;
-	  Py_DECREF (bp_obj);
 	}
     }
   PyGILState_Release (state);
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 28c391c..b798c8a 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -95,14 +95,11 @@ cmdpy_dont_repeat (PyObject *self, PyObject *args)
 static void
 cmdpy_destroyer (struct cmd_list_element *self, void *context)
 {
-  cmdpy_object *cmd;
-
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
   /* Release our hold on the command object.  */
-  cmd = (cmdpy_object *) context;
+  gdbpy_subclass<cmdpy_object> cmd ((cmdpy_object *) context);
   cmd->command = NULL;
-  Py_DECREF (cmd);
 
   /* We allocated the name, doc string, and perhaps the prefix
      name.  */
diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c
index a50da1f..1369fb4 100644
--- a/gdb/python/py-event.c
+++ b/gdb/python/py-event.c
@@ -30,21 +30,15 @@ evpy_dealloc (PyObject *self)
 PyObject *
 create_event_object (PyTypeObject *py_type)
 {
-  event_object *event_obj;
-
-  event_obj = PyObject_New (event_object, py_type);
-  if (!event_obj)
-    goto fail;
+  gdbpy_subclass<event_object> event_obj (PyObject_New (event_object, py_type));
+  if (event_obj == NULL)
+    return NULL;
 
   event_obj->dict = PyDict_New ();
   if (!event_obj->dict)
-    goto fail;
-
-  return (PyObject*) event_obj;
+    return NULL;
 
- fail:
-  Py_XDECREF (event_obj);
-  return NULL;
+  return (PyObject*) event_obj.release ();
 }
 
 /* Add the attribute ATTR to the event object EVENT.  In
diff --git a/gdb/python/py-evtregistry.c b/gdb/python/py-evtregistry.c
index 81bf927..023a7ce 100644
--- a/gdb/python/py-evtregistry.c
+++ b/gdb/python/py-evtregistry.c
@@ -20,6 +20,7 @@
 #include "defs.h"
 #include "command.h"
 #include "py-events.h"
+#include "py-ref.h"
 
 events_object gdb_py_events;
 
@@ -79,22 +80,18 @@ evregpy_disconnect (PyObject *self, PyObject *function)
 eventregistry_object *
 create_eventregistry_object (void)
 {
-  eventregistry_object *eventregistry_obj;
+  gdbpy_subclass<eventregistry_object>
+    eventregistry_obj (PyObject_New (eventregistry_object,
+				     &eventregistry_object_type));
 
-  eventregistry_obj = PyObject_New (eventregistry_object,
-                                    &eventregistry_object_type);
-
-  if (!eventregistry_obj)
+  if (eventregistry_obj == NULL)
     return NULL;
 
   eventregistry_obj->callbacks = PyList_New (0);
   if (!eventregistry_obj->callbacks)
-    {
-      Py_DECREF (eventregistry_obj);
-      return NULL;
-    }
+    return NULL;
 
-  return eventregistry_obj;
+  return eventregistry_obj.release ();
 }
 
 static void
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 3594be2..8b07f72 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -28,6 +28,7 @@
 #include "symfile.h"
 #include "objfiles.h"
 #include "user-regs.h"
+#include "py-ref.h"
 
 typedef struct {
   PyObject_HEAD
@@ -361,9 +362,8 @@ frapy_function (PyObject *self, PyObject *args)
 PyObject *
 frame_info_to_frame_object (struct frame_info *frame)
 {
-  frame_object *frame_obj;
-
-  frame_obj = PyObject_New (frame_object, &frame_object_type);
+  gdbpy_subclass<frame_object> frame_obj
+    (PyObject_New (frame_object, &frame_object_type));
   if (frame_obj == NULL)
     return NULL;
 
@@ -389,13 +389,12 @@ frame_info_to_frame_object (struct frame_info *frame)
     }
   CATCH (except, RETURN_MASK_ALL)
     {
-      Py_DECREF (frame_obj);
       gdbpy_convert_exception (except);
       return NULL;
     }
   END_CATCH
 
-  return (PyObject *) frame_obj;
+  return (PyObject *) frame_obj.release ();
 }
 
 /* Implementation of gdb.Frame.older (self) -> gdb.Frame.
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 9e10d62..e2f21d4 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -307,7 +307,6 @@ add_thread_object (struct thread_info *tp)
 static void
 delete_thread_object (struct thread_info *tp, int ignore)
 {
-  inferior_object *inf_obj;
   struct threadlist_entry **entry, *tmp;
 
   if (!gdb_python_initialized)
@@ -315,9 +314,9 @@ delete_thread_object (struct thread_info *tp, int ignore)
 
   gdbpy_enter enter_py (python_gdbarch, python_language);
 
-  inf_obj
-    = (inferior_object *) find_inferior_object (ptid_get_pid (tp->ptid));
-  if (!inf_obj)
+  gdbpy_subclass<inferior_object> inf_obj
+    ((inferior_object *) find_inferior_object (ptid_get_pid (tp->ptid)));
+  if (inf_obj == NULL)
     return;
 
   /* Find thread entry in its inferior's thread_list.  */
@@ -327,10 +326,7 @@ delete_thread_object (struct thread_info *tp, int ignore)
       break;
 
   if (!*entry)
-    {
-      Py_DECREF (inf_obj);
-      return;
-    }
+    return;
 
   tmp = *entry;
   tmp->thread_obj->thread = NULL;
@@ -339,7 +335,6 @@ delete_thread_object (struct thread_info *tp, int ignore)
   inf_obj->nthreads--;
 
   Py_DECREF (tmp->thread_obj);
-  Py_DECREF (inf_obj);
   xfree (tmp);
 }
 
@@ -446,7 +441,6 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
 {
   CORE_ADDR addr, length;
   gdb_byte *buffer = NULL;
-  membuf_object *membuf_obj;
   PyObject *addr_obj, *length_obj, *result;
   static char *keywords[] = { "address", "length", NULL };
 
@@ -471,7 +465,8 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
     }
   END_CATCH
 
-  membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
+  gdbpy_subclass<membuf_object> membuf_obj (PyObject_New (membuf_object,
+							  &membuf_object_type));
   if (membuf_obj == NULL)
     {
       xfree (buffer);
@@ -483,12 +478,11 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
   membuf_obj->length = length;
 
 #ifdef IS_PY3K
-  result = PyMemoryView_FromObject ((PyObject *) membuf_obj);
+  result = PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
 #else
-  result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
+  result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj.get (), 0,
 					 Py_END_OF_BUFFER);
 #endif
-  Py_DECREF (membuf_obj);
 
   return result;
 }
@@ -776,7 +770,7 @@ infpy_dealloc (PyObject *obj)
 static void
 py_free_inferior (struct inferior *inf, void *datum)
 {
-  inferior_object *inf_obj = (inferior_object *) datum;
+  gdbpy_subclass<inferior_object> inf_obj ((inferior_object *) datum);
   struct threadlist_entry *th_entry, *th_tmp;
 
   if (!gdb_python_initialized)
@@ -797,8 +791,6 @@ py_free_inferior (struct inferior *inf, void *datum)
     }
 
   inf_obj->nthreads = 0;
-
-  Py_DECREF ((PyObject *) inf_obj);
 }
 
 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
index 694fa09..136dfa7 100644
--- a/gdb/python/py-objfile.c
+++ b/gdb/python/py-objfile.c
@@ -24,6 +24,7 @@
 #include "language.h"
 #include "build-id.h"
 #include "symtab.h"
+#include "py-ref.h"
 
 typedef struct
 {
@@ -227,18 +228,16 @@ objfpy_initialize (objfile_object *self)
 static PyObject *
 objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
 {
-  objfile_object *self = (objfile_object *) type->tp_alloc (type, 0);
+  gdbpy_subclass<objfile_object> self
+    ((objfile_object *) type->tp_alloc (type, 0));
 
-  if (self)
+  if (self != NULL)
     {
-      if (!objfpy_initialize (self))
-	{
-	  Py_DECREF (self);
-	  return NULL;
-	}
+      if (!objfpy_initialize (self.get ()))
+	return NULL;
     }
 
-  return (PyObject *) self;
+  return (PyObject *) self.release ();
 }
 
 PyObject *
@@ -612,11 +611,9 @@ gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
 static void
 py_free_objfile (struct objfile *objfile, void *datum)
 {
-  objfile_object *object = (objfile_object *) datum;
-
   gdbpy_enter enter_py (get_objfile_arch (objfile), current_language);
+  gdbpy_subclass<objfile_object> object ((objfile_object *) datum);
   object->objfile = NULL;
-  Py_DECREF ((PyObject *) object);
 }
 
 /* Return a borrowed reference to the Python object of type Objfile
@@ -627,26 +624,22 @@ py_free_objfile (struct objfile *objfile, void *datum)
 PyObject *
 objfile_to_objfile_object (struct objfile *objfile)
 {
-  objfile_object *object;
-
-  object = (objfile_object *) objfile_data (objfile, objfpy_objfile_data_key);
-  if (!object)
+  gdbpy_subclass<objfile_object> object
+    ((objfile_object *) objfile_data (objfile, objfpy_objfile_data_key));
+  if (object == NULL)
     {
-      object = PyObject_New (objfile_object, &objfile_object_type);
-      if (object)
+      object.reset (PyObject_New (objfile_object, &objfile_object_type));
+      if (object != NULL)
 	{
-	  if (!objfpy_initialize (object))
-	    {
-	      Py_DECREF (object);
-	      return NULL;
-	    }
+	  if (!objfpy_initialize (object.get ()))
+	    return NULL;
 
 	  object->objfile = objfile;
-	  set_objfile_data (objfile, objfpy_objfile_data_key, object);
+	  set_objfile_data (objfile, objfpy_objfile_data_key, object.get ());
 	}
     }
 
-  return (PyObject *) object;
+  return (PyObject *) object.release ();
 }
 
 int
diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c
index b0d9458..70e052b 100644
--- a/gdb/python/py-progspace.c
+++ b/gdb/python/py-progspace.c
@@ -24,6 +24,7 @@
 #include "objfiles.h"
 #include "language.h"
 #include "arch-utils.h"
+#include "py-ref.h"
 
 typedef struct
 {
@@ -128,18 +129,16 @@ pspy_initialize (pspace_object *self)
 static PyObject *
 pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
 {
-  pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
+  gdbpy_subclass<pspace_object> self
+    ((pspace_object *) type->tp_alloc (type, 0));
 
-  if (self)
+  if (self != NULL)
     {
-      if (!pspy_initialize (self))
-	{
-	  Py_DECREF (self);
-	  return NULL;
-	}
+      if (!pspy_initialize (self.get ()))
+	return NULL;
     }
 
-  return (PyObject *) self;
+  return (PyObject *) self.release ();
 }
 
 PyObject *
@@ -323,7 +322,7 @@ pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
 static void
 py_free_pspace (struct program_space *pspace, void *datum)
 {
-  pspace_object *object = (pspace_object *) datum;
+  gdbpy_subclass<pspace_object> object ((pspace_object *) datum);
   /* This is a fiction, but we're in a nasty spot: The pspace is in the
      process of being deleted, we can't rely on anything in it.  Plus
      this is one time when the current program space and current inferior
@@ -337,7 +336,6 @@ py_free_pspace (struct program_space *pspace, void *datum)
 
   gdbpy_enter enter_py (arch, current_language);
   object->pspace = NULL;
-  Py_DECREF ((PyObject *) object);
 }
 
 /* Return a borrowed reference to the Python object of type Pspace
@@ -348,26 +346,22 @@ py_free_pspace (struct program_space *pspace, void *datum)
 PyObject *
 pspace_to_pspace_object (struct program_space *pspace)
 {
-  pspace_object *object;
-
-  object = (pspace_object *) program_space_data (pspace, pspy_pspace_data_key);
-  if (!object)
+  gdbpy_subclass<pspace_object> object
+    ((pspace_object *) program_space_data (pspace, pspy_pspace_data_key));
+  if (object == NULL)
     {
-      object = PyObject_New (pspace_object, &pspace_object_type);
-      if (object)
+      object.reset (PyObject_New (pspace_object, &pspace_object_type));
+      if (object != NULL)
 	{
-	  if (!pspy_initialize (object))
-	    {
-	      Py_DECREF (object);
-	      return NULL;
-	    }
+	  if (!pspy_initialize (object.get ()))
+	    return NULL;
 
 	  object->pspace = pspace;
-	  set_program_space_data (pspace, pspy_pspace_data_key, object);
+	  set_program_space_data (pspace, pspy_pspace_data_key, object.get ());
 	}
     }
 
-  return (PyObject *) object;
+  return (PyObject *) object.release ();
 }
 
 int
diff --git a/gdb/python/py-ref.h b/gdb/python/py-ref.h
index b2479bf..3430768 100644
--- a/gdb/python/py-ref.h
+++ b/gdb/python/py-ref.h
@@ -1,6 +1,6 @@
 /* Python reference-holding class
 
-   Copyright (C) 2016 Free Software Foundation, Inc.
+   Copyright (C) 2016, 2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -23,20 +23,26 @@
 #include "common/gdb_ref_ptr.h"
 
 /* A policy class for gdb::ref_ptr for Python reference counting.  */
+template<typename T>
 struct gdbpy_ref_policy
 {
-  static void incref (PyObject *ptr)
+  static void incref (T *ptr)
   {
     Py_INCREF (ptr);
   }
 
-  static void decref (PyObject *ptr)
+  static void decref (T *ptr)
   {
     Py_DECREF (ptr);
   }
 };
 
 /* A gdb::ref_ptr that has been specialized for Python objects.  */
-typedef gdb::ref_ptr<PyObject, gdbpy_ref_policy> gdbpy_ref;
+typedef gdb::ref_ptr<PyObject, gdbpy_ref_policy<PyObject> > gdbpy_ref;
+
+/* A gdb::ref_ptr that has been specialized for "subclasses" of Python
+   objects.  */
+template<typename T> using gdbpy_subclass
+  = gdb::ref_ptr<T, gdbpy_ref_policy<T> >;
 
 #endif /* GDB_PYTHON_REF_H */
diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c
index 9fdb42f..770c898 100644
--- a/gdb/python/py-symtab.c
+++ b/gdb/python/py-symtab.c
@@ -24,6 +24,7 @@
 #include "python-internal.h"
 #include "objfiles.h"
 #include "block.h"
+#include "py-ref.h"
 
 typedef struct stpy_symtab_object {
   PyObject_HEAD
@@ -436,19 +437,15 @@ symtab_to_symtab_object (struct symtab *symtab)
 PyObject *
 symtab_and_line_to_sal_object (struct symtab_and_line sal)
 {
-  sal_object *sal_obj;
-
-  sal_obj = PyObject_New (sal_object, &sal_object_type);
-  if (sal_obj)
+  gdbpy_subclass<sal_object> sal_obj (PyObject_New (sal_object,
+						    &sal_object_type));
+  if (sal_obj != NULL)
     {
-      if (set_sal (sal_obj, sal) < 0)
-	{
-	  Py_DECREF (sal_obj);
-	  return NULL;
-	}
+      if (set_sal (sal_obj.get (), sal) < 0)
+	return NULL;
     }
 
-  return (PyObject *) sal_obj;
+  return (PyObject *) sal_obj.release ();
 }
 
 /* Return struct symtab_and_line reference that is wrapped by this
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 235e8b5..cc1bbf5 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -130,18 +130,16 @@ field_dealloc (PyObject *obj)
 static PyObject *
 field_new (void)
 {
-  field_object *result = PyObject_New (field_object, &field_object_type);
+  gdbpy_subclass<field_object> result (PyObject_New (field_object,
+						     &field_object_type));
 
-  if (result)
+  if (result != NULL)
     {
       result->dict = PyDict_New ();
       if (!result->dict)
-	{
-	  Py_DECREF (result);
-	  result = NULL;
-	}
+	return NULL;
     }
-  return (PyObject *) result;
+  return (PyObject *) result.release ();
 }
 
 
