Browse Source

Fix broken Python 3 support.

rdb 12 years ago
parent
commit
f29c4681e1

+ 29 - 13
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -1167,25 +1167,41 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
   out << "//********************************************************************\n";
 
   out << "#if PY_MAJOR_VERSION >= 3\n"
-      << "#define INIT_FUNC PyObject *PyInit_" << def->module_name << "\n"
-      << "#else\n"
-      << "#define INIT_FUNC void init" << def->module_name << "\n"
-      << "#endif\n\n"
-
+      << "static struct PyModuleDef python_native_module = {\n"
+      << "  PyModuleDef_HEAD_INIT,\n"
+      << "  \"" << def->module_name << "\",\n"
+      << "  NULL,\n"
+      << "  -1,\n"
+      << "  NULL,\n"
+      << "  NULL, NULL, NULL, NULL\n"
+      << "};\n"
+      << "\n"
       << "#ifdef _WIN32\n"
-      << "extern \"C\" __declspec(dllexport) INIT_FUNC();\n"
+      << "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << def->module_name << "();\n"
       << "#else\n"
-      << "extern \"C\" INIT_FUNC();\n"
-      << "#endif\n\n"
-
-      << "INIT_FUNC() {\n"
+      << "extern \"C\" PyObject *PyInit_" << def->module_name << "();\n"
+      << "#endif\n"
+      << "\n"
       << "PyObject *PyInit_" << def->module_name << "() {\n"
       << "  LibraryDef *refs[] = {&" << def->library_name << "_moddef, NULL};\n"
-      << "#if PY_MAJOR_VERSION >= 3\n"
-      << "  return\n"
+      << "  return Dtool_PyModuleInitHelper(refs, &python_native_module);\n"
+      << "}\n"
+      << "\n"
+      << "#else  // Python 2 case\n"
+      << "\n"
+      << "#ifdef _WIN32\n"
+      << "extern \"C\" __declspec(dllexport) void init" << def->module_name << "();\n"
+      << "#else\n"
+      << "extern \"C\" void init" << def->module_name << "();\n"
       << "#endif\n"
+      << "\n"
+      << "void init" << def->module_name << "() {\n"
+      << "  LibraryDef *refs[] = {&" << def->library_name << "_moddef, NULL};\n"
       << "  Dtool_PyModuleInitHelper(refs, \"" << def->module_name << "\");\n"
-      << "}\n\n";
+      << "}\n"
+      << "\n"
+      << "#endif\n"
+      << "\n";
 }
 /////////////////////////////////////////////////////////////////////////////////////////////
 // Function :write_module_class

+ 58 - 29
dtool/src/interrogate/interrogate_module.cxx

