Skip to content

Commit

Permalink
Provide support for yaml constructors !degrees and !radians
Browse files Browse the repository at this point in the history
  • Loading branch information
rhaschke committed Aug 18, 2020
1 parent 07d94f2 commit f5bb067
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/xacro/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,30 @@ def __getattr__(self, item):

__getitem__ = __getattr__


def construct_angle_radians(loader, node):
"""utility function to construct radian values from yaml"""
value = loader.construct_scalar(node).strip()
try:
return float(eval(value, global_symbols, global_symbols))
except SyntaxError as e:
raise XacroException("invalid expression: %s" % value)


def construct_angle_degrees(loader, node):
"""utility function for converting degrees into radians from yaml"""
value = loader.construct_scalar(node)
try:
return math.radians(float(value))
except ValueError:
raise XacroException("invalid degree value: %s" % value)


def load_yaml(filename):
try:
import yaml
yaml.SafeLoader.add_constructor(u'!radians', construct_angle_radians)
yaml.SafeLoader.add_constructor(u'!degrees', construct_angle_degrees)
except:
raise XacroException("yaml support not available; install python-yaml")

Expand Down
3 changes: 3 additions & 0 deletions test/constructors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
a: !degrees 180
b: !radians 0.5*pi
c: 42
10 changes: 10 additions & 0 deletions test/test_xacro.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import subprocess
import re
import ast
import math
try:
from cStringIO import StringIO # Python 2.x
except ImportError:
Expand Down Expand Up @@ -1173,6 +1174,15 @@ def test_yaml_support_key_in_dict(self):
res = '''<a>True False</a>'''
self.assert_matches(self.quick_xacro(src), res)

def test_yaml_custom_constructors(self):
src = '''
<a xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:property name="values" value="${load_yaml('constructors.yaml')}"/>
<values a="${values.a}" b="${values.b}" c="${values.c}"/>
</a>'''
res = '''<a><values a="{}" b="{}" c="42"/></a>'''.format(math.pi, 0.5*math.pi)
self.assert_matches(self.quick_xacro(src), res)

def test_macro_default_param_evaluation_order(self):
src='''<a xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:macro name="foo" params="arg:=${2*foo}">
Expand Down

0 comments on commit f5bb067

Please sign in to comment.