Skip to content

Commit bfbae89

Browse files
committed
Replace Configuration.top_models() with .root_model()
1 parent 5b93f6f commit bfbae89

File tree

1 file changed

+52
-8
lines changed

1 file changed

+52
-8
lines changed

ymmsl/v0_2/configuration.py

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,21 +225,65 @@ def check_consistent(self, check_runnable: bool = True) -> None:
225225
' problems were found:\n- '
226226
+ '\n- '.join(errors))
227227

228-
def top_models(self) -> List[Model]:
228+
def root_model(self, selected_model: Optional[Reference] = None) -> Model:
229+
"""Return the root model of this configuration.
230+
231+
If there are multiple models that are not used as an implementation in any
232+
component (root models), and selected_model is given and names one of them, then
233+
that model is returned, otherwise an exception is raised.
234+
235+
If there is only a single root model, then it is returned, unless selected_model
236+
is given and does not match, in which case an exception is raised.
237+
238+
If there are no models, an exception is raised.
239+
240+
Args:
241+
selected_model: Name of the model to return, in case of multiple options
242+
243+
Returns:
244+
The sole or selected model that is not used as an implementation in any
245+
component in the configuration.
246+
247+
Raises:
248+
RuntimeError if an error occurs, as described above.
249+
"""
250+
root_models = self._root_models()
251+
if not root_models:
252+
raise RuntimeError('No model was found in this configuration.')
253+
254+
if selected_model:
255+
match = [m for m in root_models if m.name == selected_model]
256+
if match:
257+
return match[0]
258+
259+
models = '\n- '.join([str(m.name) for m in root_models])
260+
raise RuntimeError(
261+
f'The selected model "{selected_model}" could not be found in this'
262+
' configuration. The following models are present:\n- {models}')
263+
264+
if len(root_models) == 1:
265+
return root_models[0]
266+
267+
models = '\n- '.join([str(m.name) for m in root_models])
268+
raise RuntimeError(
269+
'Multiple models were found in this configuration that are not used'
270+
f' as implementations:\n\n- {models}')
271+
272+
def _root_models(self) -> List[Model]:
229273
"""Models in this configuration that are not used as implementations."""
230-
top_models = copy(self.models)
274+
root_models = copy(self.models)
231275

232276
for model in self.models.values():
233277
for component in model.components.values():
234278
if component.implementation:
235-
if component.implementation in top_models:
236-
del top_models[component.implementation]
279+
if component.implementation in root_models:
280+
del root_models[component.implementation]
237281

238282
for impl in self.custom_implementations.values():
239-
if impl in top_models:
240-
del top_models[impl]
283+
if impl in root_models:
284+
del root_models[impl]
241285

242-
return list(top_models.values())
286+
return list(root_models.values())
243287

244288
def _component_paths(self) -> Dict[Reference, Component]:
245289
"""Return component paths for components.
@@ -253,7 +297,7 @@ def _component_paths(self) -> Dict[Reference, Component]:
253297
same component object, if a submodel is used multiple times.
254298
"""
255299
result = dict()
256-
queue = [(m, Reference([])) for m in self.top_models()]
300+
queue = [(m, Reference([])) for m in self._root_models()]
257301

258302
while queue:
259303
model, prefix = queue.pop(0)

0 commit comments

Comments
 (0)