Skip to content

Commit 390a8d4

Browse files
committed
fixed inability to invoke C# methods from base class when Python base is specified
1 parent 813e7ea commit 390a8d4

File tree

1 file changed

+34
-13
lines changed

1 file changed

+34
-13
lines changed

src/runtime/typemanager.cs

+34-13
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,16 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType)
136136
InitializeSlot(type, TypeOffset.tp_getattro, typeof(SlotOverrides).GetMethod(nameof(SlotOverrides.tp_getattro)));
137137
}
138138

139-
IntPtr base_ = GetBaseType(clrType);
139+
IntPtr base_ = GetBaseType(clrType, out IntPtr bases);
140140
if (base_ != IntPtr.Zero)
141141
{
142142
Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_);
143143
Runtime.XIncref(base_);
144+
145+
if (bases != IntPtr.Zero) {
146+
Marshal.WriteIntPtr(type, TypeOffset.tp_bases, bases);
147+
Runtime.XIncref(bases);
148+
}
144149
}
145150

146151
int flags = TypeFlags.Default;
@@ -230,29 +235,45 @@ static string CleanupFullName(string fullTypeName)
230235
return name;
231236
}
232237

233-
static IntPtr GetBaseType(Type clrType)
238+
static IntPtr GetBaseType(Type clrType, out IntPtr baseTypes)
234239
{
240+
baseTypes = IntPtr.Zero;
241+
if (clrType == typeof(Exception))
242+
{
243+
return Exceptions.Exception;
244+
}
245+
246+
var bases = new List<IntPtr>();
247+
248+
// .NET base class must always come first
249+
if (clrType.BaseType != null)
250+
{
251+
ClassBase bc = ClassManager.GetClass(clrType.BaseType);
252+
bases.Add(bc.pyHandle);
253+
}
254+
235255
var baseOverride = Util.GetLatestAttribute<BaseTypeAttributeBase>(clrType);
236256
IntPtr handle = baseOverride?.BaseType(clrType) ?? IntPtr.Zero;
237257
if (handle != IntPtr.Zero) {
238258
if ((Util.ReadCLong(handle, TypeOffset.tp_flags) & TypeFlags.BaseType) == 0) {
239259
throw new InvalidProgramException("The specified base Python type can not be inherited from");
240260
}
241261

242-
return handle;
262+
bases.Add(handle);
243263
}
244264

245-
if (clrType == typeof(Exception))
246-
{
247-
return Exceptions.Exception;
248-
}
249-
if (clrType.BaseType != null)
250-
{
251-
ClassBase bc = ClassManager.GetClass(clrType.BaseType);
252-
return bc.pyHandle;
265+
switch (bases.Count) {
266+
case 0:
267+
return IntPtr.Zero;
268+
case 1:
269+
return bases[0];
270+
default:
271+
baseTypes = Runtime.PyTuple_New(bases.Count);
272+
for (int baseIndex = 0; baseIndex < bases.Count; baseIndex++) {
273+
Runtime.PyTuple_SetItem(baseTypes, baseIndex, bases[baseIndex]);
274+
}
275+
return bases[0];
253276
}
254-
255-
return IntPtr.Zero;
256277
}
257278

258279
internal static IntPtr CreateSubType(IntPtr py_name, IntPtr py_base_type, IntPtr py_dict)

0 commit comments

Comments
 (0)