From 3d4b03f0dd5a0bbc698054887ce95d2ce129f1a3 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Thu, 3 Jul 2008 14:31:30 +0100 Subject: [PATCH] Fix problem with class registration when an inner namespace class has a class defined in an outer namespace as base class. --- pybindgen/gccxmlparser.py | 11 +++++------ tests/foo.h | 21 +++++++++++++++++++++ tests/foomodulegen.py | 8 ++++++++ tests/footest.py | 5 +++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/pybindgen/gccxmlparser.py b/pybindgen/gccxmlparser.py index 292d45c..f8a595b 100644 --- a/pybindgen/gccxmlparser.py +++ b/pybindgen/gccxmlparser.py @@ -729,6 +729,7 @@ pybindgen.settings.error_handler = ErrorHandler() def scan_types(self): self._stage = 'scan types' + self._registered_classes = {} # class_t -> CppClass self._scan_namespace_types(self.module, self.module_namespace, pygen_register_function_name="register_types") self._types_scanned = True @@ -912,8 +913,6 @@ pybindgen.settings.error_handler = ErrorHandler() module.add_enum(enum.name, [name for name, dummy_val in enum.values], outer_class=outer_class) - registered_classes = {} # class_t -> CppClass - ## Look for forward declarations of class/structs like ## "typedef struct _Foo Foo"; these are represented in ## pygccxml by a typedef whose .type.declaration is a @@ -965,7 +964,7 @@ pybindgen.settings.error_handler = ErrorHandler() class_wrapper = module.add_class(alias.name, **kwargs) class_wrapper.gccxml_definition = cls - registered_classes[cls] = class_wrapper + self._registered_classes[cls] = class_wrapper if cls.name != alias.name: class_wrapper.register_alias(normalize_name(cls.name)) self.type_registry.class_registered(class_wrapper) @@ -1045,11 +1044,11 @@ pybindgen.settings.error_handler = ErrorHandler() if cls.bases: base_cls = cls.bases[0].related_class try: - base_class_wrapper = registered_classes[base_cls] + base_class_wrapper = self._registered_classes[base_cls] except KeyError: ## base class not yet registered => postpone this class registration if base_cls not in unregistered_classes: - warnings.warn_explicit("Class %s ignored because it uses has a base class (%s) " + warnings.warn_explicit("Class %s ignored because it uses a base class (%s) " "which is not declared." % (cls.decl_string, base_cls.decl_string), ModuleParserWarning, cls.location.file_name, cls.location.line) @@ -1120,7 +1119,7 @@ pybindgen.settings.error_handler = ErrorHandler() class_wrapper = module.add_class(cls_name, **kwargs) class_wrapper.gccxml_definition = cls - registered_classes[cls] = class_wrapper + self._registered_classes[cls] = class_wrapper if alias: class_wrapper.register_alias(normalize_name(alias)) self.type_registry.class_registered(class_wrapper) diff --git a/tests/foo.h b/tests/foo.h index 1efab91..3a511f7 100644 --- a/tests/foo.h +++ b/tests/foo.h @@ -630,5 +630,26 @@ float matrix_sum_of_elements (float *matrix); // -#- @matrix(direction=out, array_length=6) -#- void matrix_identity_new (float *matrix); +namespace TopNs +{ + + class OuterBase + { + public: + }; + + namespace PrefixBottomNs { + class PrefixInner : public OuterBase + { + public: + PrefixInner () {} + void Do (void) {} + }; + } + +} + + + #endif /* !FOO_H_ */ diff --git a/tests/foomodulegen.py b/tests/foomodulegen.py index 66c44af..00c685a 100755 --- a/tests/foomodulegen.py +++ b/tests/foomodulegen.py @@ -337,6 +337,14 @@ int %s::custom_method_added_by_a_hook(int x) ReturnValue.new('void'), [Parameter.new("float*", 'matrix', direction=Parameter.DIRECTION_OUT, array_length=6)]) + top_ns = mod.add_cpp_namespace('TopNs') + outer_base = top_ns.add_class('OuterBase') + bottom_ns = top_ns.add_cpp_namespace('PrefixBottomNs') + inner = bottom_ns.add_class('PrefixInner',parent=outer_base) + inner.add_constructor([]) + inner.add_method('Do', 'void', []) + + #### --- error handler --- diff --git a/tests/footest.py b/tests/footest.py index b9ab3b2..a603818 100644 --- a/tests/footest.py +++ b/tests/footest.py @@ -714,6 +714,11 @@ class TestFoo(unittest.TestCase): f = foo.Foo("hello") self.assertEqual(str(f), "hello") + def test_outer_inner_namespace(self): + inner = foo.TopNs.PrefixBottomNs.PrefixInner () + inner.Do () + self.assertEqual (True, True) + if __name__ == '__main__': unittest.main()