MCPcopy Index your code
hub / github.com/python/cpython / _c3_mro

Function _c3_mro

Lib/functools.py:783–826  ·  view source on GitHub ↗

Computes the method resolution order using extended C3 linearization. If no *abcs* are given, the algorithm works exactly like the built-in C3 linearization used for method resolution. If given, *abcs* is a list of abstract base classes that should be inserted into the resulting MR

(cls, abcs=None)

Source from the content-addressed store, hash-verified

781 del seq[0]
782
783def _c3_mro(cls, abcs=None):
784 """Computes the method resolution order using extended C3 linearization.
785
786 If no *abcs* are given, the algorithm works exactly like the built-in C3
787 linearization used for method resolution.
788
789 If given, *abcs* is a list of abstract base classes that should be inserted
790 into the resulting MRO. Unrelated ABCs are ignored and don't end up in the
791 result. The algorithm inserts ABCs where their functionality is introduced,
792 i.e. issubclass(cls, abc) returns True for the class itself but returns
793 False for all its direct base classes. Implicit ABCs for a given class
794 (either registered or inferred from the presence of a special method like
795 __len__) are inserted directly after the last ABC explicitly listed in the
796 MRO of said class. If two implicit ABCs end up next to each other in the
797 resulting MRO, their ordering depends on the order of types in *abcs*.
798
799 """
800 for i, base in enumerate(reversed(cls.__bases__)):
801 if hasattr(base, '__abstractmethods__'):
802 boundary = len(cls.__bases__) - i
803 break # Bases up to the last explicit ABC are considered first.
804 else:
805 boundary = 0
806 abcs = list(abcs) if abcs else []
807 explicit_bases = list(cls.__bases__[:boundary])
808 abstract_bases = []
809 other_bases = list(cls.__bases__[boundary:])
810 for base in abcs:
811 if issubclass(cls, base) and not any(
812 issubclass(b, base) for b in cls.__bases__
813 ):
814 # If *cls* is the class that introduces behaviour described by
815 # an ABC *base*, insert said ABC to its MRO.
816 abstract_bases.append(base)
817 for base in abstract_bases:
818 abcs.remove(base)
819 explicit_c3_mros = [_c3_mro(base, abcs=abcs) for base in explicit_bases]
820 abstract_c3_mros = [_c3_mro(base, abcs=abcs) for base in abstract_bases]
821 other_c3_mros = [_c3_mro(base, abcs=abcs) for base in other_bases]
822 return _c3_merge(
823 [[cls]] +
824 explicit_c3_mros + abstract_c3_mros + other_c3_mros +
825 [explicit_bases] + [abstract_bases] + [other_bases]
826 )
827
828def _compose_mro(cls, types):
829 """Calculates the method resolution order for a given class *cls*.

Callers 1

_compose_mroFunction · 0.85

Calls 6

enumerateFunction · 0.85
listClass · 0.85
_c3_mergeFunction · 0.85
anyFunction · 0.70
appendMethod · 0.45
removeMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…