[ros-xacro] 01/01: New upstream version 1.11.1

Jochen Sprickerhof jspricke at moszumanska.debian.org
Sun Dec 4 17:33:19 UTC 2016


This is an automated email from the git hooks/post-receive script.

jspricke pushed a commit to annotated tag upstream/1.11.1
in repository ros-xacro.

commit 1050cb2c8a7debcd237038881c096769cbcc20a7
Author: Jochen Sprickerhof <git at jochen.sprickerhof.de>
Date:   Sun Dec 4 18:23:47 2016 +0100

    New upstream version 1.11.1
---
 CHANGELOG.rst                        | 23 ++++++++++++
 package.xml                          |  2 +-
 src/xacro/__init__.py                | 71 ++++++++++++++++++++++--------------
 src/xacro/cli.py                     |  2 +-
 test/test-xacro-cmake/CMakeLists.txt |  2 +-
 test/test_xacro.py                   | 55 +++++++++++++++-------------
 6 files changed, 100 insertions(+), 55 deletions(-)

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 0f6561e..cb9d651 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -2,6 +2,29 @@
 Changelog for package xacro
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+1.11.1 (2016-06-22)
+-------------------
+* workaround for xml.dom.minidom issue
+* ensure non-empty error string
+* Contributors: Robert Haschke
+
+1.11.0 (2016-03-25)
+-------------------
+* added short option -i as alternative to --inorder
+* refactored main to fix #122, #107
+* added xacro indicator to error message to fix #123
+* moved banner generation to process_file()
+* removed special (but obsolete) output handling for just_includes mode
+* moved core processing pipeline into function process_file()
+* improved documentation: more comments, input_file -> input_file_name
+* fix #120: handle non-space whitespace characters in params string
+* extended tests to handle non-space whitespace characters in params string
+* always store macros with xacro: prefix in front: #118
+* fix #115: enforce xacro namespace usage with --xacro-ns option
+* apply correct checking for include tags, and extend testcase
+* allow (one-level) nested expression/extension evaluation
+* Contributors: Robert Haschke, Morgan Quigley
+
 1.10.6 (2015-09-01)
 -------------------
 * use correct catkin environment for cmake dependency checking
diff --git a/package.xml b/package.xml
index 6ccb98c..7af1e2d 100644
--- a/package.xml
+++ b/package.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <package>
   <name>xacro</name>
-  <version>1.10.6</version>
+  <version>1.11.1</version>
   <description>Xacro (XML Macros)
 
     Xacro is an XML macro language. With xacro, you can construct shorter and more readable XML files by using macros that expand to larger XML expressions.
diff --git a/src/xacro/__init__.py b/src/xacro/__init__.py
index d972311..a364801 100644
--- a/src/xacro/__init__.py
+++ b/src/xacro/__init__.py
@@ -356,7 +356,7 @@ def is_include(elt):
             return False
         else:
             # throw a deprecated warning
-            deprecated_tag()
+            return check_deprecated_tag(elt.tagName)
     return True
 
 
@@ -481,7 +481,7 @@ def parse_macro_arg(s):
         return param, (param if forward else None, default), rest
     else:
         # there is no default specified at all
-        result = s.lstrip(' ').split(' ', 1)
+        result = s.lstrip().split(None, 1)
         return result[0], None, result[1] if len(result) > 1 else ''
 
 
@@ -494,6 +494,9 @@ def grab_macro(elt, macros):
         warning("deprecated use of macro name 'call'; xacro:call became a new keyword")
     if name.find('.') != -1:
         warning("macro names must not contain '.': %s" % name)
+    # always have 'xacro:' namespace in macro name
+    if not name.startswith('xacro:'):
+        name = 'xacro:' + name
 
     # fetch existing or create new macro definition
     macro = macros.get(name, Macro())
