diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 606cd6b27..0ed7081b4 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -295,6 +295,12 @@ fn extract_impl_items(mut items: Vec) -> Result Result<(TokenStream2, TokenStream2), Diagnostic> { let mut withs = Vec::new(); let mut flags = vec![quote! { ::rustpython_vm::slots::PyTpFlags::DEFAULT.bits() }]; + #[cfg(debug_assertions)] + { + flags.push(quote! { + | ::rustpython_vm::slots::PyTpFlags::_CREATED_WITH_FLAGS.bits() + }); + } for attr in attr { match attr { diff --git a/vm/src/obj/objmodule.rs b/vm/src/obj/objmodule.rs index 5a000e661..2cf988311 100644 --- a/vm/src/obj/objmodule.rs +++ b/vm/src/obj/objmodule.rs @@ -55,6 +55,9 @@ impl PyModuleRef { doc: OptionalOption, vm: &VirtualMachine, ) -> PyResult<()> { + debug_assert!(crate::pyobject::TypeProtocol::lease_class(self.as_object()) + .flags + .has_feature(crate::slots::PyTpFlags::HAS_DICT)); init_module_dict( vm, &self.as_object().dict().unwrap(), diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index d9b69a601..53e5f7a89 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -1446,6 +1446,7 @@ pub trait PyClassImpl: PyClassDef { fn impl_extend_class(ctx: &PyContext, class: &PyClassRef); fn extend_class(ctx: &PyContext, class: &PyClassRef) { + debug_assert!(class.flags.is_created_with_flags()); if Self::TP_FLAGS.has_feature(PyTpFlags::HAS_DICT) { class.set_str_attr( "__dict__", @@ -1472,6 +1473,10 @@ pub trait PyClassImpl: PyClassDef { Self::extend_class(ctx, &py_class); py_class } + + fn create_bare_type(type_type: &PyClassRef, base: &PyClassRef) -> PyClassRef { + create_type_with_flags(Self::NAME, type_type, base, Self::TP_FLAGS) + } } pub trait PyStructSequenceImpl: PyClassImpl { diff --git a/vm/src/slots.rs b/vm/src/slots.rs index 586f6c2e6..adecc7067 100644 --- a/vm/src/slots.rs +++ b/vm/src/slots.rs @@ -7,6 +7,9 @@ bitflags! { const HEAPTYPE = 1 << 9; const BASETYPE = 1 << 10; const HAS_DICT = 1 << 40; + + #[cfg(debug_assertions)] + const _CREATED_WITH_FLAGS = 1 << 63; } } @@ -17,6 +20,14 @@ impl PyTpFlags { pub fn has_feature(self, flag: Self) -> bool { self.contains(flag) } + + pub fn is_created_with_flags(self) -> bool { + if cfg!(debug_assertions) { + self.contains(Self::_CREATED_WITH_FLAGS) + } else { + true + } + } } impl Default for PyTpFlags {