From 7b5c20907375400cf4db6993a13238e86b38acf3 Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Thu, 20 Jan 2022 08:53:40 +0100 Subject: [PATCH] Fix resolving of properties declared and used in/from a namespace (#306) This is a follow-up of #297, which resolved a corresponding issue for macro names only. As we have separate dicts for macros and symbols, we need to resolve both of them. --- src/xacro/__init__.py | 15 ++++++++------- test/include3.xacro | 8 ++++++++ test/inner.xacro | 5 +++++ test/test_xacro.py | 18 ++++++++++++------ 4 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 test/include3.xacro create mode 100644 test/inner.xacro diff --git a/src/xacro/__init__.py b/src/xacro/__init__.py index 28a139e..666f7d4 100644 --- a/src/xacro/__init__.py +++ b/src/xacro/__init__.py @@ -848,23 +848,24 @@ def handle_dynamic_macro_call(node, macros, symbols): raise XacroException("unknown macro name '%s' in xacro:call" % name) -def resolve_macro(fullname, macros): +def resolve_macro(fullname, macros, symbols): # split name into namespaces and real name namespaces = fullname.split('.') name = namespaces.pop(-1) - def _resolve(namespaces, name, macros): - # traverse namespaces to actual macros dict + def _resolve(namespaces, name, macros, symbols): + # traverse namespaces to actual macros+symbols dicts for ns in namespaces: macros = macros[ns] - return macros, macros[name] + symbols = symbols[ns] + return macros, symbols, macros[name] # try fullname and (namespaces, name) in this order try: - return _resolve([], fullname, macros) + return _resolve([], fullname, macros, symbols) except KeyError: if namespaces: - return _resolve(namespaces, name, macros) + return _resolve(namespaces, name, macros, symbols) else: raise @@ -878,7 +879,7 @@ def handle_macro_call(node, macros, symbols): return False try: - macros, m = resolve_macro(name, macros) + macros, symbols, m = resolve_macro(name, macros, symbols) if name is node.tagName: # no xacro prefix provided? deprecated_tag(name) body = m.body.cloneNode(deep=True) diff --git a/test/include3.xacro b/test/include3.xacro new file mode 100644 index 0000000..bb4f92e --- /dev/null +++ b/test/include3.xacro @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/test/inner.xacro b/test/inner.xacro new file mode 100644 index 0000000..fef4e2a --- /dev/null +++ b/test/inner.xacro @@ -0,0 +1,5 @@ + + + + + diff --git a/test/test_xacro.py b/test/test_xacro.py index 17d617f..baa7f49 100644 --- a/test/test_xacro.py +++ b/test/test_xacro.py @@ -260,17 +260,17 @@ def test_is_valid_name(self): self.assertFalse(xacro.is_valid_name('invalid.too')) # dot separates fields def test_resolve_macro(self): - # define three nested macro dicts with the same macro names (keys) + # define three nested dicts with the same names (keys) content = {'simple': 'simple'} ns2 = dict({k: v + '2' for k, v in content.items()}) ns1 = dict({k: v + '1' for k, v in content.items()}) ns1.update(ns2=ns2) - macros = dict(content) - macros.update(ns1=ns1) + ns = dict(content) + ns.update(ns1=ns1) - self.assertEqual(xacro.resolve_macro('simple', macros), (macros, 'simple')) - self.assertEqual(xacro.resolve_macro('ns1.simple', macros), (ns1, 'simple1')) - self.assertEqual(xacro.resolve_macro('ns1.ns2.simple', macros), (ns2, 'simple2')) + self.assertEqual(xacro.resolve_macro('simple', ns, ns), (ns, ns, 'simple')) + self.assertEqual(xacro.resolve_macro('ns1.simple', ns, ns), (ns1, ns1, 'simple1')) + self.assertEqual(xacro.resolve_macro('ns1.ns2.simple', ns, ns), (ns2, ns2, 'simple2')) def check_macro_arg(self, s, param, forward, default, rest): p, v, r = xacro.parse_macro_arg(s) @@ -1285,6 +1285,12 @@ def test_include_from_macro(self): res = '''''' self.assert_matches(self.quick_xacro(src), res) + def test_namespace_propagation(self): + src = ''' + ''' + res = '''''' + self.assert_matches(self.quick_xacro(src), res) + def test_dotify(self): src = '''