@@ -584,14 +587,14 @@ LEXER = QuickLexer(DOLLAR_DOLLAR_BRACE=r"\$\$+\{",
 def eval_text(text, symbols):
     def handle_expr(s):
         try:
-            return eval(s, global_symbols, symbols)
+            return eval(eval_text(s, symbols), global_symbols, symbols)
         except Exception as e:
             # re-raise as XacroException to add more context
             raise XacroException(exc=e,
                 suffix=os.linesep + "when evaluating expression '%s'" % s)
 
     def handle_extension(s):
-        return eval_extension("$(%s)" % s)
+        return eval_extension("$(%s)" % eval_text(s, symbols))
 
     results = []
     lex = QuickLexer(LEXER)
@@ -656,9 +659,9 @@ def resolve_macro(fullname, macros):
         try:
             return macros[name]
         except KeyError:
-            # try without xacro: prefix as well
-            if name.startswith('xacro:'):
-                return _resolve([], name.replace('xacro:',''), macros)
+            # try with xacro: prefix as well
+            if allow_non_prefixed_tags and not name.startswith('xacro:'):
+                return _resolve([], 'xacro:' + name, macros)
 
     # try fullname and (namespaces, name) in this order
     m = _resolve([], fullname, macros)
@@ -720,6 +723,7 @@ def handle_macro_call(node, macros, symbols):
     try:
         eval_all(body, macros, scoped)
     except Exception as e:
+        # fill in macro call history for nice error reporting
         if hasattr(e, 'macros'):
             e.macros.append(m)
         else:
@@ -773,7 +777,7 @@ def remove_previous_comments(node):
         else:
             # insert empty text node to stop removing of comments in future calls
             # actually this moves the singleton instance to the new location
-            if next: node.parentNode.insertBefore(_empty_text_node, next)
+            if next and _empty_text_node != next: node.parentNode.insertBefore(_empty_text_node, next)
             return
 
 
@@ -984,20 +988,41 @@ def print_location(filestack, err=None, file=sys.stderr):
         print(msg, f, file=file)
         msg = 'included from:'
 
+def process_file(input_file_name, **kwargs):
+    """main processing pipeline"""
+    # initialize file stack for error-reporting
+    restore_filestack([input_file_name])
+    # parse the document into a xml.dom tree
+    doc = parse(None, input_file_name)
+    # perform macro replacement
+    process_doc(doc, **kwargs)
+
+    # add xacro auto-generated banner
+    banner = [xml.dom.minidom.Comment(c) for c in
+              [" %s " % ('=' * 83),
+               " |    This document was autogenerated by xacro from %-30s | " % input_file_name,
+               " |    EDITING THIS FILE BY HAND IS NOT RECOMMENDED  %-30s | " % "",
+               " %s " % ('=' * 83)]]
+    first = doc.firstChild
+    for comment in banner:
+        doc.insertBefore(comment, first)
+
+    return doc
 
 def main():
-    opts, input_file = process_args(sys.argv[1:])
+    opts, input_file_name = process_args(sys.argv[1:])
     if opts.in_order == False:
-        warning("Traditional processing is deprecated. Switch to --inorder processing!")
+        warning("xacro: Traditional processing is deprecated. Switch to --inorder processing!")
         message("To check for compatibility of your document, use option --check-order.", color='yellow')
         message("For more infos, see http://wiki.ros.org/xacro#Processing_Order", color='yellow')
 
     try:
-        restore_filestack([input_file])
-        doc = parse(None, input_file)
-        process_doc(doc, **vars(opts))
+        # open and process file
+        doc = process_file(input_file_name, **vars(opts))
+        # open the output file
         out = open_output(opts.output)
 
+    # error handling
     except xml.parsers.expat.ExpatError as e:
         error("XML parsing error: %s" % str(e), alt_text=None)
         if verbosity > 0:
@@ -1010,7 +1035,9 @@ def main():
         sys.exit(2)  # indicate failure, but don't print stack trace on XML errors
 
     except Exception as e:
-        error(str(e))
+        msg = error(str(e))
+        if not msg: msg = repr(e)
+        error(msg)
         if verbosity > 0:
             print_location(filestack, e)
         if verbosity > 1:
@@ -1019,25 +1046,15 @@ def main():
         else:
             sys.exit(2)  # gracefully exit with error condition
 
+    # special output mode
     if opts.just_deps:
         out.write(" ".join(set(all_includes)))
         print()
         return
-    if opts.just_includes:
-        out.write(doc.toprettyxml(indent='  '))
-        print()
-        return
-
-    banner = [xml.dom.minidom.Comment(c) for c in
-              [" %s " % ('=' * 83),
-               " |    This document was autogenerated by xacro from %-30s | " % input_file,
-               " |    EDITING THIS FILE BY HAND IS NOT RECOMMENDED  %-30s | " % "",
-               " %s " % ('=' * 83)]]
-    first = doc.firstChild
-    for comment in banner:
-        doc.insertBefore(comment, first)
 
+    # write output
     out.write(doc.toprettyxml(indent='  '))
     print()
+    # only close output file, but not stdout
     if opts.output:
         out.close()
diff --git a/src/xacro/cli.py b/src/xacro/cli.py
index 30e66ed..7815707 100644
--- a/src/xacro/cli.py
+++ b/src/xacro/cli.py
@@ -66,7 +66,7 @@ def process_args(argv, require_input=True):
                       help="write output to FILE instead of stdout")
     parser.add_option("--oldorder", action="store_false", dest="in_order",
                       help="use traditional processing order [deprecated default]")
