1from __future__ import annotations
2
3from collections.abc import Generator
4from typing import Any
5
6
7def make_model_tuple(model: Any) -> tuple[str, str]:
8 """
9 Take a model or a string of the form "package_label.ModelName" and return a
10 corresponding ("package_label", "modelname") tuple. If a tuple is passed in,
11 assume it's a valid model tuple already and return it unchanged.
12 """
13 try:
14 if isinstance(model, tuple):
15 model_tuple = model
16 elif isinstance(model, str):
17 package_label, model_name = model.split(".")
18 model_tuple = package_label, model_name.lower()
19 else:
20 model_tuple = (
21 model.model_options.package_label,
22 model.model_options.model_name,
23 )
24 assert len(model_tuple) == 2
25 return model_tuple
26 except (ValueError, AssertionError):
27 raise ValueError(
28 f"Invalid model reference '{model}'. String model references "
29 "must be of the form 'package_label.ModelName'."
30 )
31
32
33def resolve_callables(
34 mapping: dict[str, Any],
35) -> Generator[tuple[str, Any], None, None]:
36 """
37 Generate key/value pairs for the given mapping where the values are
38 evaluated if they're callable.
39 """
40 for k, v in mapping.items():
41 yield k, v() if callable(v) else v