Skip to content

Commit c204edc

Browse files
committed
only allow dict value to update dict easyconfig parameter, take copy of original parameter value rather than using reference to original value, fix comments/error messages
1 parent a347fb1 commit c204edc

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

easybuild/framework/easyconfig/easyconfig.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -574,45 +574,50 @@ def copy(self, validate=None):
574574

575575
def update(self, key, value, allow_duplicate=True):
576576
"""
577-
Update a string configuration value with a value (i.e. append to it).
578-
NOTE: For dictionaries, 'allow_duplicate' will be ignored.
577+
Update an easyconfig parameter with the specified value (i.e. append to it).
578+
Note: For dictionary easyconfig parameters, 'allow_duplicate' is ignored (since it's meaningless).
579579
"""
580580
if isinstance(value, string_type):
581581
inval = [value]
582582
elif isinstance(value, (list, dict, tuple)):
583583
inval = value
584584
else:
585585
msg = "Can't update configuration value for %s, because the attempted"
586-
msg += " update value, '%s', is not a string, list or dictionary."
586+
msg += " update value, '%s', is not a string, list, tuple or dictionary."
587587
raise EasyBuildError(msg, key, value)
588588

589-
# For dictionaries, input value cannot be a string; must be iterable
590-
if isinstance(self[key], dict) and isinstance(value, string_type):
589+
# For easyconfig parameters that are dictionaries, input value must also be a dictionary
590+
if isinstance(self[key], dict) and not isinstance(value, dict):
591591
msg = "Can't update configuration value for %s, because the attempted"
592-
msg += "update value, '%s', is not iterable (list, tuple, dict)."
593-
raise EasyBuildError(msg, key, value)
592+
msg += "update value (%s), is not a dictionary (type: %s)."
593+
raise EasyBuildError(msg, key, value, type(value))
594+
595+
# Grab current parameter value so we can modify it
596+
param_value = copy.deepcopy(self[key])
594597

595-
# Make copy of current configuration value so we can modify it
596-
param_value = self[key]
597598
if isinstance(param_value, string_type):
598599
for item in inval:
599600
# re.search: only add value to string if it's not there yet (surrounded by whitespace)
600601
if allow_duplicate or (not re.search(r'(^|\s+)%s(\s+|$)' % re.escape(item), param_value)):
601602
param_value = param_value + ' %s ' % item
603+
602604
elif isinstance(param_value, (list, tuple)):
605+
# make sure we have a list value so we can just append to it
603606
param_value = list(param_value)
604607
for item in inval:
605608
if allow_duplicate or item not in param_value:
606609
param_value.append(item)
607-
if isinstance(self[key], tuple): # Cast back to original type
610+
# cast back to tuple if original value was a tuple
611+
if isinstance(self[key], tuple):
608612
param_value = tuple(param_value)
613+
609614
elif isinstance(param_value, dict):
610615
param_value.update(inval)
611616
else:
612-
msg = "Can't update configuration value for %s, because it's not a string, list or dictionary."
617+
msg = "Can't update configuration value for %s, because it's not a string, list, tuple or dictionary."
613618
raise EasyBuildError(msg, key)
614619

615-
# Replace modified value back into configuration, preserving type
620+
# Overwrite easyconfig parameter value with updated value, preserving type
616621
self[key] = param_value
617622

618623
def set_keys(self, params):

0 commit comments

Comments
 (0)