Skip to content

Commit d3cb4b8

Browse files
authored
Values are now type converted as needed, rather than immediately. This prevents issues with variable values that look like numerics, but need to act like strings. (#862)
1 parent 980177a commit d3cb4b8

File tree

4 files changed

+28
-11
lines changed

4 files changed

+28
-11
lines changed

lib/pavilion/parsers/expressions.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,14 @@ def _apply_op(self, op_func: Callable[[Any, Any], Any],
173173
else:
174174
val1 = arg1.value
175175
val2 = arg2.value
176+
# When one of the two isn't a string, try to convert them both to non-string values.
177+
if not (isinstance(val1, str) and isinstance(val2, str)):
178+
val1 = auto_type_convert(arg1.value)
179+
val2 = auto_type_convert(arg2.value)
180+
# After conversion, if one is still a string, make them both string values.
181+
if isinstance(val1, str) or isinstance(val2, str):
182+
val1 = str(arg1.value)
183+
val2 = str(arg2.value)
176184

177185
if (isinstance(val1, list) and isinstance(val2, list)
178186
and len(val1) != len(val2)):
@@ -693,10 +701,6 @@ def var_ref(self, items) -> lark.Token:
693701
self._merge_tokens(items, var_key),
694702
err.args[0])
695703

696-
# Convert val into the type it looks most like.
697-
if isinstance(val, str):
698-
val = auto_type_convert(val)
699-
700704
return self._merge_tokens(items, val)
701705

702706
@staticmethod

test/tests/mod_wrapper_tests.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pavilion.unittest import PavTestCase
88
from pavilion import resolver
99
from pavilion.test_run import TestRun
10+
from pavilion import module_wrapper
1011

1112
MODULE_SYSTEM_ROOT_PATHS = [
1213
Path('/usr/share/Modules'),
@@ -102,6 +103,7 @@ def test_add_module(self):
102103
test_cfg['run']['modules'] = [
103104
'', # A blank module
104105
'test_mod1/1.0',
106+
'test_mod1/1.10',
105107
'test_mod1', # Should load 1.1 as the default.
106108
'test_mod2', # Un-versioned.
107109
]
@@ -114,8 +116,8 @@ def test_add_module(self):
114116
# test_mod1 only gets added once (no dups)
115117
'[[ "${mods_sorted}" == "test_mod1:test_mod2" ]] || exit 1',
116118
# test_mod2 has no version (but the module file appends it anyway.)
117-
'[[ "${vers_sorted}" == "1.0:1.1:" ]] || '
118-
'[[ "${vers_sorted}" == "1.1::" ]] || exit 1'
119+
'[[ "${vers_sorted}" == "1.0:1.10:" ]] || '
120+
'[[ "${vers_sorted}" == "1.10::" ]] || exit 1'
119121
]
120122

121123
test = self._quick_test(test_cfg)
@@ -309,3 +311,13 @@ def check_test(ctest, expected_lines):
309311
'module swap $old_module gcc/1.2.8',
310312
])
311313

314+
def test_parse_module(self):
315+
"""Make sure the parse_module function behaves as expected"""
316+
317+
checks = [
318+
('foo/1.10', ('load', ('foo', '1.10'), (None, None)))
319+
]
320+
321+
for mod, result in checks:
322+
self.assertEqual(module_wrapper.parse_module(mod), result)
323+

test/tests/parser_tests.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,18 @@ def test_visitors(self):
8282
'int1 + var.int2 * 11 * - sum([int1, int2])': -65,
8383
'int1 + var.float1 * -2 * -len(ints.*)': 14.200000000000001,
8484
'str1': 'hello',
85-
'ints.3': 3,
86-
'ints[3]': 3,
85+
'ints.3': '3',
86+
'ints.3 + 1': 4,
87+
'ints[3]': '3',
8788
'ints[3:5]': ['3', '4'],
8889
'ints[:3]': ['0', '1', '2'],
8990
'ints[3:]': ['3', '4', '5'],
9091
'ints[:]': ['0', '1', '2', '3', '4', '5'],
91-
'ints[-3]': 3,
92+
'ints[-3]': '3',
9293
'ints[-4:-1]': ['2', '3', '4'],
93-
'ints': 0,
94+
'ints': '0',
9495
# Make sure this isn't parsed as 'not e'
95-
'note': 3,
96+
'note': '3',
9697
'struct.cpus * 0': 0,
9798
'struct.cpus // 7': 28,
9899
'struct.cpus / 7': 28.571428571428573,

0 commit comments

Comments
 (0)