backward compatibility with Python 2.7

This commit is contained in:
rdb 2013-10-27 18:51:20 +00:00
parent 6296ed0a4e
commit 7926a5fa7b
3 changed files with 52 additions and 160 deletions

View File

@ -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

View File

@ -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);

View File

@ -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..
////////////////////////////////////////////////////////////////////////