Skip to content

Commit 418e767

Browse files
committed
Implement __instancecheck__.
1 parent aa87074 commit 418e767

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

src/runtime/converter.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ internal static Type GetTypeByAlias(IntPtr op) {
8080
// This always returns a new reference. Note that the System.Decimal
8181
// type has no Python equivalent and converts to a managed instance.
8282
//====================================================================
83+
internal static IntPtr ToPython<T>(T value)
84+
{
85+
return ToPython(value, typeof(T));
86+
}
8387

8488
internal static IntPtr ToPython(Object value, Type type) {
8589
IntPtr result = IntPtr.Zero;

src/runtime/interop.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ static Interop() {
447447
pmap["bf_getcharbuffer"] = p["IntObjArgFunc"];
448448

449449
pmap["__import__"] = p["TernaryFunc"];
450+
pmap["__instancecheck__"] = p["BinaryFunc"];
450451
}
451452

452453
internal static Type GetPrototype(string name) {

src/runtime/metatype.cs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,30 @@ public static void tp_dealloc(IntPtr tp) {
260260
return;
261261
}
262262

263-
264-
265-
263+
public static IntPtr __instancecheck__(IntPtr tp, IntPtr args)
264+
{
265+
ClassBase cb = GetManagedObject(tp) as ClassBase;
266+
267+
if (cb == null)
268+
return Runtime.PyFalse;
269+
270+
using (PyList argsObj = new PyList(args))
271+
{
272+
if (argsObj.Length() != 1)
273+
return Exceptions.RaiseTypeError("Invalid parameter count");
274+
275+
PyObject arg = argsObj[0];
276+
PyObject otherType = arg.GetPythonType();
277+
278+
if (Runtime.PyObject_TYPE(otherType.Handle) != PyCLRMetaType)
279+
return Runtime.PyFalse;
280+
281+
ClassBase otherCb = GetManagedObject(otherType.Handle) as ClassBase;
282+
if (otherCb == null)
283+
return Runtime.PyFalse;
284+
285+
return Converter.ToPython(cb.type.IsAssignableFrom(otherCb.type));
286+
}
287+
}
266288
}
267-
268-
269289
}

src/runtime/typemanager.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,17 @@ internal static IntPtr CreateMetaType(Type impl) {
300300
flags |= TypeFlags.Managed;
301301
flags |= TypeFlags.HeapType;
302302
flags |= TypeFlags.HaveGC;
303-
Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
303+
Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
304+
305+
IntPtr fp = Interop.GetThunk(typeof(MetaType).GetMethod("__instancecheck__"));
306+
IntPtr mdef = Runtime.PyMem_Malloc(5 * IntPtr.Size);
307+
Marshal.WriteIntPtr(mdef, Marshal.StringToHGlobalAnsi("__instancecheck__"));
308+
Marshal.WriteIntPtr(mdef, (1 * IntPtr.Size), fp);
309+
Marshal.WriteIntPtr(mdef, (2 * IntPtr.Size), (IntPtr)0x0001); // METH_VARARGS
310+
Marshal.WriteIntPtr(mdef, (3 * IntPtr.Size), IntPtr.Zero);
311+
Marshal.WriteIntPtr(mdef, (4 * IntPtr.Size), IntPtr.Zero);
312+
313+
Marshal.WriteIntPtr(type, TypeOffset.tp_methods, mdef);
304314

305315
Runtime.PyType_Ready(type);
306316

0 commit comments

Comments
 (0)