@@ -80,7 +80,7 @@ int write_python_table_native(ostream &out) {
 
   int count = 0;
 
-  pset<std::string > Libraries;
+  pset<std::string> libraries;
 
 //  out << "extern \"C\" {\n";
 
@@ -92,59 +92,88 @@ int write_python_table_native(ostream &out) {
 
     // Consider only those that belong in the module we asked for.
     if (interrogate_function_has_module_name(function_index) &&
-        module_name == interrogate_function_module_name(function_index)) {
-        // if it has a library name add it to set of libraries
-        if(interrogate_function_has_library_name(function_index))
-            Libraries.insert(interrogate_function_library_name(function_index));
+      module_name == interrogate_function_module_name(function_index)) {
+      // if it has a library name add it to set of libraries
+      if (interrogate_function_has_library_name(function_index)) {
+        libraries.insert(interrogate_function_library_name(function_index));
+      }
     }
   }
 
-  for(int ti = 0; ti < interrogate_number_of_types(); ti++) {
+  for (int ti = 0; ti < interrogate_number_of_types(); ti++) {
     TypeIndex thetype  = interrogate_get_type(ti);
-    if(interrogate_type_has_module_name(thetype) && module_name == interrogate_type_module_name(thetype)) {
-        if(interrogate_type_has_library_name(thetype))
-            Libraries.insert(interrogate_type_library_name(thetype));
+    if (interrogate_type_has_module_name(thetype) && module_name == interrogate_type_module_name(thetype)) {
+      if (interrogate_type_has_library_name(thetype)) {
+        libraries.insert(interrogate_type_library_name(thetype));
+      }
     }
   }
 
   pset<std::string >::iterator ii;
-  for(ii = Libraries.begin(); ii != Libraries.end(); ii++) {
-    printf("Referencing Library %s\n",(*ii).c_str());
-    out << "extern LibraryDef "<< *ii << "_moddef;\n";
+  for(ii = libraries.begin(); ii != libraries.end(); ii++) {
+    printf("Referencing Library %s\n", (*ii).c_str());
+    out << "extern LibraryDef " << *ii << "_moddef;\n";
   }
 
   out << "\n"
       << "#if PY_MAJOR_VERSION >= 3\n"
-      << "#define INIT_FUNC PyObject *PyInit_" << library_name << "\n"
+      << "static struct PyModuleDef py_" << library_name << "_module = {\n"
+      << "  PyModuleDef_HEAD_INIT,\n"
+      << "  \"" << library_name << "\",\n"
+      << "  NULL,\n"
+      << "  -1,\n"
+      << "  NULL,\n"
+      << "  NULL, NULL, NULL, NULL\n"
+      << "};\n"
+      << "\n"
+      << "#ifdef _WIN32\n"
+      << "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << library_name << "();\n"
       << "#else\n"
-      << "#define INIT_FUNC void init" << library_name << "\n"
-      << "#endif\n\n"
+      << "extern \"C\" PyObject *PyInit_" << library_name << "();\n"
+      << "#endif\n"
+      << "\n"
+      << "PyObject *PyInit_" << library_name << "() {\n";
 
+  if (track_interpreter) {
+    out << "  in_interpreter = 1;\n";
+  }
+
+  out << "  LibraryDef *defs[] = {";
+  for(ii = libraries.begin(); ii != libraries.end(); ii++) {
+    out << "&" << *ii << "_moddef, ";
+  }
+
+  out << "NULL};\n"
+      << "\n"
+      << "  return Dtool_PyModuleInitHelper(defs, &py_" << library_name << "_module);\n"
+      << "}\n"
+      << "\n"
+      << "#else  // Python 2 case\n"
+      << "\n"
       << "#ifdef _WIN32\n"
-      << "extern \"C\" __declspec(dllexport) INIT_FUNC();\n"
+      << "extern \"C\" __declspec(dllexport) void init" << library_name << "();\n"
       << "#else\n"
-      << "extern \"C\" INIT_FUNC();\n"
-      << "#endif\n\n"
-
-      << "INIT_FUNC() {\n";
+      << "extern \"C\" void init" << library_name << "();\n"
+      << "#endif\n"
+      << "\n"
+      << "void init" << library_name << "() {\n";
 
   if (track_interpreter) {
     out << "  in_interpreter = 1;\n";
   }
 
   out << "  LibraryDef *defs[] = {";
-  for(ii = Libraries.begin(); ii != Libraries.end(); ii++) {
-    out << "&"<< *ii << "_moddef, ";
+  for(ii = libraries.begin(); ii != libraries.end(); ii++) {
+    out << "&" << *ii << "_moddef, ";
   }
 
-  out << "NULL};\n\n";
+  out << "NULL};\n"
+      << "\n"
+      << "  Dtool_PyModuleInitHelper(defs, \"" << library_name << "\");\n"
+      << "}\n"
+      << "#endif\n"
+      << "\n";
 
-  out << "#if PY_MAJOR_VERSION >= 3\n";
-  out << "  return Dtool_PyModuleInitHelper(defs, \"" << library_name << "\");\n";
-  out << "#else\n";
-  out << "  Dtool_PyModuleInitHelper(defs, \"" << library_name << "\");\n";
-  out << "#endif\n";
-  out << "}\n";
 
   return count;
 }

+ 12 - 19
dtool/src/interrogatedb/py_panda.cxx

@@ -203,8 +203,7 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
         if (report_errors) {
           ostringstream str;
           str << function_name << "() argument " << param << " must be ";
-          
-          
+
           PyObject *fname = PyObject_GetAttrString((PyObject *)classdef, "__name__");
           if (fname != (PyObject *)NULL) {
 #if PY_MAJOR_VERSION >= 3
@@ -216,7 +215,7 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
           } else {
             str << classdef->_name;
           }
-          
+
           PyObject *tname = PyObject_GetAttrString((PyObject *)Py_TYPE(self), "__name__");
           if (tname != (PyObject *)NULL) {
 #if PY_MAJOR_VERSION >= 3
@@ -228,7 +227,7 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
           } else {
             str << ", not " << my_type->_name;
           }
-          
+
           string msg = str.str();
           PyErr_SetString(PyExc_TypeError, msg.c_str());
         }
@@ -445,11 +444,15 @@ Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) {
       return di->second;
     }
   }
-  return NULL;    
+  return NULL;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+#if PY_MAJOR_VERSION >= 3
+PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def) {
+#else
 PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
+#endif
   // the module level function inits....
   MethodDefmap functions;
   for (int xx = 0; defs[xx] != NULL; xx++) {
@@ -468,20 +471,11 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
   newdef[offset].ml_flags = 0;
 
 #if PY_MAJOR_VERSION >= 3
-  cerr << "About to create module " << modulename << "\n";
-  struct PyModuleDef moduledef = {
-    PyModuleDef_HEAD_INIT,
-    modulename,
-    NULL,
-    -1,
-    newdef,
-    NULL, NULL, NULL, NULL
-  };
-  PyObject *module = PyModule_Create(&moduledef);
-  cerr << "Module created!\n";
+  module_def->m_methods = newdef;
+  PyObject *module = PyModule_Create(module_def);
 #else
-  PyObject *module = Py_InitModule((char *)modulename, newdef); 
-#endif  
+  PyObject *module = Py_InitModule((char *)modulename, newdef);
+#endif
 
   if (module == NULL) {
 #if PY_MAJOR_VERSION >= 3
@@ -492,7 +486,6 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
     return NULL;
   }
 
-
   // the constant inits... enums, classes ...
   for (int y = 0; defs[y] != NULL; y++) {
     defs[y]->_constants(module);

+ 5 - 1
dtool/src/interrogatedb/py_panda.h

@@ -204,7 +204,7 @@ struct Dtool_PyTypedObject {
     {                                                                   \
       {                                                                 \
         PyVarObject_HEAD_INIT(NULL, 0)                                  \
-        "lib" #MODULE_NAME "." #PUBLIC_NAME, /*type name with module */ \
+        #MODULE_NAME "." #PUBLIC_NAME,       /*type name with module */ \
         sizeof(Dtool_PyInstDef),                /* tp_basicsize */      \
         0,                                      /* tp_itemsize */       \
         &Dtool_Deallocate_General,              /* tp_dealloc */        \
@@ -444,7 +444,11 @@ struct LibraryDef {
 };
 ///////////////////////////////////////////////////////////////////////////////
 
+#if PY_MAJOR_VERSION >= 3
+EXPCL_DTOOLCONFIG PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def);
+#else
 EXPCL_DTOOLCONFIG PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename);
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 ///  HACK.... Be carefull