Open duyang76 opened 1 month ago
Can someone take a look or provide some insight?
The class definition is below. It runs fine. But if I create an instance in polyglot notebook, the kernel crashes due to stack overflow. There is no infinite-loop in the code, just recursive call on the child nodes (which is empty). It seems that the .net interactive or polyglot causes infinite-loop somewhere.
public class TestIEnumerator : IEnumerable<TestIEnumerator>
{
private List<TestIEnumerator> children;
public List<TestIEnumerator> Children
{
get
{
if (children==null) children = new List<TestIEnumerator>();
return children;
}
}
public IEnumerator<TestIEnumerator> GetEnumerator()
{
List<TestIEnumerator> childList = new List<TestIEnumerator>();
recurseChildren(this, ref childList, 0);
return childList.GetEnumerator();
}
private void recurseChildren(TestIEnumerator f, ref List<TestIEnumerator>coll, int lvl)
{
coll.Add(f);
Console.WriteLine("RecurseChildren level: " + lvl);
foreach(TestIEnumerator tmp in f.Children)
{
RecurseChildren(tmp, ref coll, lvl+1);
}
}
System.Collection.IEnumerator System.Collection.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Can someone provide some thoughts?
I looked at the stack trace and source code, and found that the infinite loop is caused by the CreateForAnyEnumerable() in PlainTextFormatter{T}.cs (https://github.com/dotnet/interactive/blob/main/src/Microsoft.DotNet.Interactive.Formatting/PlainTextFormatter%7BT%7D.cs#L73). In particular, the IEnumerable<> look through around line 84. Even though FormatContext has limit for recursion depth, it does not apply here. So, it causes infinite loop if if T is IEnumerable\<T>.
I am able to work around by overriding PlainTextFormatter\<T>.Default to my own formatter. But what is the correct fix? Is the look-through still needed if T is IEnumerable\<T>?
I can replicate this issue with a bare minimum example: a class implementing IEnumerable of itself with an empty child list.
Version: 1.0.522904
I cannot post from my company's internal network, so I'm typing from my phone and taking a screenshot below. But it is pretty obvious.