@@ -1022,6 +1022,7 @@ def update_config(
10221022 function_filter : Callable = None ,
10231023 attributes : list [str ] | str = None ,
10241024 dynamic : bool = True ,
1025+ dict_mod : bool = False ,
10251026 ):
10261027 """
10271028 Update the job config.
@@ -1045,6 +1046,9 @@ def update_config(
10451046 dynamic
10461047 The updates will be propagated to Jobs/Flows dynamically generated at
10471048 runtime.
1049+ dict_mod
1050+ Use the dict mod language to apply updates. See :obj:`.DictMods` for more
1051+ details.
10481052
10491053 Examples
10501054 --------
@@ -1096,12 +1100,23 @@ def update_config(
10961100 At variance, if `dynamic` is set to `False` the `manager_config` option will
10971101 only be set for the `test_job` and not for the generated Jobs.
10981102 """
1103+ from jobflow .utils .dict_mods import apply_mod
1104+
1105+ if dict_mod and attributes :
1106+ raise ValueError ("dict_mod and attributes options cannot be used together" )
1107+
1108+ if dict_mod and isinstance (config , JobConfig ):
1109+ raise ValueError (
1110+ "If dict_mod is selected the update config cannot be a JobConfig object"
1111+ )
1112+
10991113 if dynamic :
11001114 dict_input = {
11011115 "config" : config ,
11021116 "name_filter" : name_filter ,
11031117 "function_filter" : function_filter ,
11041118 "attributes" : attributes ,
1119+ "dict_mod" : dict_mod ,
11051120 }
11061121 self .config_updates .append (dict_input )
11071122
@@ -1119,29 +1134,34 @@ def update_config(
11191134 return
11201135
11211136 # if we get to here then we pass all the filters
1122- if isinstance (config , dict ):
1123- # convert dict specification to a JobConfig but set the attributes
1124- if attributes is None :
1125- attributes = list (config .keys ())
1126-
1127- attributes = [attributes ] if isinstance (attributes , str ) else attributes
1128- if not set (attributes ).issubset (set (config .keys ())):
1129- raise ValueError (
1130- "Specified attributes include a key that is not present in the "
1131- "config dictionary."
1132- )
1133- config = JobConfig (** config )
1134-
1135- if attributes is None :
1136- # overwrite the whole config
1137- self .config = config
1137+ if dict_mod :
1138+ conf_dict = self .config .as_dict ()
1139+ apply_mod (config , conf_dict )
1140+ self .config = JobConfig .from_dict (conf_dict )
11381141 else :
1139- # only update the specified attributes
1140- attributes = [attributes ] if isinstance (attributes , str ) else attributes
1141- for attr in attributes :
1142- if not hasattr (self .config , attr ):
1143- raise ValueError (f"Unknown JobConfig attribute: { attr } " )
1144- setattr (self .config , attr , getattr (config , attr ))
1142+ if isinstance (config , dict ):
1143+ # convert dict specification to a JobConfig but set the attributes
1144+ if attributes is None :
1145+ attributes = list (config .keys ())
1146+
1147+ attributes = [attributes ] if isinstance (attributes , str ) else attributes
1148+ if not set (attributes ).issubset (set (config .keys ())):
1149+ raise ValueError (
1150+ "Specified attributes include a key that is not present in the "
1151+ "config dictionary."
1152+ )
1153+ config = JobConfig (** config )
1154+
1155+ if attributes is None :
1156+ # overwrite the whole config
1157+ self .config = config
1158+ else :
1159+ # only update the specified attributes
1160+ attributes = [attributes ] if isinstance (attributes , str ) else attributes
1161+ for attr in attributes :
1162+ if not hasattr (self .config , attr ):
1163+ raise ValueError (f"Unknown JobConfig attribute: { attr } " )
1164+ setattr (self .config , attr , getattr (config , attr ))
11451165
11461166 def as_dict (self ) -> dict :
11471167 """Serialize the job as a dictionary."""
0 commit comments