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

Method setattro

crates/vm/src/builtins/type.rs:2459–2507  ·  view source on GitHub ↗
(
        zelf: &Py<Self>,
        attr_name: &Py<PyStr>,
        value: PySetterValue,
        vm: &VirtualMachine,
    )

Source from the content-addressed store, hash-verified

2457
2458impl SetAttr for PyType {
2459 fn setattro(
2460 zelf: &Py<Self>,
2461 attr_name: &Py<PyStr>,
2462 value: PySetterValue,
2463 vm: &VirtualMachine,
2464 ) -> PyResult<()> {
2465 let attr_name = vm.ctx.intern_str(attr_name.as_wtf8());
2466 if zelf.slots.flags.has_feature(PyTypeFlags::IMMUTABLETYPE) {
2467 return Err(vm.new_type_error(format!(
2468 "cannot set '{}' attribute of immutable type '{}'",
2469 attr_name,
2470 zelf.slot_name()
2471 )));
2472 }
2473 if let Some(attr) = zelf.get_class_attr(attr_name) {
2474 let descr_set = attr.class().slots.descr_set.load();
2475 if let Some(descriptor) = descr_set {
2476 return descriptor(&attr, zelf.to_owned().into(), value, vm);
2477 }
2478 }
2479 let assign = value.is_assign();
2480
2481 // Invalidate inline caches before modifying attributes.
2482 // This ensures other threads see the version invalidation before
2483 // any attribute changes, preventing use-after-free of cached descriptors.
2484 zelf.modified();
2485
2486 if let PySetterValue::Assign(value) = value {
2487 zelf.attributes.write().insert(attr_name, value);
2488 } else {
2489 let prev_value = zelf.attributes.write().shift_remove(attr_name); // TODO: swap_remove applicable?
2490 if prev_value.is_none() {
2491 return Err(vm.new_attribute_error(format!(
2492 "type object '{}' has no attribute '{}'",
2493 zelf.name(),
2494 attr_name,
2495 )));
2496 }
2497 }
2498
2499 if attr_name.as_wtf8().starts_with("__") && attr_name.as_wtf8().ends_with("__") {
2500 if assign {
2501 zelf.update_slot::<true>(attr_name, &vm.ctx);
2502 } else {
2503 zelf.update_slot::<false>(attr_name, &vm.ctx);
2504 }
2505 }
2506 Ok(())
2507 }
2508}
2509
2510impl Callable for PyType {

Callers

nothing calls this directly

Calls 15

descriptorClass · 0.85
intern_strMethod · 0.80
has_featureMethod · 0.80
get_class_attrMethod · 0.80
starts_withMethod · 0.80
ends_withMethod · 0.80
ErrClass · 0.50
as_wtf8Method · 0.45
loadMethod · 0.45
classMethod · 0.45
to_ownedMethod · 0.45
modifiedMethod · 0.45

Tested by

no test coverage detected