From 7926a5fa7be79ee93bd87a87092942a1ff902308 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 27 Oct 2013 18:51:20 +0000 Subject: [PATCH] backward compatibility with Python 2.7 --- .../interfaceMakerPythonNative.cxx | 72 +++++---- .../interrogate/interfaceMakerPythonNative.h | 1 + dtool/src/interrogatedb/py_panda.h | 139 +----------------- 3 files changed, 52 insertions(+), 160 deletions(-) diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 1efbfe6194..0a457f4058 100755 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/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 static_functions; - std::map normal_Operator_functions; - std::map wraped_Operator_functions; + std::map 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::iterator rfi; // wraped_Operator_functions; - for (rfi = wraped_Operator_functions.begin(); rfi != wraped_Operator_functions.end(); rfi++) { + std::map::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_" <::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::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::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 diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.h b/dtool/src/interrogate/interfaceMakerPythonNative.h index 77fcdc16f3..32ddd65af7 100755 --- a/dtool/src/interrogate/interfaceMakerPythonNative.h +++ b/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); diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index 6ca20c7586..1f8d35594d 100755 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -252,144 +252,13 @@ 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 */ \ - }; \ + 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) -#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 */ \ - }; \ - Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) -#endif - //////////////////////////////////////////////////////////////////////// // The Fast Deallocator.. for Our instances.. ////////////////////////////////////////////////////////////////////////