Index: src/org/python/core/Py.java =================================================================== --- src/org/python/core/Py.java (revision 3416) +++ src/org/python/core/Py.java (working copy) @@ -1915,8 +1915,15 @@ } return false; } - + + private static int get_recursionlimit() { + return Py.getSystemState().getrecursionlimit(); + } + + public static int recursion_depth=1000; + public static boolean isInstance(PyObject obj, PyObject cls) { + recursion_depth--; if (cls instanceof PyType) { PyType objtype = obj.getType(); if (objtype == cls) @@ -1928,9 +1935,14 @@ return ((PyClass) obj.fastGetClass()).isSubClass((PyClass) cls); } else if (cls.getClass() == PyTuple.class) { for (int i = 0; i < cls.__len__(); i++) { - if (isInstance(obj, cls.__getitem__(i))) + if(recursion_depth == 0) + throw Py.RuntimeError("nest level of tuple too deep"); + if (isInstance(obj, cls.__getitem__(i))) { + recursion_depth = get_recursionlimit(); return true; + } } + recursion_depth = get_recursionlimit(); return false; } else { if (cls.__findattr__("__bases__") == null) @@ -1943,8 +1955,10 @@ return abstract_issubclass(ocls, cls); } } + public static boolean isSubClass(PyObject derived,PyObject cls) { + recursion_depth--; if (derived instanceof PyType && cls instanceof PyType) { if (derived == cls) return true; return ((PyType)derived).isSubType((PyType)cls); @@ -1952,9 +1966,14 @@ return ((PyClass)derived).isSubClass((PyClass)cls); } else if (cls.getClass() == PyTuple.class) { for (int i = 0; i < cls.__len__(); i++) { - if (isSubClass(derived, cls.__getitem__(i))) + if(recursion_depth == 0) + throw Py.RuntimeError("nest level of tuple too deep"); + if (isSubClass(derived, cls.__getitem__(i))) { + recursion_depth = get_recursionlimit(); return true; + } } + recursion_depth = get_recursionlimit(); return false; } else { if (derived.__findattr__("__bases__") == null) Index: Lib/test/test_isinstance.py =================================================================== --- Lib/test/test_isinstance.py (revision 3416) +++ Lib/test/test_isinstance.py (working copy) @@ -268,16 +268,18 @@ def test_main(): if test_support.is_jython: -# Jython transition 2.3 -# isinstance and issubclass don't prevent a StackOverflow with a deeply nested tuple -# http://jython.org/bugs/1768988 - del TestIsInstanceIsSubclass.test_isinstance_recursion_limit - del TestIsInstanceIsSubclass.test_subclass_recursion_limit + TestIsInstanceIsSubclass.test_isinstance_recursion_limit + TestIsInstanceIsSubclass.test_subclass_recursion_limit + test_support.run_unittest( + TestIsSubclassExceptions + ) + test_support.run_unittest( + TestIsInstanceIsSubclass + ) test_support.run_unittest( - TestIsInstanceExceptions, - TestIsSubclassExceptions, - TestIsInstanceIsSubclass + TestIsInstanceExceptions ) + if __name__ == '__main__':