Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5aca5cb

Browse files
author
denfromufa
authored
Merge pull request #250 from matthid/fix_stackoverflow
Fix a StackOverflowException.
2 parents 8029ffe + 502001e commit 5aca5cb

File tree

4 files changed

+48
-8
lines changed

4 files changed

+48
-8
lines changed

src/runtime/classmanager.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ internal static ClassBase GetClass(Type type)
5050
}
5151
cb = CreateClass(type);
5252
cache.Add(type, cb);
53+
// Initialize the object later, as this might call this GetClass method recursivly (for example when a nested class inherits its declaring class...)
54+
InitClassBase(type, cb);
5355
return cb;
5456
}
5557

@@ -62,12 +64,6 @@ internal static ClassBase GetClass(Type type)
6264

6365
private static ClassBase CreateClass(Type type)
6466
{
65-
// First, we introspect the managed type and build some class
66-
// information, including generating the member descriptors
67-
// that we'll be putting in the Python class __dict__.
68-
69-
ClassInfo info = GetClassInfo(type);
70-
7167
// Next, select the appropriate managed implementation class.
7268
// Different kinds of types, such as array types or interface
7369
// types, want to vary certain implementation details to make
@@ -115,6 +111,18 @@ private static ClassBase CreateClass(Type type)
115111
impl = new ClassObject(type);
116112
}
117113

114+
115+
return impl;
116+
}
117+
118+
private static void InitClassBase(Type type, ClassBase impl)
119+
{
120+
// First, we introspect the managed type and build some class
121+
// information, including generating the member descriptors
122+
// that we'll be putting in the Python class __dict__.
123+
124+
ClassInfo info = GetClassInfo(type);
125+
118126
impl.indexer = info.indexer;
119127

120128
// Now we allocate the Python type object to reflect the given
@@ -182,10 +190,8 @@ private static ClassBase CreateClass(Type type)
182190
}
183191
}
184192

185-
return impl;
186193
}
187194

188-
189195
private static ClassInfo GetClassInfo(Type type)
190196
{
191197
ClassInfo ci = new ClassInfo(type);
@@ -353,6 +359,7 @@ private static ClassInfo GetClassInfo(Type type)
353359
if (!(tp.IsNestedPublic || tp.IsNestedFamily ||
354360
tp.IsNestedFamORAssem))
355361
continue;
362+
// Note the given instance might be uninitialized
356363
ob = ClassManager.GetClass(tp);
357364
ci.members[mi.Name] = ob;
358365
continue;

src/testing/subclasstest.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ public virtual void OnTestEvent(int value)
6464
}
6565
}
6666

67+
public abstract class RecursiveInheritance
68+
{
69+
public class SubClass : RecursiveInheritance
70+
{
71+
public void SomeMethod()
72+
{
73+
74+
}
75+
}
76+
}
77+
6778
public class TestFunctions
6879
{
6980
public static string test_foo(IInterfaceTest x)

src/tests/test_suite/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
from .test_import import test_suite as import_tests
66
from .test_callback import test_suite as callback_tests
7+
from .test_recursiveTypes import test_suite as recursiveTypes_tests
78

89
def test_suite():
910
suite = unittest.TestSuite()
1011
suite.addTests((import_tests(),))
1112
suite.addTests((callback_tests(),))
13+
suite.addTests((recursiveTypes_tests(),))
1214
return suite
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import unittest, sys
2+
import clr
3+
4+
this_module = sys.modules[__name__]
5+
clr.AddReference("Python.Test")
6+
class RecursiveTypesTests(unittest.TestCase):
7+
"""Test if interop with recursive type inheritance works."""
8+
9+
def testRecursiveTypeCreation(self):
10+
"""Test that a recursive types don't crash with a StackOverflowException"""
11+
import Python.Test as Test
12+
from Python.Test import RecursiveInheritance
13+
test_instance = RecursiveInheritance.SubClass()
14+
test_instance.SomeMethod()
15+
pass
16+
17+
18+
def test_suite():
19+
return unittest.makeSuite(RecursiveTypesTests)
20+

0 commit comments

Comments
 (0)