diff --git a/modules/python/config/dnn_tracker.json b/modules/python/config/dnn_tracker.json index 871b47c723..294b0d30ac 100644 --- a/modules/python/config/dnn_tracker.json +++ b/modules/python/config/dnn_tracker.json @@ -1 +1,7 @@ -{"ignored_headers": [], "ignored_classes": [], "user_defined_headers": [], "classes": {}, "enums": {}} \ No newline at end of file +{ + "ignored_headers": [], + "ignored_classes": [], + "user_defined_headers": [], + "classes": {}, + "enums": {} +} diff --git a/modules/python/config/gui.json b/modules/python/config/gui.json index 9e26dfeeb6..294b0d30ac 100644 --- a/modules/python/config/gui.json +++ b/modules/python/config/gui.json @@ -1 +1,7 @@ -{} \ No newline at end of file +{ + "ignored_headers": [], + "ignored_classes": [], + "user_defined_headers": [], + "classes": {}, + "enums": {} +} diff --git a/modules/python/config/imgproc.json b/modules/python/config/imgproc.json index 0e0dcd235c..294b0d30ac 100644 --- a/modules/python/config/imgproc.json +++ b/modules/python/config/imgproc.json @@ -1,3 +1,7 @@ { - -} \ No newline at end of file + "ignored_headers": [], + "ignored_classes": [], + "user_defined_headers": [], + "classes": {}, + "enums": {} +} diff --git a/modules/python/config/tt.json b/modules/python/config/tt.json index 871b47c723..294b0d30ac 100644 --- a/modules/python/config/tt.json +++ b/modules/python/config/tt.json @@ -1 +1,7 @@ -{"ignored_headers": [], "ignored_classes": [], "user_defined_headers": [], "classes": {}, "enums": {}} \ No newline at end of file +{ + "ignored_headers": [], + "ignored_classes": [], + "user_defined_headers": [], + "classes": {}, + "enums": {} +} diff --git a/modules/python/config/tt_mi.json b/modules/python/config/tt_mi.json index 871b47c723..689f81f91f 100644 --- a/modules/python/config/tt_mi.json +++ b/modules/python/config/tt_mi.json @@ -1 +1,11 @@ -{"ignored_headers": [], "ignored_classes": [], "user_defined_headers": [], "classes": {}, "enums": {}} \ No newline at end of file +{ + "ignored_headers": [], + "ignored_classes": [], + "user_defined_headers": [], + "classes": { + "vpTemplateTrackerMI": { + "is_virtual": true + } + }, + "enums": {} +} diff --git a/modules/python/docs/todos.rst b/modules/python/docs/todos.rst index 3e618a1d3e..7f29f8a017 100644 --- a/modules/python/docs/todos.rst +++ b/modules/python/docs/todos.rst @@ -54,6 +54,18 @@ To be written: * In code documentation for the generator * Document config files +* Failure cases + + * If you have this error: + error: invalid new-expression of abstract class type ‘vpTemplateTrackerMI’ + return new Class{std::forward(args)...}; + In file included from /home/sfelton/software/visp_build/modules/python/bindings/src/tt_mi.cpp:13:0: + /home/sfelton/software/visp-sfelton/modules/tracker/tt_mi/include/visp3/tt_mi/vpTemplateTrackerMI.h:46:19: note: because the following virtual functions are pure within ‘vpTemplateTrackerMI’: + class VISP_EXPORT vpTemplateTrackerMI : public vpTemplateTracker + You should define the class (here vpTemplaterMI) as pure virtual in the config file (via the flag is_virtual) + This error occurs because some methods are defined as pure virtual in a parent class and are not defined in the class this class: Pure virtual class detection does not look in the class hierarchy but only at the present class + + Packaging ------------------ diff --git a/modules/python/generator/visp_python_bindgen/methods.py b/modules/python/generator/visp_python_bindgen/methods.py index 68937c4d56..0599c049b3 100644 --- a/modules/python/generator/visp_python_bindgen/methods.py +++ b/modules/python/generator/visp_python_bindgen/methods.py @@ -256,12 +256,16 @@ def define_method(method: types.Method, method_config: Dict, is_class_method, sp else: self_param_with_name = None method_caller = bound_object.cpp_name + '::' if is_class_method else bound_object.cpp_name + output_param_symbols = [] if return_type is None or return_type == 'void': maybe_get_return = '' - maybe_return_in_tuple = '' + output_param_symbols.append('') else: maybe_get_return = f'{return_type} res = ' - maybe_return_in_tuple = 'res, ' + if '&' in return_type: + output_param_symbols.append('&res') + else: + output_param_symbols.append('res') if len(output_param_names) == 0 and (return_type is None or return_type == 'void'): return_str = '' @@ -270,7 +274,11 @@ def define_method(method: types.Method, method_config: Dict, is_class_method, sp elif len(output_param_names) == 1 and (return_type is None or return_type == 'void'): return_str = output_param_names[0] else: - return_str = f'std::make_tuple({maybe_return_in_tuple}{", ".join(output_param_names)})' + # When returning a tuple we need to explicitely convert references to pointer. + # This is required since std::tuple will upcast the ref to its base class and try to store a copy of the object + # If a class is pure virtual, this is not possible and will a compilation error! + output_param_symbols.extend(['&' + name for name in output_param_names if '&' in name]) + return_str = f'std::make_tuple({", ".join(output_param_symbols)})' lambda_body = f''' {param_declarations}