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

Function __build_class__

crates/vm/src/stdlib/builtins.rs:1165–1334  ·  view source on GitHub ↗
(
        function: PyRef<PyFunction>,
        name: PyStrRef,
        bases: PosArgs,
        mut kwargs: KwArgs,
        vm: &VirtualMachine,
    )

Source from the content-addressed store, hash-verified

1163
1164 #[pyfunction]
1165 pub fn __build_class__(
1166 function: PyRef<PyFunction>,
1167 name: PyStrRef,
1168 bases: PosArgs,
1169 mut kwargs: KwArgs,
1170 vm: &VirtualMachine,
1171 ) -> PyResult {
1172 let name_obj: PyObjectRef = name.clone().into();
1173
1174 // Update bases.
1175 let mut new_bases: Option<Vec<PyObjectRef>> = None;
1176 let bases = PyTuple::new_ref(bases.into_vec(), &vm.ctx);
1177 for (i, base) in bases.iter().enumerate() {
1178 if base.fast_isinstance(vm.ctx.types.type_type) {
1179 if let Some(bases) = &mut new_bases {
1180 bases.push(base.clone());
1181 }
1182 continue;
1183 }
1184 let mro_entries =
1185 vm.get_attribute_opt(base.clone(), identifier!(vm, __mro_entries__))?;
1186 let entries = match mro_entries {
1187 Some(meth) => meth.call((bases.clone(),), vm)?,
1188 None => {
1189 if let Some(bases) = &mut new_bases {
1190 bases.push(base.clone());
1191 }
1192 continue;
1193 }
1194 };
1195 let entries: PyTupleRef = entries
1196 .downcast()
1197 .map_err(|_| vm.new_type_error("__mro_entries__ must return a tuple"))?;
1198 let new_bases = new_bases.get_or_insert_with(|| bases[..i].to_vec());
1199 new_bases.extend_from_slice(&entries);
1200 }
1201
1202 let new_bases = new_bases.map(|v| PyTuple::new_ref(v, &vm.ctx));
1203 let (orig_bases, bases) = match new_bases {
1204 Some(new) => (Some(bases), new),
1205 None => (None, bases),
1206 };
1207
1208 // Use downcast_exact to keep ref to old object on error.
1209 let metaclass = kwargs
1210 .pop_kwarg("metaclass")
1211 .map(|metaclass| {
1212 metaclass
1213 .downcast_exact::<PyType>(vm)
1214 .map(|m| m.into_pyref())
1215 })
1216 .unwrap_or_else(|| {
1217 // if there are no bases, use type; else get the type of the first base
1218 Ok(if bases.is_empty() {
1219 vm.ctx.types.type_type.to_owned()
1220 } else {
1221 bases.first().unwrap().class().to_owned()
1222 })

Callers

nothing calls this directly

Calls 15

newFunction · 0.85
fast_isinstanceMethod · 0.80
get_attribute_optMethod · 0.80
downcastMethod · 0.80
to_vecMethod · 0.80
pop_kwargMethod · 0.80
into_pyrefMethod · 0.80
fast_issubclassMethod · 0.80
new_dictMethod · 0.80
intern_strMethod · 0.80
invoke_with_localsMethod · 0.80
okMethod · 0.80

Tested by

no test coverage detected