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

Method set___class__

crates/vm/src/builtins/object.rs:446–512  ·  view source on GitHub ↗
(
        instance: PyObjectRef,
        value: PyObjectRef,
        vm: &VirtualMachine,
    )

Source from the content-addressed store, hash-verified

444
445 #[pygetset(setter)]
446 fn set___class__(
447 instance: PyObjectRef,
448 value: PyObjectRef,
449 vm: &VirtualMachine,
450 ) -> PyResult<()> {
451 match value.downcast::<PyType>() {
452 Ok(cls) => {
453 let current_cls = instance.class();
454 let both_module = current_cls.fast_issubclass(vm.ctx.types.module_type)
455 && cls.fast_issubclass(vm.ctx.types.module_type);
456 let both_mutable = !current_cls
457 .slots
458 .flags
459 .has_feature(PyTypeFlags::IMMUTABLETYPE)
460 && !cls.slots.flags.has_feature(PyTypeFlags::IMMUTABLETYPE);
461 // FIXME(#1979) cls instances might have a payload
462 if both_mutable || both_module {
463 let has_dict =
464 |typ: &Py<PyType>| typ.slots.flags.has_feature(PyTypeFlags::HAS_DICT);
465 let has_weakref =
466 |typ: &Py<PyType>| typ.slots.flags.has_feature(PyTypeFlags::HAS_WEAKREF);
467 // Compare slots tuples
468 let slots_equal = match (
469 current_cls
470 .heaptype_ext
471 .as_ref()
472 .and_then(|e| e.slots.as_ref()),
473 cls.heaptype_ext.as_ref().and_then(|e| e.slots.as_ref()),
474 ) {
475 (Some(a), Some(b)) => {
476 a.len() == b.len()
477 && a.iter()
478 .zip(b.iter())
479 .all(|(x, y)| x.as_wtf8() == y.as_wtf8())
480 }
481 (None, None) => true,
482 _ => false,
483 };
484 if current_cls.slots.basicsize != cls.slots.basicsize
485 || !slots_equal
486 || has_dict(current_cls) != has_dict(&cls)
487 || has_weakref(current_cls) != has_weakref(&cls)
488 || current_cls.slots.member_count != cls.slots.member_count
489 {
490 return Err(vm.new_type_error(format!(
491 "__class__ assignment: '{}' object layout differs from '{}'",
492 cls.name(),
493 current_cls.name()
494 )));
495 }
496 instance.set_class(cls, vm);
497 Ok(())
498 } else {
499 Err(vm.new_type_error(
500 "__class__ assignment only supported for mutable types or ModuleType subclasses",
501 ))
502 }
503 }

Callers

nothing calls this directly

Calls 11

fast_issubclassMethod · 0.80
has_featureMethod · 0.80
allMethod · 0.80
set_classMethod · 0.80
ErrClass · 0.50
classMethod · 0.45
as_refMethod · 0.45
lenMethod · 0.45
iterMethod · 0.45
as_wtf8Method · 0.45
nameMethod · 0.45

Tested by

no test coverage detected