@@ -158,10 +158,11 @@ def resolve_impls(
158158 rename_local_impls (config .programs , module , ylocals )
159159 rename_local_impls (config .models , module , ylocals )
160160 resolve_impl_imports (config , ylocals , ctx )
161- update_local_implementations (config , ylocals )
162161 config .imports = [i for i in config .imports if i .kind != ImportKind .IMPLEMENTATION ]
163162
164- return apply_custom_implementations (config , module , ylocals , ctx )
163+ overwritten_impls = apply_custom_implementations (config , module , ylocals , ctx )
164+ update_local_implementations (config , ylocals )
165+ return overwritten_impls
165166
166167
167168T = TypeVar ('T' , bound = 'Implementation' )
@@ -225,16 +226,6 @@ def resolve_impl_imports(
225226 ctx .pop_import ()
226227
227228
228- def update_local_implementations (
229- config : Configuration , ylocals : Dict [Reference , Reference ]) -> None :
230- """Updates names of local implementations to their full names."""
231- for model in config .models .values ():
232- for cmp in model .components .values ():
233- if cmp .implementation :
234- if cmp .implementation in ylocals :
235- cmp .implementation = ylocals [cmp .implementation ]
236-
237-
238229def apply_custom_implementations (
239230 config : Configuration , module : Reference , ylocals : Dict [Reference , Reference ],
240231 ctx : ResolutionContext ) -> Set [Reference ]:
@@ -268,6 +259,8 @@ def impl_hint_msg(
268259 overwritten_implementations = set ()
269260 copied_paths = set ()
270261
262+ # Pre-copy any models that will be updated, if they were imported and we therefore
263+ # cannot modify them in place without interfering with other uses of the same model.
271264 for key , value in config .custom_implementations .items ():
272265 base_model_name = Reference ([key [0 ]])
273266 if ylocals .get (base_model_name ) not in config .models :
@@ -282,9 +275,6 @@ def impl_hint_msg(
282275 f' Unknown implementation "{ value } " in custom_implementations'
283276 f' "{ key } : { value } ". { impl_hint_msg (value )} ' )
284277
285- path = key [1 :]
286- new_impl = ylocals [value ] if value is not None else None
287-
288278 # Before modifying it, we copy the model from its original a.b.c.Model to
289279 # <module>.Model so that the changes don't affect other uses of it, or the
290280 # cached version.
@@ -299,8 +289,13 @@ def impl_hint_msg(
299289 config .models [new_name ] = m
300290 ylocals [base_model_name ] = m .name
301291 overwritten_implementations .add (orig_name )
302- else :
303- m = orig_model
292+
293+ for key , value in config .custom_implementations .items ():
294+ base_model_name = Reference ([key [0 ]])
295+ path = key [1 :]
296+ new_impl = ylocals [value ] if value is not None else None
297+
298+ m = config .models [ylocals [base_model_name ]]
304299
305300 # Now we can walk down the components and copy-and-rename the models along the
306301 # path, again to avoid making unintended changes elsewhere
@@ -319,6 +314,8 @@ def impl_hint_msg(
319314 f' which does not have a component named { str (component )} .' )
320315
321316 orig_impl = m .components [component ].implementation
317+ if orig_impl in ylocals :
318+ orig_impl = ylocals [orig_impl ]
322319 if orig_impl is None or orig_impl not in config .models :
323320 raise RuntimeError (
324321 ctx .trace () +
@@ -372,6 +369,16 @@ def impl_hint_msg(
372369 return overwritten_implementations
373370
374371
372+ def update_local_implementations (
373+ config : Configuration , ylocals : Dict [Reference , Reference ]) -> None :
374+ """Updates names of local implementations to their full names."""
375+ for model in config .models .values ():
376+ for cmp in model .components .values ():
377+ if cmp .implementation :
378+ if cmp .implementation in ylocals :
379+ cmp .implementation = ylocals [cmp .implementation ]
380+
381+
375382def find_impls (
376383 config : Configuration , name : Reference , ctx : ResolutionContext
377384 ) -> List [Implementation ]:
0 commit comments