Browse Source

backward compatibility with Python 2.7

rdb 12 years ago
parent
commit
7926a5fa7b

+ 47 - 25
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -329,6 +329,7 @@ bool InterfaceMakerPythonNative::
 get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def) {
   def._answer_location = string();
   def._wrapper_type = WT_none;
+  def._min_version = 0;
 
   string method_name = func->_ifunc.get_name();
   bool is_unary_op = func->_ifunc.is_unary_op();
@@ -408,54 +409,63 @@ get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def) {
   if (method_name == "operator +=") {
     def._answer_location = "tp_as_number->nb_inplace_add";
     def._wrapper_type = WT_one_param;
+    def._min_version = 0x02000000;
     return true;
   }
 
   if (method_name == "operator -=") {
     def._answer_location = "tp_as_number->nb_inplace_subtract";
     def._wrapper_type = WT_one_param;
+    def._min_version = 0x02000000;
     return true;
   }
 
   if (method_name == "operator *=") {
     def._answer_location = "tp_as_number->nb_inplace_multiply";
     def._wrapper_type = WT_one_param;
+    def._min_version = 0x02000000;
     return true;
   }
 
   if (method_name == "operator /=") {
     def._answer_location = "tp_as_number->nb_inplace_divide";
     def._wrapper_type = WT_one_param;
+    def._min_version = 0x02000000;
     return true;
   }
 
   if (method_name == "operator %=") {
     def._answer_location = ".tp_as_number->nb_inplace_remainder";
     def._wrapper_type = WT_one_param;
+    def._min_version = 0x02000000;
     return true;
   }
 
   if (method_name == "operator <<=") {
     def._answer_location = "tp_as_number->nb_inplace_lshift";
     def._wrapper_type = WT_one_param;
+    def._min_version = 0x02000000;
     return true;
   }
 
   if (method_name == "operator >>=") {
     def._answer_location = "tp_as_number->nb_inplace_rshift";
     def._wrapper_type = WT_one_param;
+    def._min_version = 0x02000000;
     return true;
   }
 
   if (method_name == "operator &=") {
     def._answer_location = "tp_as_number->nb_inplace_and";
     def._wrapper_type = WT_one_param;
+    def._min_version = 0x02000000;
     return true;
   }
 
   if (method_name == "operator ^=") {
     def._answer_location = "tp_as_number->nb_inplace_xor";
     def._wrapper_type = WT_one_param;
+    def._min_version = 0x02000000;
     return true;
   }
 
@@ -539,12 +549,14 @@ get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def) {
   if (method_name == "__getbuffer__") {
     def._answer_location = "tp_as_buffer->bf_getbuffer";
     def._wrapper_type = WT_getbuffer;
+    def._min_version = 0x02060000;
     return true;
   }
 
   if (method_name == "__releasebuffer__") {
     def._answer_location = "tp_as_buffer->bf_releasebuffer";
     def._wrapper_type = WT_releasebuffer;
+    def._min_version = 0x02060000;
     return true;
   }
 
@@ -1211,8 +1223,7 @@ write_module_class(ostream &out, Object *obj) {
   out << "PyMethodDef Dtool_Methods_" << ClassName << "[] = {\n";
 
   std::map<int, Function *> static_functions;
-  std::map<Function *, std::string>        normal_Operator_functions;
-  std::map<Function *, SlottedFunctionDef> wraped_Operator_functions;
+  std::map<Function *, SlottedFunctionDef> slotted_functions;
   // function Table
   bool got_copy = false;
   bool got_deepcopy = false;
@@ -1244,13 +1255,8 @@ write_module_class(ostream &out, Object *obj) {
     }
 
     SlottedFunctionDef slotted_def;
-    if (!get_slotted_function_def(obj, func, slotted_def)) {
-        
-    } else if (slotted_def._wrapper_type != WT_none) {
-      wraped_Operator_functions[func] = slotted_def;
-      
-    } else {
-      normal_Operator_functions[func] = slotted_def._answer_location;
+    if (get_slotted_function_def(obj, func, slotted_def)) {
+      slotted_functions[func] = slotted_def;
     }
   }
 
@@ -1321,8 +1327,8 @@ write_module_class(ostream &out, Object *obj) {
   }
 
   {
-    std::map<Function *, SlottedFunctionDef>::iterator rfi; //          wraped_Operator_functions;
-    for (rfi = wraped_Operator_functions.begin(); rfi != wraped_Operator_functions.end(); rfi++) {
+    std::map<Function *, SlottedFunctionDef>::iterator rfi; //          slotted_functions;
+    for (rfi = slotted_functions.begin(); rfi != slotted_functions.end(); rfi++) {
       switch (rfi->second._wrapper_type) {
       case WT_no_params:
         // PyObject *func(PyObject *self)
@@ -1878,7 +1884,9 @@ write_module_class(ostream &out, Object *obj) {
     out << "    Dtool_" << ClassName << ".As_PyTypeObject().tp_flags |= Py_TPFLAGS_HAVE_ITER;\n";
   }
   if (has_local_getbuffer) {
+    out << "#if PY_VERSION_HEX >= 0x02060000\n";
     out << "    Dtool_" << ClassName << ".As_PyTypeObject().tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;\n";
+    out << "#endif";
   }
 
   // add bases///
@@ -1899,23 +1907,37 @@ write_module_class(ostream &out, Object *obj) {
   out << "    Dtool_" << ClassName << ".As_PyTypeObject().tp_dict = PyDict_New();\n";
   out << "    PyDict_SetItemString(Dtool_" <<ClassName << ".As_PyTypeObject().tp_dict, \"DtoolClassDict\", Dtool_" <<ClassName << ".As_PyTypeObject().tp_dict);\n";
 
-  // the standard call functions
-  std::map<Function *, std::string >::iterator ofi;
-  for (ofi = normal_Operator_functions.begin(); ofi != normal_Operator_functions.end(); ofi++) {
-    Function *func = ofi->first;
-    out << "    // " << ofi->second << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
-    out << "    Dtool_" << ClassName << ".As_PyTypeObject()." << ofi->second << " = &" << func->_name << ";\n";
-  }
+  // Now assign the slotted function definitions.
+  std::map<Function *, SlottedFunctionDef>::const_iterator rfi;
+  int prev_min_version = 0;
 
+  for (rfi = slotted_functions.begin(); rfi != slotted_functions.end(); rfi++) {
+    Function *func = rfi->first;
+    const SlottedFunctionDef &def = rfi->second;
 
-  // wrapped functions...
-  {
-    std::map<Function *, SlottedFunctionDef>::iterator rfi; //          wraped_Operator_functions;
-    for (rfi = wraped_Operator_functions.begin(); rfi != wraped_Operator_functions.end(); rfi++) {
-      Function *func = rfi->first;
-      out << "    // " << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
-      out << "    Dtool_" << ClassName << ".As_PyTypeObject()." << rfi->second._answer_location << " = &" << func->_name << methodNameFromCppName(func, export_class_name, false) << ";\n";
+    // Add an #ifdef if there is a specific version requirement on this function.
+    if (def._min_version != prev_min_version) {
+      if (prev_min_version > 0) {
+        out << "#endif\n";
+      }
+      prev_min_version = def._min_version;
+      if (def._min_version > 0) {
+        out << "#if PY_VERSION_HEX >= 0x" << hex << def._min_version << dec << "\n";
+      }
     }
+
+    out << "    // " << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
+
+    if (def._wrapper_type == WT_none) {
+      // Bound directly, without wrapper.
+      out << "    Dtool_" << ClassName << ".As_PyTypeObject()." << def._answer_location << " = &" << func->_name << ";\n";
+    } else {
+      // Assign to the wrapper method that was generated earlier.
+      out << "    Dtool_" << ClassName << ".As_PyTypeObject()." << def._answer_location << " = &" << func->_name << methodNameFromCppName(func, export_class_name, false) << ";\n";
+    }
+  }
+  if (prev_min_version > 0) {
+    out << "#endif\n";
   }
 
   // compare and hash work together in PY inherit behavior hmm grrr

+ 1 - 0
dtool/src/interrogate/interfaceMakerPythonNative.h

@@ -82,6 +82,7 @@ private:
   public:
     string _answer_location;
     WrapperType _wrapper_type;
+    int _min_version;
   };
 
   static bool get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def);

+ 4 - 135
dtool/src/interrogatedb/py_panda.h

@@ -252,143 +252,12 @@ struct Dtool_PyTypedObject {
       Dtool_InitNoCoerce_##CLASS_NAME                                   \
     };
 
-#if PY_MAJOR_VERSION >= 3
-#define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME)        \
-  static PyNumberMethods Dtool_PyNumberMethods_##CLASS_NAME =           \
-    {                                                                   \
-      0,/*binaryfunc nb_add*/                                           \
-      0,/*binaryfunc nb_subtract*/                                      \
-      0,/*binaryfunc nb_multiply*/                                      \
-      0,/*binaryfunc nb_remainder*/                                     \
-      0,/*binaryfunc nb_divmod*/                                        \
-      0,/*ternaryfunc nb_power*/                                        \
-      0,/*unaryfunc nb_negative*/                                       \
-      0,/*unaryfunc nb_positive*/                                       \
-      0,/*unaryfunc nb_absolute*/                                       \
-      0,/*inquiry nb_bool*/                                             \
-      0,/*unaryfunc nb_invert*/                                         \
-      0,/*binaryfunc nb_lshift*/                                        \
-      0,/*binaryfunc nb_rshift*/                                        \
-      0,/*binaryfunc nb_and*/                                           \
-      0,/*binaryfunc nb_xor*/                                           \
-      0,/*binaryfunc nb_or*/                                            \
-      0,/*unaryfunc nb_int*/                                            \
-      0,/*void *nb_reserved*/                                           \
-      0,/*unaryfunc nb_float*/                                          \
-      0,/*binaryfunc nb_inplace_add*/                                   \
-      0,/*binaryfunc nb_inplace_subtract*/                              \
-      0,/*binaryfunc nb_inplace_multiply*/                              \
-      0,/*binaryfunc nb_inplace_remainder*/                             \
-      0,/*ternaryfunc nb_inplace_power*/                                \
-      0,/*binaryfunc nb_inplace_lshift*/                                \
-      0,/*binaryfunc nb_inplace_rshift*/                                \
-      0,/*binaryfunc nb_inplace_and*/                                   \
-      0,/*binaryfunc nb_inplace_xor*/                                   \
-      0,/*binaryfunc nb_inplace_or*/                                    \
-      0,/*binaryfunc nb_floor_divide*/                                  \
-      0,/*binaryfunc nb_true_divide*/                                   \
-      0,/*binaryfunc nb_inplace_floor_divide*/                          \
-      0,/*binaryfunc nb_inplace_true_divide*/                           \
-      0,/*unaryfunc nb_index*/                                          \
-    };                                                                  \
-  static PySequenceMethods Dtool_PySequenceMethods_##CLASS_NAME =       \
-    {                                                                   \
-      0,/*lenfunc sq_length */                                          \
-      0,/*binaryfunc sq_concat */                                       \
-      0,/*ssizeargfunc sq_repeat */                                     \
-      0,/*ssizeargfunc sq_item */                                       \
-      0,/*void *was_sq_slice */                                         \
-      0,/*ssizeargfunc sq_ass_item */                                   \
-      0,/*void *was_sq_ass_slice */                                     \
-      0,/*objobjproc sq_contains */                                     \
-      0,/*binaryfunc sq_inplace_concat */                               \
-      0,/*ssizeargfunc sq_inplace_repeat */                             \
-    };                                                                  \
-  static PyMappingMethods Dtool_PyMappingMethods_##CLASS_NAME =         \
-    {                                                                   \
-      0,/*inquiry mp_length */                                          \
-      0,/*binaryfunc mp_subscript */                                    \
-      0,/*objobjargproc mp_ass_subscript */                             \
-    };                                                                  \
-  static PyMappingMethods Dtool_PyBufferProcs_##CLASS_NAME =            \
-    {                                                                   \
-      0,/*getbufferproc bf_getbuffer */                                 \
-      0,/*releasebufferproc bf_releasebuffer */                         \
-    };                                                                  \
-  Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME)
-
-#else // Python 2:
-
 #define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME)        \
-  static PyNumberMethods Dtool_PyNumberMethods_##CLASS_NAME =           \
-    {                                                                   \
-      0,/*binaryfunc nb_add*/                                           \
-      0,/*binaryfunc nb_subtract*/                                      \
-      0,/*binaryfunc nb_multiply*/                                      \
-      0,/*binaryfunc nb_divide*/                                        \
-      0,/*binaryfunc nb_remainder*/                                     \
-      0,/*binaryfunc nb_divmod*/                                        \
-      0,/*ternaryfunc nb_power*/                                        \
-      0,/*unaryfunc nb_negative*/                                       \
-      0,/*unaryfunc nb_positive*/                                       \
-      0,/*unaryfunc nb_absolute*/                                       \
-      0,/*inquiry nb_nonzero*/                                          \
-      0,/*unaryfunc nb_invert*/                                         \
-      0,/*binaryfunc nb_lshift*/                                        \
-      0,/*binaryfunc nb_rshift*/                                        \
-      0,/*binaryfunc nb_and*/                                           \
-      0,/*binaryfunc nb_xor*/                                           \
-      0,/*binaryfunc nb_or*/                                            \
-      0,/*coercion nb_coerce*/                                          \
-      0,/*unaryfunc nb_int*/                                            \
-      0,/*unaryfunc nb_long*/                                           \
-      0,/*unaryfunc nb_float*/                                          \
-      0,/*unaryfunc nb_oct*/                                            \
-      0,/*unaryfunc nb_hex*/                                            \
-      0,/*binaryfunc nb_inplace_add*/                                   \
-      0,/*binaryfunc nb_inplace_subtract*/                              \
-      0,/*binaryfunc nb_inplace_multiply*/                              \
-      0,/*binaryfunc nb_inplace_divide*/                                \
-      0,/*binaryfunc nb_inplace_remainder*/                             \
-      0,/*ternaryfunc nb_inplace_power*/                                \
-      0,/*binaryfunc nb_inplace_lshift*/                                \
-      0,/*binaryfunc nb_inplace_rshift*/                                \
-      0,/*binaryfunc nb_inplace_and*/                                   \
-      0,/*binaryfunc nb_inplace_xor*/                                   \
-      0,/*binaryfunc nb_inplace_or*/                                    \
-      0,/*binaryfunc nb_floor_divide*/                                  \
-      0,/*binaryfunc nb_true_divide*/                                   \
-      0,/*binaryfunc nb_inplace_floor_divide*/                          \
-      0,/*binaryfunc nb_inplace_true_divide*/                           \
-    };                                                                  \
-  static PySequenceMethods Dtool_PySequenceMethods_##CLASS_NAME =       \
-    {                                                                   \
-      0,/*lenfunc sq_length */                                          \
-      0,/*binaryfunc sq_concat */                                       \
-      0,/*ssizeargfunc sq_repeat */                                     \
-      0,/*ssizeargfunc sq_item */                                       \
-      0,/*ssizeargfunc sq_ass_item */                                   \
-      0,/*objobjproc sq_contains */                                     \
-      0,/*binaryfunc sq_inplace_concat */                               \
-      0,/*ssizeargfunc sq_inplace_repeat */                             \
-    };                                                                  \
-  static PyMappingMethods Dtool_PyMappingMethods_##CLASS_NAME =         \
-    {                                                                   \
-      0,/*inquiry mp_length */                                          \
-      0,/*binaryfunc mp_subscript */                                    \
-      0,/*objobjargproc mp_ass_subscript */                             \
-    };                                                                  \
-  static PyBufferProcs Dtool_PyBufferProcs_##CLASS_NAME =               \
-    {                                                                   \
-      0,/*readbufferproc bf_getreadbuffer */                            \
-      0,/*writebufferproc bf_getwritebuffer */                          \
-      0,/*segcountproc bf_getsegcount */                                \
-      0,/*charbufferproc bf_getcharbuffer */                            \
-      0,/*getbufferproc bf_getbuffer */                                 \
-      0,/*releasebufferproc bf_releasebuffer */                         \
-    };                                                                  \
+  static PyNumberMethods Dtool_PyNumberMethods_##CLASS_NAME = {0};      \
+  static PySequenceMethods Dtool_PySequenceMethods_##CLASS_NAME = {0};  \
+  static PyMappingMethods Dtool_PyMappingMethods_##CLASS_NAME = {0};    \
+  static PyBufferProcs Dtool_PyBufferProcs_##CLASS_NAME = {0};          \
   Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME)
-#endif
 
 ////////////////////////////////////////////////////////////////////////
 // The Fast Deallocator.. for Our instances..