Last active
February 11, 2026 03:08
-
-
Save ktbarrett/a732920618513b4e49ba35105e11a452 to your computer and use it in GitHub Desktop.
Python implementation of the C3 algorithm used in Python for MRO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from collections.abc import Mapping, Sequence | |
| from typing import TypeVar | |
| T = TypeVar("T") | |
| def linearize(node: T, dep_tree: Mapping[T, Sequence[T]]) -> tuple[T, ...]: | |
| @cache | |
| def helper(node: T) -> tuple[T, ...]: | |
| return ( | |
| node, | |
| *merge(*(helper(dep) for dep in dep_tree[node])), | |
| ) | |
| def merge(*seqs: Sequence[T]) -> list[T]: | |
| merge: list[T] = [] | |
| merge_remaining = [list(seq) for seq in seqs if seq] | |
| while merge_remaining: | |
| for seq in merge_remaining: | |
| candidate = seq[0] | |
| if not any(candidate in seq[1:] for seq in merge_remaining): | |
| break | |
| else: | |
| raise ValueError("Cyclic dependencies detected") | |
| merge.append(candidate) | |
| merge_remaining = [ | |
| r | |
| for seq in merge_remaining | |
| if (r := (seq[1:] if seq[0] == candidate else seq)) | |
| ] | |
| return merge | |
| return helper(node) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment