Limit the nesting depth of a tuple passed as the second argument to
isinstance() or issubclass() to the recursion limit of the interpreter.
diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py
index 1b8c593..4562114 100644
--- a/Lib/test/test_isinstance.py
+++ b/Lib/test/test_isinstance.py
@@ -4,6 +4,7 @@
 
 import unittest
 from test import test_support
+import sys
 
 
 
@@ -244,7 +245,23 @@
         self.assertEqual(True, issubclass(int, (long, (float, int))))
         self.assertEqual(True, issubclass(str, (unicode, (Child, NewChild, basestring))))
 
+    def test_subclass_recursion_limit(self):
+        # make sure that issubclass raises RuntimeError before the C stack is
+        # blown
+        self.assertRaises(RuntimeError, blowstack, issubclass, str, str)
 
+    def test_isinstance_recursion_limit(self):
+        # make sure that issubclass raises RuntimeError before the C stack is
+        # blown 
+        self.assertRaises(RuntimeError, blowstack, isinstance, '', str)
+
+def blowstack(fxn, arg, compare_to):
+    # Make sure that calling isinstance with a deeply nested tuple for its
+    # argument will raise RuntimeError eventually.
+    tuple_arg = (compare_to,)
+    for cnt in xrange(sys.getrecursionlimit()+5):
+        tuple_arg = (tuple_arg,)
+        fxn(arg, tuple_arg)
 
 
 def test_main():
diff --git a/Misc/NEWS b/Misc/NEWS
index b0693e0..9f27fd7 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@
 Core and builtins
 -----------------
 
+- Limit the nested depth of a tuple for the second argument to isinstance()
+  and issubclass() to the recursion limit of the interpreter.
+  Fixes bug  #858016 .
+
 - Optimized dict iterators, creating separate types for each
   and having them reveal their length.  Also optimized the
   methods:  keys(), values(), and items().
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 060abc5..3d6d829 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1992,8 +1992,8 @@
 	return -1;
 }
 
-int
-PyObject_IsInstance(PyObject *inst, PyObject *cls)
+static int
+recursive_isinstance(PyObject *inst, PyObject *cls, int recursion_depth)
 {
 	PyObject *icls;
 	static PyObject *__class__ = NULL;
@@ -2028,14 +2028,20 @@
 		}
 	}
 	else if (PyTuple_Check(cls)) {
-		/* Not a general sequence -- that opens up the road to
-		   recursion and stack overflow. */
 		int i, n;
 
+                if (!recursion_depth) {
+                    PyErr_SetString(PyExc_RuntimeError,
+                                    "nest level of tuple too deep");
+                    return NULL;
+                }
+
 		n = PyTuple_GET_SIZE(cls);
 		for (i = 0; i < n; i++) {
-			retval = PyObject_IsInstance(
-				inst, PyTuple_GET_ITEM(cls, i));
+			retval = recursive_isinstance(
+                                    inst,
+                                    PyTuple_GET_ITEM(cls, i),
+                                    recursion_depth-1);
 			if (retval != 0)
 				break;
 		}
@@ -2060,7 +2066,13 @@
 }
 
 int
-PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+PyObject_IsInstance(PyObject *inst, PyObject *cls)
+{
+    return recursive_isinstance(inst, cls, Py_GetRecursionLimit());
+}
+
+static  int
+recursive_issubclass(PyObject *derived, PyObject *cls, int recursion_depth)
 {
 	int retval;
 
@@ -2072,9 +2084,17 @@
 		if (PyTuple_Check(cls)) {
 			int i;
 			int n = PyTuple_GET_SIZE(cls);
+
+                        if (!recursion_depth) {
+                            PyErr_SetString(PyExc_RuntimeError,
+                                            "nest level of tuple too deep");
+                            return NULL;
+                        }
 			for (i = 0; i < n; ++i) {
-				retval = PyObject_IsSubclass(
-					derived, PyTuple_GET_ITEM(cls, i));
+				retval = recursive_issubclass(
+                                            derived,
+                                            PyTuple_GET_ITEM(cls, i),
+                                            recursion_depth-1);
 				if (retval != 0) {
 					/* either found it, or got an error */
 					return retval;
@@ -2100,6 +2120,13 @@
 	return retval;
 }
 
+int
+PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+{
+    return recursive_issubclass(derived, cls, Py_GetRecursionLimit());
+}
+
+
 PyObject *
 PyObject_GetIter(PyObject *o)
 {