Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions spawn/parsers/specification_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,29 +243,29 @@ def _parse_value(self, parent, name, value, next_node_spec, node_policies, ghost
literal, name, value = self._parse_literal(name, value)
# combinator lookup
if self._is_combinator(name):
logger.debug('Parsing "{}" as combinator'.format(name))
logger.debug('Parsing "%s" as combinator', name)
self._parse_combinator(parent, name, value, next_node_spec, node_policies, ghost_parameters)
# list expansion
elif isinstance(value, list) and not literal:
logger.debug('Parsing "{}" as list'.format(name))
logger.debug('Parsing "%s" as list', name)
for val in value:
self._parse_value(parent, name, val, next_node_spec, node_policies, ghost_parameters)
# burrow into object
elif isinstance(value, dict) and not literal:
logger.debug('Parsing "{}" as object'.format(name))
logger.debug('Parsing "%s" as object', name)
self.parse(value, parent, node_policies=node_policies, ghost_parameters=ghost_parameters)
self.parse(next_node_spec, parent, node_policies=node_policies, ghost_parameters=ghost_parameters)
# rhs prefixed proxies (evaluators and co.) - short form and long form
elif isinstance(value, str) and self._is_value_proxy(value) and not literal:
logger.debug('Parsing "{}" as value proxy'.format(name))
logger.debug('Parsing "%s" as value proxy', name)
next_parent = ValueProxyNode(
parent, name, self._value_proxy_parser.parse(value),
node_policies.get(PATH, None), ghost_parameters
)
self.parse(next_node_spec, next_parent)
# simple single value
else:
logger.debug('Parsing "{}" as raw value ({})'.format(name, value))
logger.debug('Parsing "%s" as raw value (%s)', name, value)
next_parent = self._node_factory.create(
parent, name, value, node_policies.get(PATH, None), ghost_parameters, literal=literal
)
Expand Down Expand Up @@ -299,7 +299,8 @@ def _get_combinator(self, name):

def _parse_combinator(self, parent, name, value, next_node_spec, node_policies, ghost_parameters):
for node_spec in self._get_combinator(name)(value):
self._parse_value(parent, '', node_spec, next_node_spec, node_policies, ghost_parameters)
node_spec = {**node_spec, **next_node_spec}
self.parse(node_spec, parent, node_policies, ghost_parameters)

def _get_next_node(self, node_spec):
next_key = list(node_spec.keys())[0]
Expand Down
7 changes: 6 additions & 1 deletion spawn/specification/specification.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def add_child(self, child):
:type child: :class:`SpecificationNode`
"""
if child not in self._children:
logging.getLogger(__name__).debug('Adding child {} onto {}'.format(child.description, self.description))
logging.getLogger(__name__).debug('Adding child %s onto %s', child.description, self.description)
self._children.append(child)
#pylint: disable=protected-access
child._parent = self
Expand Down Expand Up @@ -332,6 +332,11 @@ def path(self):

@property
def description(self):
"""Description of this node

:returns: A description of the node
:rtype: str
"""
return 'root node' if self.is_root else 'node with property "{}"'.format(self.property_name)

def evaluate(self):
Expand Down
24 changes: 24 additions & 0 deletions tests/parsers/specification_parser_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -788,3 +788,27 @@ def test_multiple_literal_lists_in_object_does_not_combine():
}]
properties = [l.collected_properties for l in root_node.leaves]
assert expected == properties


def test_variable_succeeding_combinator(parser):
spec = {
"spec": {
"combine:zip": {
"alpha": [
10, 20, 30
],
"beta": [
7, 8, 9
]
},
"gamma": "#2 * !beta"
}
}
model = parser.parse(spec)
expected_properties = [
{"alpha": 10, "beta": 7, "gamma": 14},
{"alpha": 20, "beta": 8, "gamma": 16},
{"alpha": 30, "beta": 9, "gamma": 18}
]
assert len(model.root_node.leaves) == 3
assert [l.collected_properties for l in model.root_node.leaves] == expected_properties