def beta_to_blueprint_values()

in chz/data_model.py [0:0]


def beta_to_blueprint_values(obj) -> Any:
    """Return a dict which can be used to recreate the same object via blueprint.

    Example:
    ```
    @chz.chz
    class Foo:
        a: int
        b: str

    foo = Foo(a=1, b="hello")
    assert chz.Blueprint(Foo).apply(chz.beta_to_blueprint_values(foo)).make() == foo
    ```

    See also: asdict
    """
    blueprint_values = {}

    def join_arg_path(parent: str, child: str) -> str:
        if not parent:
            return child
        if child.startswith("."):
            return parent + child
        return parent + "." + child

    def inner(obj: Any, path: str):
        if hasattr(obj, "__chz_fields__"):
            for field_name, field_info in obj.__chz_fields__.items():
                value = getattr(obj, field_info.x_name)
                param_path = join_arg_path(path, field_name)
                if field_info.meta_factory is not None and (
                    type(value)
                    is not typing.get_origin(field_info.meta_factory.unspecified_factory())
                ):
                    # Try to detect when we have used polymorphic construction
                    blueprint_values[param_path] = type(value)

                inner(value, param_path)

        elif (
            isinstance(obj, dict)
            and all(isinstance(k, str) for k in obj.keys())
            and any(is_chz(v) for v in obj.values())
        ):
            for k, v in obj.items():
                param_path = join_arg_path(path, k)
                blueprint_values[param_path] = type(v)  # may be overridden if not needed
                inner(v, param_path)

        elif isinstance(obj, (list, tuple)) and any(is_chz(v) for v in obj):
            for i, v in enumerate(obj):
                param_path = join_arg_path(path, str(i))
                blueprint_values[param_path] = type(v)  # may be overridden if not needed
                inner(v, param_path)

        else:
            blueprint_values[path] = obj

    inner(obj, "")

    return blueprint_values