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

Method set_bases

crates/vm/src/builtins/type.rs:1313–1371  ·  view source on GitHub ↗
(zelf: &Py<Self>, bases: Vec<PyTypeRef>, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

1311 }
1312 #[pygetset(setter, name = "__bases__")]
1313 fn set_bases(zelf: &Py<Self>, bases: Vec<PyTypeRef>, vm: &VirtualMachine) -> PyResult<()> {
1314 // TODO: Assigning to __bases__ is only used in typing.NamedTupleMeta.__new__
1315 // Rather than correctly re-initializing the class, we are skipping a few steps for now
1316 if zelf.slots.flags.has_feature(PyTypeFlags::IMMUTABLETYPE) {
1317 return Err(vm.new_type_error(format!(
1318 "cannot set '__bases__' attribute of immutable type '{}'",
1319 zelf.name()
1320 )));
1321 }
1322 if bases.is_empty() {
1323 return Err(vm.new_type_error(format!(
1324 "can only assign non-empty tuple to %s.__bases__, not {}",
1325 zelf.name()
1326 )));
1327 }
1328
1329 // TODO: check for mro cycles
1330
1331 // TODO: Remove this class from all subclass lists
1332 // for base in self.bases.read().iter() {
1333 // let subclasses = base.subclasses.write();
1334 // // TODO: how to uniquely identify the subclasses to remove?
1335 // }
1336
1337 *zelf.bases.write() = bases;
1338 // Recursively update the mros of this class and all subclasses
1339 fn update_mro_recursively(cls: &PyType, vm: &VirtualMachine) -> PyResult<()> {
1340 let mut mro =
1341 PyType::resolve_mro(&cls.bases.read()).map_err(|msg| vm.new_type_error(msg))?;
1342 // Preserve self (mro[0]) when updating MRO
1343 mro.insert(0, cls.mro.read()[0].to_owned());
1344 *cls.mro.write() = mro;
1345 for subclass in cls.subclasses.write().iter() {
1346 let subclass = subclass.upgrade().unwrap();
1347 let subclass: &Py<PyType> = subclass.downcast_ref().unwrap();
1348 update_mro_recursively(subclass, vm)?;
1349 }
1350 Ok(())
1351 }
1352 update_mro_recursively(zelf, vm)?;
1353
1354 // Invalidate inline caches
1355 zelf.modified();
1356
1357 // TODO: do any old slots need to be cleaned up first?
1358 zelf.init_slots(&vm.ctx);
1359
1360 // Register this type as a subclass of its new bases
1361 let weakref_type = super::PyWeak::static_type();
1362 for base in zelf.bases.read().iter() {
1363 base.subclasses.write().push(
1364 zelf.as_object()
1365 .downgrade_with_weakref_typ_opt(None, weakref_type.to_owned())
1366 .unwrap(),
1367 );
1368 }
1369
1370 Ok(())

Callers

nothing calls this directly

Calls 13

has_featureMethod · 0.80
init_slotsMethod · 0.80
ErrClass · 0.50
is_emptyMethod · 0.45
writeMethod · 0.45
modifiedMethod · 0.45
iterMethod · 0.45
readMethod · 0.45
pushMethod · 0.45
unwrapMethod · 0.45
as_objectMethod · 0.45

Tested by

no test coverage detected