8000 Track Runtime run number. Assert, that PyObjects are only disposed in… · pythonnet/pythonnet@fa1fdad · GitHub
[go: up one dir, main page]

Skip to content
10000

Commit fa1fdad

Browse files
committed
Track Runtime run number. Assert, that PyObjects are only disposed in the same run they were created in.
1 parent d932176 commit fa1fdad

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

src/runtime/pyobject.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class PyObject : DynamicObject, IEnumerable, IPyDisposable
2929
public StackTrace Traceback { get; private set; }
3030
#endif
3131

32+
readonly long run = Runtime.GetRun();
3233
protected internal IntPtr obj = IntPtr.Zero;
3334
private bool disposed = false;
3435
private bool _finalized = false;
@@ -169,6 +170,8 @@ protected virtual void Dispose(bool disposing)
169170
{
170171
if (Runtime.Py_IsInitialized() > 0 && !Runtime.IsFinalizing)
171172
{
173+
if (this.run != Runtime.GetRun())
174+
throw new InvalidOperationException("Attempt to dispose PyObject from wrong run");
172175
IntPtr gs = PythonEngine.AcquireLock();
173176
Runtime.XDecref(obj);
174177
obj = IntPtr.Zero;

src/runtime/runtime.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,17 @@ public class Runtime
171171

172172
private static PyReferenceCollection _pyRefs = new PyReferenceCollection();
173173

174+
static long run = 0;
175+
176+
internal static long GetRun()
177+
{
178+
long runNumber = Interlocked.Read(ref run);
179+
System.Diagnostics.Debug.Assert(runNumber > 0,
180+
"This must only be called after Runtime is initialized at least once");
181+
return runNumber;
182+
}
183+
184+
174185
/// <summary>
175186
/// Initialize the runtime...
176187
/// </summary>

0 commit comments

Comments
 (0)
0