Skip to content

Commit

Permalink
Fix resolved values in case of failure
Browse files Browse the repository at this point in the history
When the value cannot be resolved usually the original value is
returned. However if it contains `%` signs there will be an escape step
and that escaped value is returned.
That makes it impossible to have values which can only later be
resolved, like `cd %(startdir)s` in extensions which would become
`cd %%(startdir)s` on the first resolve-attempt.
  • Loading branch information
Flamefire committed May 14, 2024
1 parent 31b1846 commit 7323bae
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 0 deletions.
2 changes: 2 additions & 0 deletions easybuild/framework/easyconfig/easyconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -2026,12 +2026,14 @@ def resolve_template(value, tmpl_dict):
# '%(name)s' -> '%(name)s'
# '%%(name)s' -> '%%(name)s'
if '%' in value:
orig_value = value
value = re.sub(re.compile(r'(%)(?!%*\(\w+\)s)'), r'\1\1', value)

try:
value = value % tmpl_dict
except KeyError:
_log.warning("Unable to resolve template value %s with dict %s", value, tmpl_dict)
value = orig_value # Undo "%"-escaping
else:
# this block deals with references to objects and returns other references
# for reading this is ok, but for self['x'] = {}
Expand Down
7 changes: 7 additions & 0 deletions test/framework/easyconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -3663,6 +3663,9 @@ def test_resolve_template(self):
('%%(name)s', '%(name)s'),
('%%%(name)s', '%FooBar'),
('%%%%(name)s', '%%(name)s'),
# It doesn't matter what is resolved
('%%(invalid)s', '%(invalid)s'),
('%%%%(invalid)s', '%%(invalid)s'),
)
for value, expected in values:
self.assertEqual(resolve_template(value, tmpl_dict), expected)
Expand All @@ -3671,6 +3674,10 @@ def test_resolve_template(self):
expected += ' FooBar'
self.assertEqual(resolve_template(value, tmpl_dict), expected)

# On unknown values the value is returned unchanged
for value in ('%(invalid)s', '%(name)s %(invalid)s', '%%%(invalid)s', '% %(invalid)s', '%s %(invalid)s'):
self.assertEqual(resolve_template(value, tmpl_dict), value)

def test_det_subtoolchain_version(self):
"""Test det_subtoolchain_version function"""
_, all_tc_classes = search_toolchain('')
Expand Down

0 comments on commit 7323bae

Please sign in to comment.