Merge pull request #19808 from alalek:3.4_python_fix_wrap_as

This commit is contained in:
Alexander Alekhin 2021-03-31 22:56:13 +00:00
commit 6773fa03e2
4 changed files with 48 additions and 23 deletions

View File

@ -2065,9 +2065,9 @@ static int convert_to_char(PyObject *o, char *dst, const ArgInfo& info)
#include "pyopencv_custom_headers.h" #include "pyopencv_custom_headers.h"
#ifdef CVPY_DYNAMIC_INIT #ifdef CVPY_DYNAMIC_INIT
#define CVPY_TYPE(NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE_DYNAMIC(NAME, STORAGE, SNAME) #define CVPY_TYPE(WNAME, NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE_DYNAMIC(WNAME, NAME, STORAGE, SNAME)
#else #else
#define CVPY_TYPE(NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE(NAME, STORAGE, SNAME) #define CVPY_TYPE(WNAME, NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE(WNAME, NAME, STORAGE, SNAME)
#endif #endif
#include "pyopencv_generated_types.h" #include "pyopencv_generated_types.h"
#undef CVPY_TYPE #undef CVPY_TYPE
@ -2150,10 +2150,10 @@ static bool init_body(PyObject * m)
#undef CVPY_MODULE #undef CVPY_MODULE
#ifdef CVPY_DYNAMIC_INIT #ifdef CVPY_DYNAMIC_INIT
#define CVPY_TYPE(NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_DYNAMIC(NAME, return false, BASE, CONSTRUCTOR) #define CVPY_TYPE(WNAME, NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_DYNAMIC(WNAME, NAME, return false, BASE, CONSTRUCTOR)
PyObject * pyopencv_NoBase_TypePtr = NULL; PyObject * pyopencv_NoBase_TypePtr = NULL;
#else #else
#define CVPY_TYPE(NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_STATIC(NAME, return false, BASE, CONSTRUCTOR) #define CVPY_TYPE(WNAME, NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_STATIC(WNAME, NAME, return false, BASE, CONSTRUCTOR)
PyTypeObject * pyopencv_NoBase_TypePtr = NULL; PyTypeObject * pyopencv_NoBase_TypePtr = NULL;
#endif #endif
#include "pyopencv_generated_types.h" #include "pyopencv_generated_types.h"

View File

@ -265,7 +265,12 @@ class ClassInfo(object):
for m in decl[2]: for m in decl[2]:
if m.startswith("="): if m.startswith("="):
self.wname = m[1:] wname = m[1:]
npos = name.rfind('.')
if npos >= 0:
self.wname = normalize_class_name(name[:npos] + '.' + wname)
else:
self.wname = wname
customname = True customname = True
elif m == "/Map": elif m == "/Map":
self.ismap = True self.ismap = True
@ -344,7 +349,8 @@ class ClassInfo(object):
if self.constructor is not None: if self.constructor is not None:
constructor_name = self.constructor.get_wrapper_name() constructor_name = self.constructor.get_wrapper_name()
return "CVPY_TYPE({}, {}, {}, {}, {});\n".format( return "CVPY_TYPE({}, {}, {}, {}, {}, {});\n".format(
self.wname,
self.name, self.name,
self.cname if self.issimple else "Ptr<{}>".format(self.cname), self.cname if self.issimple else "Ptr<{}>".format(self.cname),
self.sname if self.issimple else "Ptr", self.sname if self.issimple else "Ptr",
@ -912,7 +918,7 @@ class PythonWrapperGenerator(object):
if classes: if classes:
classname = normalize_class_name('.'.join(namespace+classes)) classname = normalize_class_name('.'.join(namespace+classes))
bareclassname = classes[-1] bareclassname = classes[-1]
namespace = '.'.join(namespace) namespace_str = '.'.join(namespace)
isconstructor = name == bareclassname isconstructor = name == bareclassname
is_static = False is_static = False
@ -937,23 +943,36 @@ class PythonWrapperGenerator(object):
if is_static: if is_static:
# Add it as a method to the class # Add it as a method to the class
func_map = self.classes[classname].methods func_map = self.classes[classname].methods
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace, is_static)) func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace_str, is_static))
func.add_variant(decl, isphantom) func.add_variant(decl, isphantom)
# Add it as global function # Add it as global function
g_name = "_".join(classes+[name]) g_name = "_".join(classes+[name])
func_map = self.namespaces.setdefault(namespace, Namespace()).funcs w_classes = []
func = func_map.setdefault(g_name, FuncInfo("", g_name, cname, isconstructor, namespace, False)) for i in range(0, len(classes)):
classes_i = classes[:i+1]
classname_i = normalize_class_name('.'.join(namespace+classes_i))
w_classname = self.classes[classname_i].wname
namespace_prefix = normalize_class_name('.'.join(namespace)) + '_'
if w_classname.startswith(namespace_prefix):
w_classname = w_classname[len(namespace_prefix):]
w_classes.append(w_classname)
g_wname = "_".join(w_classes+[name])
func_map = self.namespaces.setdefault(namespace_str, Namespace()).funcs
func = func_map.setdefault(g_name, FuncInfo("", g_name, cname, isconstructor, namespace_str, False))
func.add_variant(decl, isphantom) func.add_variant(decl, isphantom)
if g_wname != g_name: # TODO OpenCV 5.0
wfunc = func_map.setdefault(g_wname, FuncInfo("", g_wname, cname, isconstructor, namespace_str, False))
wfunc.add_variant(decl, isphantom)
else: else:
if classname and not isconstructor: if classname and not isconstructor:
if not isphantom: if not isphantom:
cname = barename cname = barename
func_map = self.classes[classname].methods func_map = self.classes[classname].methods
else: else:
func_map = self.namespaces.setdefault(namespace, Namespace()).funcs func_map = self.namespaces.setdefault(namespace_str, Namespace()).funcs
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace, is_static)) func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace_str, is_static))
func.add_variant(decl, isphantom) func.add_variant(decl, isphantom)
if classname and isconstructor: if classname and isconstructor:

