Skip to content

Commit

Permalink
Rebase from 'upstream'
Browse files Browse the repository at this point in the history
  • Loading branch information
rhaschke committed Apr 2, 2024
1 parent 1ff1a26 commit 2140f1b
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 22 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
Changelog for package xacro
^^^^^^^^^^^^^^^^^^^^^^^^^^^

1.14.18 (2024-04-02)
--------------------
* Add more unit tags for yaml files (`#331 <https://github.com/ros/xacro/issues/331>`_)
* Mark regexes as raw strings (`#336 <https://github.com/ros/xacro/issues/336>`_)
* Contributors: Adam Heins, Bruno-Pier

1.14.17 (2024-01-25)
--------------------
* Expose python.abs()
Expand Down
2 changes: 1 addition & 1 deletion package.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package>
<name>xacro</name>
<version>1.14.17</version>
<version>1.14.18</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.
Expand Down
41 changes: 25 additions & 16 deletions src/xacro/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
from __future__ import print_function, division

import ast
import collections
import enum
import glob
import math
import os
Expand Down Expand Up @@ -115,25 +117,32 @@ 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)
try:
return float(safe_eval(value, _global_symbols))
except SyntaxError:
raise XacroException("invalid expression: %s" % value)


def construct_angle_degrees(loader, node):
"""utility function for converting degrees into radians from yaml"""
return math.radians(construct_angle_radians(loader, node))
class ConstructUnits(enum.Enum):
"""utility enumeration to construct a values with a unit from yaml"""
__ConstructUnitsValue = collections.namedtuple('__ConstructUnitsValue', ['tag', 'conversion_constant'])
# Angles [base: radians]
angle_radians = __ConstructUnitsValue(u'!radians', 1.0)
angle_degrees = __ConstructUnitsValue(u'!degrees', math.pi/180.0)
# Length [base: meters]
length_meters = __ConstructUnitsValue(u'!meters', 1.0)
length_millimeters = __ConstructUnitsValue(u'!millimeters', 0.001)
length_foot = __ConstructUnitsValue(u'!foot', 0.3048)
length_inches = __ConstructUnitsValue(u'!inches', 0.0254)

def constructor(self, loader, node):
"""utility function to construct a values with a unit from yaml"""
value = loader.construct_scalar(node)
try:
return float(safe_eval(value, _global_symbols))*self.value.conversion_constant
except SyntaxError:
raise XacroException("invalid expression: %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)
for unit in ConstructUnits:
yaml.SafeLoader.add_constructor(unit.value.tag, unit.constructor)
except Exception:
raise XacroException("yaml support not available; install python-yaml")

Expand Down Expand Up @@ -566,8 +575,8 @@ def is_valid_name(name):
return False


default_value = '''\$\{.*?\}|\$\(.*?\)|(?:'.*?'|\".*?\"|[^\s'\"]+)+|'''
re_macro_arg = re.compile(r'^\s*([^\s:=]+?)\s*:?=\s*(\^\|?)?(' + default_value + ')(?:\s+|$)(.*)')
default_value = r'''\$\{.*?\}|\$\(.*?\)|(?:'.*?'|\".*?\"|[^\s'\"]+)+|'''
re_macro_arg = re.compile(r'^\s*([^\s:=]+?)\s*:?=\s*(\^\|?)?(' + default_value + r')(?:\s+|$)(.*)')
# space( param )( := )( ^| )( default )( space )(rest)


Expand Down
12 changes: 9 additions & 3 deletions test/constructors.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
a: !degrees 2*90
b: !radians 0.5*pi
c: 42
no_tag: 42
angles:
- !radians pi
- !degrees 2*90
lengths:
- !meters 5.0*5.0
- !millimeters 25.0*1000.0
- !foot 25.0/0.3048
- !inches 25.0/0.0254
4 changes: 2 additions & 2 deletions test/test_xacro.py
Original file line number Diff line number Diff line change
Expand Up @@ -1500,9 +1500,9 @@ def test_yaml_custom_constructors(self):
src = '''
<a xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:property name="values" value="${xacro.load_yaml('constructors.yaml')}"/>
<values a="${values.a}" b="${values.b}" c="${values.c}"/>
<values no_tag="${values.no_tag}" angles="${values.angles}" lengths="${values.lengths}"/>
</a>'''
res = '''<a><values a="{}" b="{}" c="42"/></a>'''.format(math.pi, 0.5*math.pi)
res = '''<a><values no_tag="42" angles="{}" lengths="{}"/></a>'''.format([math.pi]*2, [25.0]*4)
self.assert_matches(self.quick_xacro(src), res)

def test_yaml_custom_constructors_illegal_expr(self):
Expand Down

0 comments on commit 2140f1b

Please sign in to comment.