@@ -139,52 +139,50 @@ pub trait PyClassImpl: PyClassDef {
139139 }
140140 }
141141
142- // Add __init__ slot wrapper if slot exists and not already in dict
143- if let Some ( init_func) = class. slots . init . load ( ) {
144- let init_name = identifier ! ( ctx, __init__) ;
145- if !class. attributes . read ( ) .contains_key ( init_name) {
146- let wrapper = PySlotWrapper {
147- typ : class,
148- name : ctx. intern_str ( "__init__" ) ,
149- wrapped : SlotFunc :: Init ( init_func) ,
150- doc : Some ( "Initialize self. See help(type(self)) for accurate signature." ) ,
151- } ;
152- class. set_attr ( init_name, wrapper. into_ref ( ctx) . into ( ) ) ;
153- }
154- }
155-
156- // Add __hash__ slot wrapper if slot exists and not already in dict
157- // Note: hash_not_implemented is handled separately (sets __hash__ = None)
158- if let Some ( hash_func) = class. slots . hash . load ( )
159- && hash_func as usize != hash_not_implemented as usize
160- {
161- let hash_name = identifier ! ( ctx, __hash__) ;
162- if !class. attributes . read ( ) . contains_key ( hash_name) {
163- let wrapper = PySlotWrapper {
164- typ : class,
165- name : ctx. intern_str ( "__hash__" ) ,
166- wrapped : SlotFunc :: Hash ( hash_func) ,
167- doc : Some ( "Return hash(self)." ) ,
168- } ;
169- class. set_attr ( hash_name, wrapper. into_ref ( ctx) . into ( ) ) ;
170- }
171- }
172-
173- if class. slots . hash . load ( ) . map_or ( 0 , |h| h as usize ) == hash_not_implemented as usize {
174- class. set_attr ( ctx. names . __hash__ , ctx. none . clone ( ) . into ( ) ) ;
142+ // Add slot wrappers for slots that exist and are not already in dict
143+ // This mirrors CPython's add_operators() in typeobject.c
144+ macro_rules! add_slot_wrapper {
145+ ( $slot: ident, $name: ident, $variant: ident, $doc: expr) => {
146+ if let Some ( func) = class. slots. $slot. load( ) {
147+ let attr_name = identifier!( ctx, $name) ;
148+ if !class. attributes. read( ) . contains_key( attr_name) {
149+ let wrapper = PySlotWrapper {
150+ typ: class,
151+ name: ctx. intern_str( stringify!( $name) ) ,
152+ wrapped: SlotFunc :: $variant( func) ,
153+ doc: Some ( $doc) ,
154+ } ;
155+ class. set_attr( attr_name, wrapper. into_ref(
6D3F
ctx) . into( ) ) ;
156+ }
157+ }
158+ } ;
175159 }
176160
177- // Add __repr__ slot wrapper if slot exists and not already in dict
178- if let Some ( repr_func) = class. slots . repr . load ( ) {
179- let repr_name = identifier ! ( ctx, __repr__) ;
180- if !class. attributes . read ( ) . contains_key ( repr_name) {
181- let wrapper = PySlotWrapper {
182- typ : class,
183- name : ctx. intern_str ( "__repr__" ) ,
184- wrapped : SlotFunc :: Repr ( repr_func) ,
185- doc : Some ( "Return repr(self)." ) ,
186- } ;
187- class. set_attr ( repr_name, wrapper. into_ref ( ctx) . into ( ) ) ;
161+ add_slot_wrapper ! (
162+ init,
9E81
163+ __init__,
164+ Init ,
165+ "Initialize self. See help(type(self)) for accurate signature."
166+ ) ;
167+ add_slot_wrapper ! ( repr, __repr__, Repr , "Return repr(self)." ) ;
168+ add_slot_wrapper ! ( iter, __iter__, Iter , "Implement iter(self)." ) ;
169+ add_slot_wrapper ! ( iternext, __next__, IterNext , "Implement next(self)." ) ;
170+
171+ // __hash__ needs special handling: hash_not_implemented sets __hash__ = None
172+ if let Some ( hash_func) = class. slots . hash . load ( ) {
173+ if hash_func as usize == hash_not_implemented as usize {
174+ class. set_attr ( ctx. names . __hash__ , ctx. none . clone ( ) . into ( ) ) ;
175+ } else {
176+ let hash_name = identifier ! ( ctx, __hash__) ;
177+ if !class. attributes . read ( ) . contains_key ( hash_name) {
178+ let wrapper = PySlotWrapper {
179+ typ : class,
180+ name : ctx. intern_str ( "__hash__" ) ,
181+ wrapped : SlotFunc :: Hash ( hash_func) ,
182+ doc : Some ( "Return hash(self)." ) ,
183+ } ;
184+ class. set_attr ( hash_name, wrapper. into_ref ( ctx) . into ( ) ) ;
185+ }
188186 }
189187 }
190188
0 commit comments