ros / xacro

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.
http://www.ros.org/wiki/xacro
BSD 3-Clause "New" or "Revised" License
89 stars 99 forks source link

xacro args are implicitly required to be strings #321

Closed Aposhian closed 1 year ago

Aposhian commented 1 year ago

When trying to have an arg with a computed default, it only works if I put it in quotes. If I don't, then it gets interpreted as a float, and breaks downstream things that try to insert it as a string.

example: ("test.xacro")

<?xml version="1.0" encoding="UTF-8"?>
<robot name="test" xmlns:xacro="http://www.ros.org/wiki/xacro">

<xacro:property name="property_1" value="1.23"/>
<xacro:property name="property_2" value="4.56"/>

<!-- This doesn't work -->
<xacro:arg name="my_arg" default="${property_1 - property_2}"/>

<!-- This works -->
<!-- <xacro:arg name="my_arg" default="'${property_1 - property_2}'"/> -->

<xacro:property name="property_3" value="$(arg my_arg)"/>

<joint name="my_link_to_base" type="fixed">
  <origin xyz="${property_1} ${property_2} ${property_3}"/>
</joint>

</robot>

Running xacro test.xacro gives the following error

replace() argument 2 must be str, not float 
when evaluating expression 'property_3'
when processing file: test.xacro

Or more verbosely with xacro --verbosity=4 test.xacro:

set property_1: 1.23 (test.xacro)
set property_2: 4.56 (test.xacro)
use property_1: 1.23 (test.xacro)
use property_2: 4.56 (test.xacro)
set property_3: $(arg my_arg) (test.xacro)
use property_1: 1.23 (test.xacro)
use property_2: 4.56 (test.xacro)
replace() argument 2 must be str, not float 
when evaluating expression 'property_3'
when processing file: test.xacro

Traceback (most recent call last):
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 689, in handle_expr
    return safe_eval(eval_text(s, symbols), symbols)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 233, in safe_eval
    return eval(code, globals, locals)
  File "<expression>", line 1, in <module>
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 353, in __getitem__
    return self._resolve_(key)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 340, in _resolve_
    dict.__setitem__(self, key, self._eval_literal(eval_text(dict.__getitem__(self, key), self)))
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 706, in eval_text
    results.append(handle_extension(lex.next()[1][2:-1]))
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 696, in handle_extension
    return eval_extension("$(%s)" % eval_text(s, symbols))
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 289, in eval_extension
    return resolve_args(s, context=substitution_args_context)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/substitution_args.py", line 322, in resolve_args
    resolved = _resolve_args(arg_str, context, commands)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/substitution_args.py", line 338, in _resolve_args
    resolved = commands[command](resolved, a, args, context)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/substitution_args.py", line 182, in _arg
    return resolved.replace('$(%s)' % a, _eval_arg(name=args[0], args=context['arg']))
TypeError: replace() argument 2 must be str, not float

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/ros/humble/bin/xacro", line 33, in <module>
    sys.exit(load_entry_point('xacro==2.0.8', 'console_scripts', 'xacro')())
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 1171, in main
    _process(input_file_name, vars(opts))
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 1119, in _process
    doc = process_file(input_file_name, **opts)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 1098, in process_file
    process_doc(doc, **kwargs)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 1050, in process_doc
    eval_all(doc.documentElement, macros, symbols)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 981, in eval_all
    eval_all(node, macros, symbols)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 981, in eval_all
    eval_all(node, macros, symbols)
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 895, in eval_all
    result = str(eval_text(value, symbols))
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 704, in eval_text
    results.append(handle_expr(lex.next()[1][2:-1]))
  File "/opt/ros/humble/local/lib/python3.10/dist-packages/xacro/__init__.py", line 692, in handle_expr
    raise XacroException(exc=e,
xacro.XacroException: replace() argument 2 must be str, not float 
when evaluating expression 'property_3'
rhaschke commented 1 year ago

Thanks for reporting this bug.

rhaschke commented 1 year ago

Closed via #322