Plain is headed towards 1.0! Subscribe for development updates →

 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