diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index 978cc93053..8f1f8764b1 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -152,8 +152,6 @@ def f(): for _ in range(1025): self.assertTrue(f()) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_metaclass_swap(self): class OldMetaclass(type): @property @@ -411,8 +409,6 @@ def f(): for _ in range(1025): self.assertTrue(f()) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_metaclass_swap(self): class OldMetaclass(type): @property diff --git a/derive-impl/src/pyclass.rs b/derive-impl/src/pyclass.rs index 8f688b366a..a8371d889b 100644 --- a/derive-impl/src/pyclass.rs +++ b/derive-impl/src/pyclass.rs @@ -1497,6 +1497,9 @@ fn extract_impl_attrs(attr: AttributeArgs, item: &Ident) -> Result PyResult<()> { - if instance.payload_is::() { + 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::() + .map(|t| t.slots.flags.has_feature(PyTypeFlags::IMMUTABLETYPE)) + .unwrap_or(false); + if both_mutable || both_module { match value.downcast::() { Ok(cls) => { // FIXME(#1979) cls instances might have a payload @@ -298,7 +310,8 @@ impl PyBaseObject { } } else { Err(vm.new_type_error( - "__class__ assignment only supported for types without a payload".to_owned(), + "__class__ assignment only supported for mutable types or ModuleType subclasses" + .to_owned(), )) } }