|
1 | 1 | using System;
|
2 | 2 | using System.Collections;
|
3 | 3 | using System.Collections.Generic;
|
| 4 | +using System.Diagnostics; |
| 5 | +using System.Linq; |
4 | 6 | using System.Reflection;
|
5 | 7 | using System.Runtime.InteropServices;
|
6 | 8 | using System.Security;
|
7 |
| -using System.Linq; |
8 | 9 |
|
9 | 10 | namespace Python.Runtime
|
10 | 11 | {
|
@@ -151,8 +152,12 @@ internal static Dictionary<ManagedType, InterDomainContext> RestoreRuntimeData(R
|
151 | 152 | invalidClasses.Add(pair);
|
152 | 153 | continue;
|
153 | 154 | }
|
| 155 | + // Ensure, that matching Python type exists first. |
| 156 | + // It is required for self-referential classes |
| 157 | + // (e.g. with members, that refer to the same class) |
| 158 | + var pyType = InitPyType(pair.Key.Value, pair.Value); |
154 | 159 | // re-init the class
|
155 |
| - InitClassBase(pair.Key.Value, pair.Value); |
| 160 | + InitClassBase(pair.Key.Value, pair.Value, pyType); |
156 | 161 | // We modified the Type object, notify it we did.
|
157 | 162 | Runtime.PyType_Modified(pair.Value.TypeReference);
|
158 | 163 | var context = contexts[pair.Value.pyHandle];
|
@@ -184,9 +189,13 @@ internal static ClassBase GetClass(Type type)
|
184 | 189 | }
|
185 | 190 | cb = CreateClass(type);
|
186 | 191 | cache.Add(type, cb);
|
| 192 | + // Ensure, that matching Python type exists first. |
| 193 | + // It is required for self-referential classes |
| 194 | + // (e.g. with members, that refer to the same class) |
| 195 | + var pyType = InitPyType(type, cb); |
187 | 196 | // Initialize the object later, as this might call this GetClass method
|
188 | 197 | // recursively (for example when a nested class inherits
57AE
its declaring class...)
|
189 |
| - InitClassBase(type, cb); |
| 198 | + InitClassBase(type, cb, pyType); |
190 | 199 | return cb;
|
191 | 200 | }
|
192 | 201 |
|
@@ -249,16 +258,18 @@ private static ClassBase CreateClass(Type type)
|
249 | 258 | return impl;
|
250 | 259 | }
|
251 | 260 |
|
252 |
| - private static void InitClassBase(Type type, ClassBase impl) |
| 261 | + private static PyType InitPyType(Type type, ClassBase impl) |
253 | 262 | {
|
254 |
| - // Ensure, that matching Python type exists first. |
255 |
| - // It is required for self-referential classes |
256 |
| - // (e.g. with members, that refer to the same class) |
257 | 263 | var pyType = TypeManager.GetOrCreateClass(type);
|
258 | 264 |
|
259 | 265 | // Set the handle attributes on the implementing instance.
|
260 | 266 | impl.tpHandle = impl.pyHandle = pyType.Handle;
|
261 | 267 |
|
| 268 | + return pyType; |
| 269 | + } |
| 270 | + |
| 271 | + private static void InitClassBase(Type type, ClassBase impl, PyType pyType) |
| 272 | + { |
262 | 273 | // First, we introspect the managed type and build some class
|
263 | 274 | // information, including generating the member descriptors
|
264 | 275 | // that we'll be putting in the Python class __dict__.
|
@@ -549,6 +560,11 @@ private static ClassInfo GetClassInfo(Type type)
|
549 | 560 | }
|
550 | 561 | // Note the given instance might be uninitialized
|
551 | 562 | ob = GetClass(tp);
|
| 563 | + if (ob.pyHandle == IntPtr.Zero && ob is ClassObject) |
| 564 | + { |
| 565 | + ob.pyHandle = ob.tpHandle = TypeManager.GetOrCreateClass(tp).Handle; |
| 566 | + } |
| 567 | + Debug.Assert(ob.pyHandle != IntPtr.Zero); |
552 | 568 | // GetClass returns a Borrowed ref. ci.members owns the reference.
|
553 | 569 | ob.IncrRefCount();
|
554 | 570 | ci.members[mi.Name] = ob;
|
|
0 commit comments