@@ -574,30 +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).
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).
578579 """
579580 if isinstance (value , string_type ):
580- lval = [value ]
581- elif isinstance (value , list ):
582- lval = value
581+ inval = [value ]
582+ elif isinstance (value , ( list , dict , tuple ) ):
583+ inval = value
583584 else :
584- msg = "Can't update configuration value for %s, because the "
585- msg += "attempted update value, '%s', is not a string or list ."
585+ msg = "Can't update configuration value for %s, because the attempted "
586+ msg += " update value, '%s', is not a string, list, tuple or dictionary ."
586587 raise EasyBuildError (msg , key , value )
587588
588- param_value = self [key ]
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 ):
591+ msg = "Can't update configuration value for %s, because the attempted"
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 ])
597+
589598 if isinstance (param_value , string_type ):
590- for item in lval :
599+ for item in inval :
591600 # re.search: only add value to string if it's not there yet (surrounded by whitespace)
592601 if allow_duplicate or (not re .search (r'(^|\s+)%s(\s+|$)' % re .escape (item ), param_value )):
593602 param_value = param_value + ' %s ' % item
594- elif isinstance (param_value , list ):
595- for item in lval :
603+
604+ elif isinstance (param_value , (list , tuple )):
605+ # make sure we have a list value so we can just append to it
606+ param_value = list (param_value )
607+ for item in inval :
596608 if allow_duplicate or item not in param_value :
597- param_value = param_value + [item ]
609+ param_value .append (item )
610+ # cast back to tuple if original value was a tuple
611+ if isinstance (self [key ], tuple ):
612+ param_value = tuple (param_value )
613+
614+ elif isinstance (param_value , dict ):
615+ param_value .update (inval )
598616 else :
599- raise EasyBuildError ("Can't update configuration value for %s, because it's not a string or list." , key )
617+ msg = "Can't update configuration value for %s, because it's not a string, list, tuple or dictionary."
618+ raise EasyBuildError (msg , key )
600619
620+ # Overwrite easyconfig parameter value with updated value, preserving type
601621 self [key ] = param_value
602622
603623 def set_keys (self , params ):
0 commit comments