-    parser.add_option("--inorder", action="store_true", dest="in_order",
+    parser.add_option("--inorder", "-i", action="store_true", dest="in_order",
                       help="use processing in read order")
     parser.add_option("--check-order", action="store_true", dest="do_check_order",
                       help="check document for inorder processing", default=False)
diff --git a/test/test-xacro-cmake/CMakeLists.txt b/test/test-xacro-cmake/CMakeLists.txt
index d5247ee..672af70 100644
--- a/test/test-xacro-cmake/CMakeLists.txt
+++ b/test/test-xacro-cmake/CMakeLists.txt
@@ -14,5 +14,5 @@ list(APPEND xacro_outputs ${MY_OUTPUT_VAR})
 add_custom_target(xacro_target ALL DEPENDS ${xacro_outputs})
 xacro_install(xacro_target ${xacro_outputs} DESTINATION xml)
 
-## convienency function
+## convenience function
 xacro_add_files(TARGET xacro test.xacro REMAP bar:=foo foo:=bar INSTALL)
diff --git a/test/test_xacro.py b/test/test_xacro.py
index eb8f468..450d456 100644
--- a/test/test_xacro.py
+++ b/test/test_xacro.py
@@ -165,8 +165,8 @@ class TestXacroFunctions(unittest.TestCase):
         self.assertFalse(xacro.is_valid_name('invalid.too'))  # dot separates fields
 
     def test_resolve_macro(self):
-        # define three nested macro dicts with the same content
-        content = {'simple': 'simple', 'xacro:prefixed': 'prefixed'}
+        # define three nested macro dicts with the same macro names (keys)
+        content = {'xacro:simple': 'simple'}
         ns2 = dict({k: v+'2' for k,v in content.iteritems()})
         ns1 = dict({k: v+'1' for k,v in content.iteritems()})
         ns1.update(ns2=ns2)
@@ -181,26 +181,18 @@ class TestXacroFunctions(unittest.TestCase):
         self.assertEqual(xacro.resolve_macro('xacro:ns1.simple', macros), 'simple1')
         self.assertEqual(xacro.resolve_macro('xacro:ns1.ns2.simple', macros), 'simple2')
 
-        self.assertEqual(xacro.resolve_macro('prefixed', macros), None)
-        self.assertEqual(xacro.resolve_macro('ns1.prefixed', macros), None)
-        self.assertEqual(xacro.resolve_macro('ns1.ns2.prefixed', macros), None)
-
-        self.assertEqual(xacro.resolve_macro('xacro:prefixed', macros), 'prefixed')
-        self.assertEqual(xacro.resolve_macro('xacro:ns1.prefixed', macros), 'prefixed1')
-        self.assertEqual(xacro.resolve_macro('xacro:ns1.ns2.prefixed', macros), 'prefixed2')
+    def check_macro_arg(self, s, param, forward, default, rest):
+        p, v, r = xacro.parse_macro_arg(s)
+        self.assertEqual(p, param, msg="'{0}' != '{1}' parsing {2}".format(p, param, s))
+        if forward or default:
+            self.assertTrue(v is not None)
+            self.assertEqual(v[0], forward, msg="'{0}' != '{1}' parsing {2}".format(v[0], forward, s))
+            self.assertEqual(v[1], default, msg="'{0}' != '{1}' parsing {2}".format(v[1], default, s))
+        else:
+            self.assertTrue(v is None)
+        self.assertEqual(r, rest, msg="'{0}' != '{1}' parsing {2}".format(r, rest, s))
 
     def test_parse_macro_arg(self):
-        def check(s, param, forward, default, rest):
-            p, v, r = xacro.parse_macro_arg(s)
-            self.assertEqual(p, param, msg="'{0}' != '{1}' parsing {2}".format(p, param, s))
-            if forward or default:
-                self.assertTrue(v is not None)
-                self.assertEqual(v[0], forward, msg="'{0}' != '{1}' parsing {2}".format(v[0], forward, s))
-                self.assertEqual(v[1], default, msg="'{0}' != '{1}' parsing {2}".format(v[1], default, s))
-            else:
-                self.assertTrue(v is None)
-            self.assertEqual(r, rest, msg="'{0}' != '{1}' parsing {2}".format(r, rest, s))
-
         for forward in ['', '^', '^|']:
             defaults = ['', "f('some string','some other')", "f('a b')"]
             if forward == '^': defaults = ['']
@@ -209,10 +201,12 @@ class TestXacroFunctions(unittest.TestCase):
                 for sep in seps:
                     for rest in ['', ' ', ' bar', ' bar=42']:
                         s = 'foo{0}{1}{2}{3}'.format(sep, forward, default, rest)
-                        check(s, 'foo', 'foo' if forward else None,
-                              default if default else None,
-                              rest.lstrip(' '))
-        check('  foo bar=341', 'foo', None, None, 'bar=341')
+                        self.check_macro_arg(s, 'foo', 'foo' if forward else None,
+                                             default if default else None,
+                                             rest.lstrip())
+    def test_parse_macro_whitespace(self):
+        for ws in ['  ', ' \t ', ' \n ']:
+            self.check_macro_arg(ws + 'foo' + ws + 'bar=42' + ws, 'foo', None, None, 'bar=42' + ws)
 
 # base class providing some convenience functions
 class TestXacroBase(unittest.TestCase):
@@ -984,15 +978,17 @@ class TestXacro(TestXacroCommentsIgnored):
   <a list="[0, 2, 2]" tuple="(0, 2, 2)" dict="{'a': 0, 'c': 2, 'b': 2}"/>
 </a>''')
 
-    def test_ros_arg_param(self):
+    def test_enforce_xacro_ns(self):
         self.assert_matches(
                 self.quick_xacro('''\
 <a xmlns:xacro="http://www.ros.org/wiki/xacro">
   <arg name="foo" value="bar"/>
+  <include filename="foo"/>
 </a>''', xacro_ns=False),
 '''\
 <a xmlns:xacro="http://www.ros.org/wiki/xacro">
   <arg name="foo" value="bar"/>
+  <include filename="foo"/>
 </a>''')
 
     def test_issue_68_numeric_arg(self):
@@ -1062,6 +1058,15 @@ class TestXacro(TestXacroCommentsIgnored):
         self.assert_matches(self.quick_xacro(src % '|'), res % '42')
         self.assert_matches(self.quick_xacro(src % '|6'), res % '42')
 
+    def test_extension_in_expression(self):
+        src='''<a xmlns:xacro="http://www.ros.org/wiki/xacro">${2*'$(arg var)'}</a>'''
+        res='''<a xmlns:xacro="http://www.ros.org/wiki/xacro">%s</a>'''
+        self.assert_matches(self.quick_xacro(src, ['var:=xacro']), res % (2*'xacro'))
+
+    def test_expression_in_extension(self):
+        src='''<a xmlns:xacro="http://www.ros.org/wiki/xacro">$(arg ${'v'+'ar'})</a>'''
+        res='''<a xmlns:xacro="http://www.ros.org/wiki/xacro">%s</a>'''
+        self.assert_matches(self.quick_xacro(src, ['var:=xacro']), res % 'xacro')
 
 # test class for in-order processing
 class TestXacroInorder(TestXacro):

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/ros/ros-xacro.git



More information about the debian-science-commits mailing list