@@ -145,6 +145,34 @@ def set_process_keys(self):
145
145
if od_key is not None :
146
146
p_obj .__xsimlab_od_keys__ [var .name ] = od_key
147
147
148
+ def ensure_no_intent_conflict (self ):
149
+ """Raise an error if more than one variable with
150
+ intent='out' targets the same variable.
151
+
152
+ """
153
+ filter_out = lambda var : (
154
+ var .metadata ['intent' ] == VarIntent .OUT and
155
+ var .metadata ['var_type' ] != VarType .ON_DEMAND
156
+ )
157
+
158
+ targets = defaultdict (list )
159
+
160
+ for p_name , p_obj in self ._processes_obj .items ():
161
+ for var in filter_variables (p_obj , func = filter_out ).values ():
162
+ target_key = p_obj .__xsimlab_store_keys__ .get (var .name )
163
+ targets [target_key ].append ((p_name , var .name ))
164
+
165
+ conflicts = {k : v for k , v in targets .items () if len (v ) > 1 }
166
+
167
+ if conflicts :
168
+ conflicts_str = {k : ' and ' .join (["'{}.{}'" .format (* i ) for i in v ])
169
+ for k , v in conflicts .items ()}
170
+ msg = '\n ' .join (["'{}.{}' set by: {}" .format (* k , v )
171
+ for k , v in conflicts_str .items ()])
172
+
173
+ raise ValueError (
174
+ "Conflict(s) found in given variable intents:\n " + msg )
175
+
148
176
def get_all_variables (self ):
149
177
"""Get all variables in the model as a list of
150
178
``(process_name, var_name)`` tuples.
@@ -364,6 +392,8 @@ def __init__(self, processes):
364
392
self ._all_vars = builder .get_all_variables ()
365
393
self ._all_vars_dict = None
366
394
395
+ builder .ensure_no_intent_conflict ()
396
+
367
397
self ._input_vars = builder .get_input_variables ()
368
398
self ._input_vars_dict = None
369
399
0 commit comments