8000 Check `value` is `PyType` first by moreal · Pull Request #5227 · RustPython/RustPython · GitHub
[go: up one dir, main page]

Skip to content

Check value is PyType first #5227

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 15, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Check downcast to type first
  • Loading branch information
moreal committed Apr 14, 2024
commit 40f91730f6856a7d66d64ef1a6e48a4c5c82cd7e
51 changes: 24 additions & 27 deletions vm/src/builtins/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,37 +282,34 @@ impl PyBaseObject {

#[pygetset(name = "__class__", setter)]
fn set_class(instance: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let both_module = instance.class().fast_issubclass(vm.ctx.types.module_type)
&& value.class().fast_issubclass(vm.ctx.types.module_type);
let both_mutable = !instance
.class()
.slots
.flags
.has_feature(PyTypeFlags::IMMUTABLETYPE)
&& !value
.downcast_ref::<PyType>()
.map(|t| t.slots.flags.has_feature(PyTypeFlags::IMMUTABLETYPE))
.unwrap_or(false);
if both_mutable || both_module {
match value.downcast::<PyType>() {
Ok(cls) => {
// FIXME(#1979) cls instances might have a payload
match value.downcast::<PyType>() {
Ok(cls) => {
let both_module = instance.class().fast_issubclass(vm.ctx.types.module_type)
&& cls.fast_issubclass(vm.ctx.types.module_type);
let both_mutable = !instance
.class()
.slots
.flags
.has_feature(PyTypeFlags::IMMUTABLETYPE)
&& !cls.slots.flags.has_feature(PyTypeFlags::IMMUTABLETYPE);
// FIXME(#1979) cls instances might have a payload
if both_mutable || both_module {
instance.set_class(cls, vm);
Ok(())
}
Err(value) => {
let value_class = value.class();
let type_repr = &value_class.name();
Err(vm.new_type_error(format!(
"__class__ must be set to a class, not '{type_repr}' object"
)))
} else {
Err(vm.new_type_error(
"__class__ assignment only supported for mutable types or ModuleType subclasses"
.to_owned(),
))
}
}
} else {
Err(vm.new_type_error(
"__class__ assignment only supported for mutable types or ModuleType subclasses"
.to_owned(),
))
Err(value) => {
let value_class = value.class();
let type_repr = &value_class.name();
Err(vm.new_type_error(format!(
"__class__ must be set to a class, not '{type_repr}' object"
)))
}
}
}

Expand Down
0