Skip to content

Commit

Permalink
do not dispose the iterable until wrapper is disposed
Browse files Browse the repository at this point in the history
e.g. when a python list is passed to ui listbox, it will hold
a reference to the iterator instance. it works when it iterates
the first time but it crashes on later iterations since
the iterator gets disposed on first iteration
  • Loading branch information
eirannejad committed Dec 21, 2023
1 parent 1287b19 commit cc03d51
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/runtime/CollectionWrappers/IterableWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,44 @@ namespace Python.Runtime.CollectionWrappers
internal class IterableWrapper<T> : IEnumerable<T>
{
protected readonly PyObject pyObject;
PyIter? iterObject;

public IterableWrapper(PyObject pyObj)
{
if (pyObj == null)
throw new ArgumentNullException();

pyObject = new PyObject(pyObj.Reference);
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public IEnumerator<T> GetEnumerator()
{
PyIter iterObject;
using (Py.GIL())
{
iterObject = PyIter.GetIter(pyObject);
}

using var _ = iterObject;
while (true)
{
using var GIL = Py.GIL();

if (!iterObject.MoveNext())
{
iterObject.Dispose();
break;
}

yield return iterObject.Current.As<T>()!;
}
}

~IterableWrapper()
{
using (Py.GIL())
{
iterObject?.Dispose();
iterObject = null;
}
}
}
}

0 comments on commit cc03d51

Please sign in to comment.