@@ -858,7 +858,7 @@ static PyType_Spec DynType_spec = {
858858 .name = " NativeClass" ,
859859 .basicsize = sizeof (DynObj),
860860 .itemsize = 0 ,
861- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
861+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_BASETYPE ,
862862 .slots = DynType_slots
863863};
864864
@@ -870,7 +870,7 @@ static PyType_Spec StaticPropMetaClass_spec = {
870870 .name = " builtins.PuerStaticPropMetaClass" ,
871871 .basicsize = sizeof (PyHeapTypeObject),
872872 .itemsize = 0 ,
873- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
873+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_BASETYPE ,
874874 .slots = StaticPropMetaClass_slots
875875};
876876
@@ -920,30 +920,47 @@ PyObject* CppObjectMapper::FindOrCreateClass(const puerts::ScriptClassDefinition
920920 char * typeName = (char *) PyMem_Malloc (strlen (ClassDefinition->ScriptName ) + 10 ); // "builtins." + name + '\0'
921921 sprintf (typeName, " builtins.%s" , ClassDefinition->ScriptName );
922922 spec.name = typeName;
923- spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_BASETYPE;
923+
924+ PyType_Spec Meta_Spec = StaticPropMetaClass_spec;
925+ char * meta_type_name = (char *) PyMem_Malloc (strlen (ClassDefinition->ScriptName ) + 25 ); // "builtins.PuerStaticPropMetaClass." + name + '\0'
926+ sprintf (meta_type_name, " builtins.PuerStaticPropMetaClass.%s" , ClassDefinition->ScriptName );
927+ Meta_Spec.name = meta_type_name;
928+
924929
925930 PyObject* type_obj = nullptr ;
926931 PyObject* meta_class_type_obj = nullptr ;
927932 if (ClassDefinition->SuperTypeId )
928933 {
929- PyType_Spec Meta_Spec = StaticPropMetaClass_spec;
930- char * meta_type_name = (char *) PyMem_Malloc (strlen (ClassDefinition->ScriptName ) + 25 ); // "builtins.PuerStaticPropMetaClass." + name + '\0'
931- sprintf (meta_type_name, " builtins.PuerStaticPropMetaClass.%s" , ClassDefinition->ScriptName );
932- Meta_Spec.name = meta_type_name;
933- PyObject* bases = PyTuple_Pack (1 , FindOrCreateClass (puerts::LoadClassByID (registry, ClassDefinition->SuperTypeId )));
934- PyObject* meta_bases = PyTuple_Pack (1 , (PyObject*)&PyType_Type);
934+ auto super_type_obj = FindOrCreateClass (puerts::LoadClassByID (registry, ClassDefinition->SuperTypeId ));
935+ PyObject* bases = PyTuple_Pack (1 , super_type_obj);
936+ auto super_meta = PyObject_GetAttrString (super_type_obj, " __puerts_metaclass__" );
937+ if (!super_meta)
938+ {
939+ printf (" Failed to get super metaclass for %s\n " , ClassDefinition->ScriptName );
940+ PyErr_SetString (PyExc_RuntimeError, " Failed to get super metaclass" );
941+ Py_DECREF (bases);
942+ return NULL ;
943+ }
944+ PyObject* meta_bases = PyTuple_Pack (1 , super_meta);
935945 meta_class_type_obj = PyType_FromSpecWithBases (&StaticPropMetaClass_spec, meta_bases);
936946 Py_DECREF (meta_bases);
937947 type_obj = PyType_FromMetaclass (reinterpret_cast <PyTypeObject *>(meta_class_type_obj), nullptr , &spec, bases);
938948 Py_DECREF (bases);
939949 }
940950 else
941951 {
942- type_obj = PyType_FromSpec (&spec);
952+ PyObject* meta_bases = PyTuple_Pack (1 , (PyObject*)&PyType_Type);
953+ meta_class_type_obj = PyType_FromSpecWithBases (&StaticPropMetaClass_spec, meta_bases);
954+ if (!meta_class_type_obj) {
955+ printf (" Failed to create metaclass type object for %s\n " , ClassDefinition->ScriptName );
956+ PyErr_SetString (PyExc_RuntimeError, " Failed to create metaclass type object" );
957+ }
958+ Py_DECREF (meta_bases);
959+ type_obj = PyType_FromMetaclass (reinterpret_cast <PyTypeObject *>(meta_class_type_obj), nullptr , &spec, nullptr );
943960 }
944- PyHeapTypeObject* type = (PyHeapTypeObject*)type_obj;
945961 if (!type_obj) return NULL ;
946-
962+ if (!meta_class_type_obj) return NULL ;
963+ PyObject_SetAttrString (type_obj, " __puerts_metaclass__" , meta_class_type_obj);
947964
948965 ContextObj* ctx = (ContextObj*)PyObject_New (ContextObj, &Context_Type);
949966 if (!ctx) {
0 commit comments