internal static IntPtr AllocateTypeObject(string name)
{
IntPtr type = Runtime.PyType_GenericAlloc(Runtime.PyTypeType, 0);
// Cheat a little: we'll set tp_name to the internal char * of
// the Python version of the type name - otherwise we'd have to
// allocate the tp_name and would have no way to free it.
#if PYTHON3
// For python3 we leak two objects. One for the ascii representation
// required for tp_name, and another for the unicode representation
// for ht_name.
IntPtr temp = Runtime.PyBytes_FromString(name);
IntPtr raw = Runtime.PyBytes_AS_STRING(temp);
temp = Runtime.PyUnicode_FromString(name);
#elif PYTHON2
IntPtr temp = Runtime.PyString_FromString(name);
IntPtr raw = Runtime.PyString_AS_STRING(temp);
#endif
Marshal.WriteIntPtr(type, TypeOffset.tp_name, raw);
Marshal.WriteIntPtr(type, TypeOffset.name, temp);
#if PYTHON3
Marshal.WriteIntPtr(type, TypeOffset.qualname, temp);
#endif
long ptr = type.ToInt64(); // 64-bit safe
temp = new IntPtr(ptr + TypeOffset.nb_add);
Marshal.WriteIntPtr(type, TypeOffset.tp_as_number, temp);
temp = new IntPtr(ptr + TypeOffset.sq_length);
Marshal.WriteIntPtr(type, TypeOffset.tp_as_sequence, temp);
temp = new IntPtr(ptr + TypeOffset.mp_length);
Marshal.WriteIntPtr(type, TypeOffset.tp_as_mapping, temp);
#if PYTHON3
temp = new IntPtr(ptr + TypeOffset.bf_getbuffer);
Marshal.WriteIntPtr(type, TypeOffset.tp_as_buffer, temp);
#elif PYTHON2
temp = new IntPtr(ptr + TypeOffset.bf_getreadbuffer);
Marshal.WriteIntPtr(type, TypeOffset.tp_as_buffer, temp);
#endif
return type;
}