View File

@ -255,6 +255,8 @@ class CppHeaderParser(object):
l = l.replace("CV_EXPORTS_W_SIMPLE", "") l = l.replace("CV_EXPORTS_W_SIMPLE", "")
modlist.append("/Simple") modlist.append("/Simple")
npos = l.find("CV_EXPORTS_AS") npos = l.find("CV_EXPORTS_AS")
if npos < 0:
npos = l.find('CV_WRAP_AS')
if npos >= 0: if npos >= 0:
macro_arg, npos3 = self.get_macro_arg(l, npos) macro_arg, npos3 = self.get_macro_arg(l, npos)
modlist.append("=" + macro_arg) modlist.append("=" + macro_arg)
@ -825,7 +827,11 @@ class CppHeaderParser(object):
continue continue
state = SCAN state = SCAN
l = re.sub(r'//(.+)?', '', l).strip() # drop // comment l = re.sub(r'//(.+)?', '', l).strip() # drop // comment
if l == '#if 0' or l == '#if defined(__OPENCV_BUILD)' or l == '#ifdef __OPENCV_BUILD': if l in [
'#if 0',
'#if defined(__OPENCV_BUILD)', '#ifdef __OPENCV_BUILD',
'#if !defined(OPENCV_BINDING_PARSER)', '#ifndef OPENCV_BINDING_PARSER',
]:
state = DIRECTIVE_IF_0 state = DIRECTIVE_IF_0
depth_if_0 = 1 depth_if_0 = 1
continue continue

View File

@ -172,7 +172,7 @@ PyObject* pyopencv_from(const TYPE& src)
#endif #endif
#define CVPY_TYPE_DECLARE(NAME, STORAGE, SNAME) \ #define CVPY_TYPE_DECLARE(WNAME, NAME, STORAGE, SNAME) \
struct pyopencv_##NAME##_t \ struct pyopencv_##NAME##_t \
{ \ { \
PyObject_HEAD \ PyObject_HEAD \
@ -181,7 +181,7 @@ PyObject* pyopencv_from(const TYPE& src)
static PyTypeObject pyopencv_##NAME##_TypeXXX = \ static PyTypeObject pyopencv_##NAME##_TypeXXX = \
{ \ { \
CVPY_TYPE_HEAD \ CVPY_TYPE_HEAD \
MODULESTR"."#NAME, \ MODULESTR"."#WNAME, \
sizeof(pyopencv_##NAME##_t), \ sizeof(pyopencv_##NAME##_t), \
}; \ }; \
static PyTypeObject * pyopencv_##NAME##_TypePtr = &pyopencv_##NAME##_TypeXXX; \ static PyTypeObject * pyopencv_##NAME##_TypePtr = &pyopencv_##NAME##_TypeXXX; \
@ -208,12 +208,12 @@ PyObject* pyopencv_from(const TYPE& src)
static PyObject* pyopencv_##NAME##_repr(PyObject* self) \ static PyObject* pyopencv_##NAME##_repr(PyObject* self) \
{ \ { \
char str[1000]; \ char str[1000]; \
sprintf(str, "<"#NAME" %p>", self); \ sprintf(str, "<"#WNAME" %p>", self); \
return PyString_FromString(str); \ return PyString_FromString(str); \
} }
#define CVPY_TYPE_INIT_STATIC(NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \ #define CVPY_TYPE_INIT_STATIC(WNAME, NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
{ \ { \
pyopencv_##NAME##_TypePtr->tp_base = pyopencv_##BASE##_TypePtr; \ pyopencv_##NAME##_TypePtr->tp_base = pyopencv_##BASE##_TypePtr; \
pyopencv_##NAME##_TypePtr->tp_dealloc = pyopencv_##NAME##_dealloc; \ pyopencv_##NAME##_TypePtr->tp_dealloc = pyopencv_##NAME##_dealloc; \
@ -229,12 +229,12 @@ PyObject* pyopencv_from(const TYPE& src)
ERROR_HANDLER; \ ERROR_HANDLER; \
} \ } \
CVPY_TYPE_INCREF(pyopencv_##NAME##_TypePtr); \ CVPY_TYPE_INCREF(pyopencv_##NAME##_TypePtr); \
PyModule_AddObject(m, #NAME, (PyObject *)pyopencv_##NAME##_TypePtr); \ PyModule_AddObject(m, #WNAME, (PyObject *)pyopencv_##NAME##_TypePtr); \
} }
//================================================================================================== //==================================================================================================
#define CVPY_TYPE_DECLARE_DYNAMIC(NAME, STORAGE, SNAME) \ #define CVPY_TYPE_DECLARE_DYNAMIC(WNAME, NAME, STORAGE, SNAME) \
struct pyopencv_##NAME##_t \ struct pyopencv_##NAME##_t \
{ \ { \
PyObject_HEAD \ PyObject_HEAD \
@ -264,7 +264,7 @@ PyObject* pyopencv_from(const TYPE& src)
static PyObject* pyopencv_##NAME##_repr(PyObject* self) \ static PyObject* pyopencv_##NAME##_repr(PyObject* self) \
{ \ { \
char str[1000]; \ char str[1000]; \
sprintf(str, "<"#NAME" %p>", self); \ sprintf(str, "<"#WNAME" %p>", self); \
return PyString_FromString(str); \ return PyString_FromString(str); \
} \ } \
static PyType_Slot pyopencv_##NAME##_Slots[] = \ static PyType_Slot pyopencv_##NAME##_Slots[] = \
@ -280,14 +280,14 @@ PyObject* pyopencv_from(const TYPE& src)
}; \ }; \
static PyType_Spec pyopencv_##NAME##_Spec = \ static PyType_Spec pyopencv_##NAME##_Spec = \
{ \ { \
MODULESTR"."#NAME, \ MODULESTR"."#WNAME, \
sizeof(pyopencv_##NAME##_t), \ sizeof(pyopencv_##NAME##_t), \
0, \ 0, \
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \
pyopencv_##NAME##_Slots \ pyopencv_##NAME##_Slots \
}; };
#define CVPY_TYPE_INIT_DYNAMIC(NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \ #define CVPY_TYPE_INIT_DYNAMIC(WNAME, NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
{ \ { \
pyopencv_##NAME##_Slots[0].pfunc /*tp_dealloc*/ = (void*)pyopencv_##NAME##_dealloc; \ pyopencv_##NAME##_Slots[0].pfunc /*tp_dealloc*/ = (void*)pyopencv_##NAME##_dealloc; \
pyopencv_##NAME##_Slots[1].pfunc /*tp_repr*/ = (void*)pyopencv_##NAME##_repr; \ pyopencv_##NAME##_Slots[1].pfunc /*tp_repr*/ = (void*)pyopencv_##NAME##_repr; \
@ -302,7 +302,7 @@ PyObject* pyopencv_from(const TYPE& src)
pyopencv_##NAME##_TypePtr = PyType_FromSpecWithBases(&pyopencv_##NAME##_Spec, bases); \ pyopencv_##NAME##_TypePtr = PyType_FromSpecWithBases(&pyopencv_##NAME##_Spec, bases); \
if (!pyopencv_##NAME##_TypePtr) \ if (!pyopencv_##NAME##_TypePtr) \
{ \ { \
printf("Failed to init: " #NAME ", base (" #BASE ")" "\n"); \ printf("Failed to init: " #WNAME ", base (" #BASE ")" "\n"); \
ERROR_HANDLER; \ ERROR_HANDLER; \
} \ } \
PyModule_AddObject(m, #NAME, (PyObject *)pyopencv_##NAME##_TypePtr); \ PyModule_AddObject(m, #NAME, (PyObject *)pyopencv_##NAME##_TypePtr); \