8000 Allow update `__class__` for module subclasses · RustPython/RustPython@802e045 · GitHub
[go: up one dir, main page]

Skip to content

Commit 802e045

Browse files
committed
Allow update __class__ for module subclasses
1 parent 8c7b811 commit 802e045

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

vm/src/builtins/object.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::{PyDictRef, PyList, PyStr, PyStrRef, PyType, PyTypeRef};
22
use crate::common::hash::PyHash;
3+
use crate::types::PyTypeFlags;
34
use crate::{
45
class::PyClassImpl,
56
function::{Either, FuncArgs, PyArithmeticValue, PyComparisonValue, PySetterValue},
@@ -281,7 +282,19 @@ impl PyBaseObject {
281282

282283
#[pygetset(name = "__class__", setter)]
283284
fn set_class(instance: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
284-
if instance.payload_is::<PyBaseObject>() {
285+
let both_module = instance.class().fast_issubclass(vm.ctx.types.module_type)
286+
&& value.class().fast_issubclass(vm.ctx.types.module_type);
287+
let both_mutable = !instance
288+
.class()
289+
.slots
290+
.flags
291+
.has_feature(PyTypeFlags::IMMUTABLETYPE)
292+
&& !value
293+
.class()
294+
.slots
295+
.flags
296+
.has_feature(PyTypeFlags::IMMUTABLETYPE);
297+
if both_mutable || both_module {
285298
match value.downcast::<PyType>() {
286299
Ok(cls) => {
287300
// FIXME(#1979) cls instances might have a payload
@@ -298,7 +311,8 @@ impl PyBaseObject {
298311
}
299312
} else {
300313
Err(vm.new_type_error(
301-
"__class__ assignment only supported for types without a payload".to_owned(),
314+
"__class__ assignment only supported for mutable types or ModuleType subclasses"
315+
.to_owned(),
302316
))
303317
}
304318
}

0 commit comments

Comments
 (0)
0