def check_field_consistency_in_tree()

in chz/validators.py [0:0]


def check_field_consistency_in_tree(obj: Any, fields: set[str], regex_root: str = "") -> None:
    """
    This isn't itself a validator. See test_validate_field_consistency for example usage.
    This is effectively a way to paper over a potential missing feature in chz.
    """
    values: dict[tuple[str, str], dict[object, list[str]]] = collections.defaultdict(
        lambda: collections.defaultdict(list)
    )

    def inner(obj: Any, obj_path: str):
        assert chz.is_chz(obj)

        for f in obj.__chz_fields__.values():
            value = getattr(obj, f.logical_name)
            field_path = f"{obj_path}.{f.logical_name}" if obj_path else f.logical_name
            regex_match = re.search(regex_root, obj_path)
            if f.logical_name in fields and regex_match:
                values[(regex_match.group(), f.logical_name)][value].append(field_path)

            if chz.is_chz(value):
                inner(value, field_path)
            if isinstance(value, collections.abc.Mapping):
                for k, v in value.items():
                    if chz.is_chz(v):
                        inner(v, f"{field_path}.{k}")
            elif isinstance(value, collections.abc.Sequence):
                for i, v in enumerate(value):
                    if chz.is_chz(v):
                        inner(v, f"{field_path}.{i}")

    inner(obj, "")

    def paths_repr(paths: list[str]) -> str:
        if len(paths) <= 3:
            return ", ".join(paths)
        return ", ".join(paths[:3]) + f", ... ({len(paths) - 3} more)"

    for (_, field), value_to_paths in values.items():
        if len(value_to_paths) > 1:
            raise ValueError(
                f"Field {field!r} has inconsistent values in object tree:\n"
                + "\n".join(
                    f"{value!r} at {paths_repr(paths)}" for value, paths in value_to_paths.items()
                )
            )