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

Method extend_class

crates/vm/src/class.rs:134–207  ·  view source on GitHub ↗
(ctx: &'static Context, class: &'static Py<PyType>)

Source from the content-addressed store, hash-verified

132 const TP_FLAGS: PyTypeFlags = PyTypeFlags::DEFAULT;
133
134 fn extend_class(ctx: &'static Context, class: &'static Py<PyType>)
135 where
136 Self: Sized,
137 {
138 #[cfg(debug_assertions)]
139 {
140 assert!(class.slots.flags.is_created_with_flags());
141 }
142
143 let _ = ctx.intern_str(Self::NAME); // intern type name
144
145 if Self::TP_FLAGS.has_feature(PyTypeFlags::HAS_DICT) {
146 let __dict__ = identifier!(ctx, __dict__);
147 class.set_attr(
148 __dict__,
149 ctx.new_static_getset(
150 "__dict__",
151 class,
152 crate::builtins::object::object_get_dict,
153 crate::builtins::object::object_set_dict,
154 )
155 .into(),
156 );
157 }
158 Self::impl_extend_class(ctx, class);
159 if let Some(doc) = Self::DOC {
160 // Only set __doc__ if it doesn't already exist (e.g., as a member descriptor)
161 // This matches CPython's behavior in type_dict_set_doc
162 let doc_attr_name = identifier!(ctx, __doc__);
163 if class.attributes.read().get(doc_attr_name).is_none() {
164 class.set_attr(doc_attr_name, ctx.new_str(doc).into());
165 }
166 }
167 if let Some(module_name) = Self::MODULE_NAME {
168 let module_key = identifier!(ctx, __module__);
169 // Don't overwrite a getset descriptor for __module__ (e.g. TypeAliasType
170 // has an instance-level __module__ getset that should not be replaced)
171 let has_getset = class
172 .attributes
173 .read()
174 .get(module_key)
175 .is_some_and(|v| v.downcastable::<crate::builtins::PyGetSet>());
176 if !has_getset {
177 class.set_attr(module_key, ctx.new_str(module_name).into());
178 }
179 }
180
181 // Don't add __new__ attribute if slot_new is inherited from object
182 // (Python doesn't add __new__ to __dict__ for inherited slots)
183 // Exception: object itself should have __new__ in its dict
184 if let Some(slot_new) = class.slots.new.load() {
185 let object_new = ctx.types.object_type.slots.new.load();
186 let is_object_itself = core::ptr::eq(class, ctx.types.object_type);
187 let is_inherited_from_object = !is_object_itself
188 && object_new.is_some_and(|obj_new| slot_new as usize == obj_new as usize);
189
190 if !is_inherited_from_object {
191 let bound_new =

Callers

nothing calls this directly

Calls 15

add_operatorsFunction · 0.85
intern_strMethod · 0.80
has_featureMethod · 0.80
new_static_getsetMethod · 0.80
build_bound_methodMethod · 0.80
inherit_slotsMethod · 0.80
extend_methodsMethod · 0.80
eqFunction · 0.50
set_attrMethod · 0.45
is_noneMethod · 0.45
getMethod · 0.45
readMethod · 0.45

Tested by

no test coverage detected