@@ -27,6 +27,7 @@ public partial class PyObject : DynamicObject, IDisposable
27
27
#endif
28
28
29
29
protected internal IntPtr obj = IntPtr . Zero ;
30
+ readonly int run = Runtime . GetRun ( ) ;
30
31
31
32
public static PyObject None => new PyObject ( new BorrowedReference ( Runtime . PyNone ) ) ;
32
33
internal BorrowedReference Reference => new BorrowedReference ( this . obj ) ;
@@ -95,11 +96,15 @@ internal PyObject(in StolenReference reference)
95
96
// when the managed wrapper is garbage-collected.
96
97
~ PyObject ( )
97
98
{
98
- if ( obj == IntPtr . Zero )
99
- {
100
- return ;
101
- }
99
+ Debug . Assert ( obj != IntPtr . Zero ) ;
100
+
101
+ #if TRACE_ALLOC
102
+ CheckRun ( ) ;
103
+ #endif
104
+
102
105
Finalizer . Instance . AddFinalizedObject ( ref obj ) ;
106
+
107
+ Dispose ( false ) ;
103
108
}
104
109
105
110
@@ -167,17 +172,6 @@ public object AsManagedObject(Type t)
167
172
168
173
internal bool IsDisposed => obj == IntPtr . Zero ;
169
174
170
- /// <summary>
171
- /// Dispose Method
172
- /// </summary>
173
- /// <remarks>
174
- /// The Dispose method provides a way to explicitly release the
175
- /// Python object represented by a PyObject instance. It is a good
176
- /// idea to call Dispose on PyObjects that wrap resources that are
177
- /// limited or need strict lifetime control. Otherwise, references
178
- /// to Python objects will not be released until a managed garbage
179
- /// collection occurs.
180
- /// </remarks>
181
175
protected virtual void Dispose ( bool disposing )
182
176
{
183
177
if ( this . obj == IntPtr . Zero )
@@ -188,6 +182,8 @@ protected virtual void Dispose(bool disposing)
188
182
if ( Runtime . Py_IsInitialized ( ) == 0 )
189
183
throw new InvalidOperationException ( "Python runtime must be initialized" ) ;
190
184
185
+ CheckRun ( ) ;
186
+
191
187
if ( ! Runtime . IsFinalizing )
192
188
{
193
189
long refcount = Runtime . Refcount ( this . obj ) ;
@@ -221,10 +217,26 @@ protected virtual void Dispose(bool disposing)
221
217
this . obj = IntPtr . Zero ;
222
218
}
223
219
220
+ /// <summary>
221
+ /// The Dispose method provides a way to explicitly release the
222
+ /// Python object represented by a PyObject instance. It is a good
223
+ /// idea to call Dispose on PyObjects that wrap resources that are
224
+ /// limited or need strict lifetime control. Otherwise, references
225
+ /// to Python objects will not be released until a managed garbage
226
+ /// collection occurs.
227
+ /// </summary>
224
228
public void Dispose ( )
225
229
{
226
- Dispose ( true ) ;
227
230
GC . SuppressFinalize ( this ) ;
231
+ Dispose ( true ) ;
232
+ }
233
+
234
+ internal void CheckRun ( )
235
+ {
236
+ if ( run != Runtime . GetRun ( ) )
237
+ throw new InvalidOperationException (
238
+ "PythonEngine was shut down after this object was created." +
239
+ " It is an error to attempt to dispose or to continue using it." ) ;
228
240
}
229
241
230
242
internal BorrowedReference GetPythonTypeReference ( )
0 commit comments