Skip to content

Commit

Permalink
Merge pull request #19 from matthewrmshin/feature/include-variables-o…
Browse files Browse the repository at this point in the history
…bject

include (local scope) variable with non-str value
  • Loading branch information
matthewrmshin authored Nov 29, 2023
2 parents 18b4c3d + 81a6a5c commit 1acbc7f
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 4 deletions.
42 changes: 40 additions & 2 deletions docs/data-process.rst
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ string value. If you want to leave the original syntax unchanged for unbound
variables, set the placeholder VALUE to ``YP_ORIGINAL``.


String Value Variable Substitution Include Scope
------------------------------------------------
Variable Substitution Include Scope
-----------------------------------

It is possible to define or override the values of the variables for
substitution in include files. The scope of the change will be local to the
Expand Down Expand Up @@ -378,6 +378,44 @@ Running :program:`yp-data main.yaml <yp-data>` will give:
car:
type: Porsche
It is possible to pass variables of any type via the include scope, and
reference them in a substitution. However, only variables of string type can be
used in substitution that involves a string concatenation.

Consider:

.. code-block:: yaml
hello:
- INCLUDE: greet.yaml
VARIABLES:
HELLO: greet
TARGETS:
- Humans
- Martians
You can reference ``TARGETS`` in ``greet.yaml`` on its own but not in a string
substitution.

For example, this causes a ``ValueError``:

.. code-block:: yaml
# greet.yaml
say:
- ${HELLO} ${TARGETS} # Bad, cannot concatenate a list to a string
# ...
But this is fine:

.. code-block:: yaml
# greet.yaml
say:
- hello: ${HELLO}
targets: ${TARGETS} # Good, value used on its own
# ...
String Value Date-Time Substitution
-----------------------------------
Expand Down
7 changes: 5 additions & 2 deletions src/yamlprocessor/dataprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class DataProcessor:
},
VARIABLES_KEY: {
'patternProperties': {
r'^[A-z_]\w*$': {'type': 'string'},
r'^[A-z_]\w*$': {'description': 'any valid variable name'},
},
'additionalProperties': False,
'type': 'object',
Expand Down Expand Up @@ -563,7 +563,7 @@ def process_variable(
else:
substitute = groups['symbol']
if substitute != groups['symbol'] and groups['cast']:
if groups['head'] or tail != item:
if groups['head'] or groups['tail'] or tail != item:
raise ValueError(
f'{item}: bad substitution expression')
try:
Expand All @@ -588,6 +588,9 @@ def process_variable(
f'{item}: bad substitution value: {substitute}')
ret = substitute
tail = ''
elif not any(groups[k] for k in ('head', 'escape', 'tail')):
ret = substitute
tail = ''
else:
ret += (
groups['head']
Expand Down
42 changes: 42 additions & 0 deletions src/yamlprocessor/tests/test_dataprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,48 @@ def test_main_14(tmp_path, yaml):
}


def test_main_15(tmp_path, yaml):
"""Test main, include file with variables as anchor."""
yaml_0 = """
hello: &worlds
earth: sapiens
mars: martians
greet:
INCLUDE: in_1.yaml
VARIABLES:
WORLDS: *worlds
"""
yaml_1 = """
known_worlds: $WORLDS
other_worlds:
pandora: Na'vi people
endor: ewoks
"""
infilename = tmp_path / 'in_0.yaml'
with infilename.open('w') as infile:
infile.write(yaml_0)
with (tmp_path / 'in_1.yaml').open('w') as infile:
infile.write(yaml_1)
outfilename = tmp_path / 'out.yaml'
main([str(infilename), str(outfilename)])
assert yaml.load(outfilename.open()) == {
'hello': {
'earth': 'sapiens',
'mars': 'martians',
},
'greet': {
'known_worlds': {
'earth': 'sapiens',
'mars': 'martians',
},
'other_worlds': {
'pandora': 'Na\'vi people',
'endor': 'ewoks',
},
},
}


def test_main_validate_1(tmp_path, capsys, yaml):
"""Test main, YAML with JSON schema validation."""
schema = {
Expand Down

0 comments on commit 1acbc7f

Please sign in to comment.