Source code for app.util.helpers.mro

# SPDX-License-Identifier: GPLv3-or-later
# Copyright © 2025 pygaindalf Rui Pinheiro


from typing import TYPE_CHECKING


if TYPE_CHECKING:
    from collections.abc import Iterable


def _ensure_mro_order(final: type, target: type, others: type | Iterable[type], *, before: bool = True, fail: bool = True) -> bool:
    mro = final.__mro__
    index = mro.index(target)

    if isinstance(others, type):
        others = (others,)

    for cur in others:
        try:
            cur_index = mro.index(cur)
            if (cur_index < index) if before else (cur_index > index):
                if fail:
                    msg = f"'{target.__name__}' must come *{'before' if before else 'after'}* '{cur.__name__}' in the '{type(final).__name__}' MRO"
                    raise TypeError(msg)
                return False
        except ValueError:
            continue  # If the class is not in the MRO, we ignore it

    return True


[docs] def ensure_mro_order( final: type | object, target: type, *, before: type | Iterable[type] | None = None, after: type | Iterable[type] | None = None, fail: bool = True ) -> bool: if not isinstance(final, type): final = type(final) if before is not None: if not _ensure_mro_order(final, target, before, before=True, fail=fail): return False if after is not None: if not _ensure_mro_order(final, target, after, before=False, fail=fail): return False return True