Skip to content

Instantly share code, notes, and snippets.

@AlexWaygood
Last active October 11, 2024 09:57
Show Gist options
  • Save AlexWaygood/674db1fce6856a90f251f63e73853639 to your computer and use it in GitHub Desktop.
Save AlexWaygood/674db1fce6856a90f251f63e73853639 to your computer and use it in GitHub Desktop.
C3 linearization
type BasesList = list[type]
type Mro = list[type]
def merge(seqs: list[BasesList]) -> Mro:
print(f"Merging {seqs}")
mro: Mro = []
i = 1
while True:
print(f"{mro=}")
print(f"Loop {i}")
i += 1
non_empty_seqs: list[BasesList] = [seq for seq in seqs if seq]
if not non_empty_seqs:
print(f"Returning merged sequences {mro=}\n\n")
return mro
candidate: type | None = None
for seq in non_empty_seqs: # find merge candidates among seq heads
candidate = seq[0]
print(f"{candidate=}")
not_head = any(candidate in seq[1:] for seq in non_empty_seqs)
if not_head:
candidate = None # reject candidate
else:
break
if not candidate:
raise Exception("Inconsistent hierarchy")
mro.append(candidate)
for seq in non_empty_seqs: # remove cand
if seq[0] == candidate:
del seq[0]
def mro(C: type) -> Mro:
"Compute the class precedence list (mro) according to C3"
return merge([[C], *map(mro, C.__bases__), list(C.__bases__)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment