python: fix CV_WRAP_AS handling
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Tue, 30 Mar 2021 20:54:11 +0000 (20:54 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Tue, 30 Mar 2021 22:02:48 +0000 (22:02 +0000)
modules/python/src2/cv2.cpp
modules/python/src2/gen2.py
modules/python/src2/hdr_parser.py
modules/python/src2/pycompat.hpp

index 8bb15cd43f5149c71f1ae57038b4e1d5b9171aa5..f96bcc4458be90effafb39f80a4a2743ee1d8af7 100644 (file)
@@ -2065,9 +2065,9 @@ static int convert_to_char(PyObject *o, char *dst, const ArgInfo& info)
 #include "pyopencv_custom_headers.h"
 
 #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
-#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
 #include "pyopencv_generated_types.h"
 #undef CVPY_TYPE
@@ -2150,10 +2150,10 @@ static bool init_body(PyObject * m)
 #undef CVPY_MODULE
 
 #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;
 #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;
 #endif
     #include "pyopencv_generated_types.h"
index 4acca07ada304f334818c501514f000bb69cf4f8..0579b42a5f5facc58827bdac395e3f5361daba1c 100755 (executable)
@@ -265,7 +265,12 @@ class ClassInfo(object):
 
             for m in decl[2]:
                 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
                 elif m == "/Map":
                     self.ismap = True
@@ -344,7 +349,8 @@ class ClassInfo(object):
         if self.constructor is not None:
             constructor_name = self.constructor.get_wrapper_name()
 
-        return "CVPY_TYPE({}, {}, {}, {}, {});\n".format(
+        return "CVPY_TYPE({}, {}, {}, {}, {}, {});\n".format(
+            self.wname,
             self.name,
             self.cname if self.issimple else "Ptr<{}>".format(self.cname),
             self.sname if self.issimple else "Ptr",
@@ -912,7 +918,7 @@ class PythonWrapperGenerator(object):
         if classes:
             classname = normalize_class_name('.'.join(namespace+classes))
             bareclassname = classes[-1]
-        namespace = '.'.join(namespace)
+        namespace_str = '.'.join(namespace)
 
         isconstructor = name == bareclassname
         is_static = False
@@ -937,23 +943,36 @@ class PythonWrapperGenerator(object):
         if is_static:
             # Add it as a method to the class
             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)
 
             # Add it as global function
             g_name = "_".join(classes+[name])
-            func_map = self.namespaces.setdefault(namespace, Namespace()).funcs
-            func = func_map.setdefault(g_name, FuncInfo("", g_name, cname, isconstructor, namespace, False))
+            w_classes = []
+            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)
+            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:
             if classname and not isconstructor:
                 if not isphantom:
                     cname = barename
                 func_map = self.classes[classname].methods
             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)
 
         if classname and isconstructor:
index d8b04b43ce488d60e96dad566e3aac065c832e36..ac3f383dc85b678991e91420495974a9e2c6bbad 100755 (executable)
@@ -255,6 +255,8 @@ class CppHeaderParser(object):
             l = l.replace("CV_EXPORTS_W_SIMPLE", "")
             modlist.append("/Simple")
         npos = l.find("CV_EXPORTS_AS")
+        if npos < 0:
+            npos = l.find('CV_WRAP_AS')
         if npos >= 0:
             macro_arg, npos3 = self.get_macro_arg(l, npos)
             modlist.append("=" + macro_arg)
@@ -825,7 +827,11 @@ class CppHeaderParser(object):
                     continue
                 state = SCAN
                 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
                     depth_if_0 = 1
                 continue
index 054117d625cd1690a0171c67f9642355d261f222..2650554b3fc964958ab22203ddc114113e9b625b 100644 (file)
@@ -172,7 +172,7 @@ PyObject* pyopencv_from(const TYPE& src)
 #endif
 
 
-#define CVPY_TYPE_DECLARE(NAME, STORAGE, SNAME) \
+#define CVPY_TYPE_DECLARE(WNAME, NAME, STORAGE, SNAME) \
     struct pyopencv_##NAME##_t \
     { \
         PyObject_HEAD \
@@ -181,7 +181,7 @@ PyObject* pyopencv_from(const TYPE& src)
     static PyTypeObject pyopencv_##NAME##_TypeXXX = \
     { \
         CVPY_TYPE_HEAD \
-        MODULESTR"."#NAME, \
+        MODULESTR"."#WNAME, \
         sizeof(pyopencv_##NAME##_t), \
     }; \
     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) \
     { \
         char str[1000]; \
-        sprintf(str, "<"#NAME" %p>", self); \
+        sprintf(str, "<"#WNAME" %p>", self); \
         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_dealloc = pyopencv_##NAME##_dealloc; \
@@ -229,12 +229,12 @@ PyObject* pyopencv_from(const TYPE& src)
             ERROR_HANDLER; \
         } \
         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 \
     { \
         PyObject_HEAD \
@@ -264,7 +264,7 @@ PyObject* pyopencv_from(const TYPE& src)
     static PyObject* pyopencv_##NAME##_repr(PyObject* self) \
     { \
         char str[1000]; \
-        sprintf(str, "<"#NAME" %p>", self); \
+        sprintf(str, "<"#WNAME" %p>", self); \
         return PyString_FromString(str); \
     } \
     static PyType_Slot pyopencv_##NAME##_Slots[] =  \
@@ -280,14 +280,14 @@ PyObject* pyopencv_from(const TYPE& src)
     }; \
     static PyType_Spec pyopencv_##NAME##_Spec = \
     { \
-        MODULESTR"."#NAME, \
+        MODULESTR"."#WNAME, \
         sizeof(pyopencv_##NAME##_t), \
         0, \
         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \
         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[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); \
         if (!pyopencv_##NAME##_TypePtr) \
         { \
-            printf("Failed to init: " #NAME ", base (" #BASE ")" "\n"); \
+            printf("Failed to init: " #WNAME ", base (" #BASE ")" "\n"); \
             ERROR_HANDLER; \
         } \
         PyModule_AddObject(m, #NAME, (PyObject *)pyopencv_##NAME##_TypePtr); \