MCPcopy Index your code
hub / github.com/RustPython/RustPython / linearise_mro

Function linearise_mro

crates/vm/src/builtins/type.rs:2794–2831  ·  view source on GitHub ↗
(mut bases: Vec<Vec<PyTypeRef>>)

Source from the content-addressed store, hash-verified

2792}
2793
2794fn linearise_mro(mut bases: Vec<Vec<PyTypeRef>>) -> Result<Vec<PyTypeRef>, String> {
2795 vm_trace!("Linearise MRO: {:?}", bases);
2796 // Python requires that the class direct bases are kept in the same order.
2797 // This is called local precedence ordering.
2798 // This means we must verify that for classes A(), B(A) we must reject C(A, B) even though this
2799 // algorithm will allow the mro ordering of [C, B, A, object].
2800 // To verify this, we make sure non of the direct bases are in the mro of bases after them.
2801 for (i, base_mro) in bases.iter().enumerate() {
2802 let base = &base_mro[0]; // MROs cannot be empty.
2803 for later_mro in &bases[i + 1..] {
2804 // We start at index 1 to skip direct bases.
2805 // This will not catch duplicate bases, but such a thing is already tested for.
2806 if later_mro[1..].iter().any(|cls| cls.is(base)) {
2807 return Err(format!(
2808 "Cannot create a consistent method resolution order (MRO) for bases {}",
2809 bases.iter().map(|x| x.first().unwrap()).format(", ")
2810 ));
2811 }
2812 }
2813 }
2814
2815 let mut result = vec![];
2816 while !bases.is_empty() {
2817 let head = take_next_base(&mut bases).ok_or_else(|| {
2818 // Take the head class of each class here. Now that we have reached the problematic bases.
2819 // Because this failed, we assume the lists cannot be empty.
2820 format!(
2821 "Cannot create a consistent method resolution order (MRO) for bases {}",
2822 bases.iter().map(|x| x.first().unwrap()).format(", ")
2823 )
2824 })?;
2825
2826 result.push(head);
2827
2828 bases.retain(|x| !x.is_empty());
2829 }
2830 Ok(result)
2831}
2832
2833fn calculate_meta_class(
2834 metatype: PyTypeRef,

Callers 1

resolve_mroMethod · 0.85

Calls 8

take_next_baseFunction · 0.85
isMethod · 0.80
ok_or_elseMethod · 0.80
ErrClass · 0.50
iterMethod · 0.45
is_emptyMethod · 0.45
pushMethod · 0.45
retainMethod · 0.45

Tested by

no test coverage detected