@@ -6,10 +6,13 @@ use crate::{
66 common:: hash:: PyHash ,
77 convert:: { ToPyObject , ToPyResult } ,
88 function:: { FuncArgs , PyMethodDef , PyMethodFlags , PySetterValue } ,
9+ protocol:: { PyNumberBinaryFunc , PyNumberTernaryFunc , PyNumberUnaryFunc } ,
910 types:: {
1011 Callable , Comparable , DelFunc , DescrGetFunc , DescrSetFunc , GenericMethod , GetDescriptor ,
11- GetattroFunc , HashFunc , Hashable , InitFunc , IterFunc , IterNextFunc , PyComparisonOp ,
12- Representable , RichCompareFunc , SetattroFunc , StringifyFunc ,
12+ GetattroFunc , HashFunc , Hashable , InitFunc , IterFunc , IterNextFunc , MapAssSubscriptFunc ,
13+ MapLenFunc , MapSubscriptFunc , PyComparisonOp , Representable , RichCompareFunc ,
14+ SeqAssItemFunc , SeqConcatFunc , SeqContainsFunc , SeqItemFunc , SeqLenFunc , SeqRepeatFunc ,
15+ SetattroFunc , StringifyFunc ,
1316 } ,
1417} ;
1518use rustpython_common:: lock:: PyRwLock ;
@@ -394,7 +397,6 @@ pub fn init(ctx: &Context) {
394397
395398// PyWrapper - wrapper_descriptor
396399
397- /// Type-erased slot function - mirrors CPython's void* d_wrapped
398400/// Each variant knows how to call the wrapped function with proper types
399401#[ derive( Clone , Copy ) ]
400402pub enum SlotFunc {
@@ -420,6 +422,25 @@ pub enum SlotFunc {
420422 DescrGet ( DescrGetFunc ) ,
421423 DescrSet ( DescrSetFunc ) , // __set__
422424 DescrDel ( DescrSetFunc ) , // __delete__ (same func type, different PySetterValue)
425+
426+ // Sequence sub-slots (sq_*)
427+ SeqLength ( SeqLenFunc ) ,
428+ SeqConcat ( SeqConcatFunc ) ,
429+ SeqRepeat ( SeqRepeatFunc ) ,
430+ SeqItem ( SeqItemFunc ) ,
431+ SeqAssItem ( SeqAssItemFunc ) ,
432+ SeqContains ( SeqContainsFunc ) ,
433+
434+ // Mapping sub-slots (mp_*)
435+ MapLength ( MapLenFunc ) ,
436+ MapSubscript ( MapSubscriptFunc ) ,
437+ MapAssSubscript ( MapAssSubscriptFunc ) ,
438+
439+ // Number sub-slots (nb_*) - grouped by signature
440+ NumBoolean ( PyNumberUnaryFunc < bool > ) , // __bool__
441+ NumUnary ( PyNumberUnaryFunc ) , // __int__, __float__, __index__
442+ NumBinary ( PyNumberBinaryFunc ) , // __add__, __sub__, __mul__, etc.
443+ NumTernary ( PyNumberTernaryFunc ) , // __pow__
423444}
424445
425446impl std:: fmt:: Debug for SlotFunc {
@@ -440,6 +461,22 @@ impl std::fmt::Debug for SlotFunc {
440461 SlotFunc :: DescrGet ( _) => write ! ( f, "SlotFunc::DescrGet(...)" ) ,
441462 SlotFunc :: DescrSet ( _) => write ! ( f, "SlotFunc::DescrSet(...)" ) ,
442463 SlotFunc :: DescrDel ( _) => write ! ( f, "SlotFunc::DescrDel(...)" ) ,
464+ // Sequence sub-slots
465+ SlotFunc :: SeqLength ( _) => write ! ( f, "SlotFunc::SeqLength(...)" ) ,
466+ SlotFunc :: SeqConcat ( _) => write ! ( f, "SlotFunc::SeqConcat(...)" ) ,
467+ SlotFunc :: SeqRepeat ( _) => write ! ( f, "SlotFunc::SeqRepeat(...)" ) ,
468+ SlotFunc :: SeqItem ( _) => write ! ( f, "SlotFunc::SeqItem(...)" ) ,
469+ SlotFunc :: SeqAssItem ( _) => write ! ( f, "SlotFunc::SeqAssItem(...)" ) ,
470+ SlotFunc :: SeqContains ( _) => write ! ( f, "SlotFunc::SeqContains(...)" ) ,
471+ // Mapping sub-slots
472+ SlotFunc :: MapLength ( _) => write ! ( f, "SlotFunc::MapLength(...)" ) ,
473+ SlotFunc :: MapSubscript ( _) => write ! ( f, "SlotFunc::MapSubscript(...)" ) ,
474+ SlotFunc :: MapAssSubscript ( _) => write ! ( f, "SlotFunc::MapAssSubscript(...)" ) ,
475+ // Number sub-slots
476+ SlotFunc :: NumBoolean ( _) => write ! ( f, "SlotFunc::NumBoolean(...)" ) ,
477+ SlotFunc :: NumUnary ( _) => write ! ( f, "SlotFunc::NumUnary(...)" ) ,
478+ SlotFunc :: NumBinary ( _) => write ! ( f, "SlotFunc::NumBinary(...)" ) ,
479+ SlotFunc :: NumTernary ( _) => write ! ( f, "SlotFunc::NumTernary(...)" ) ,
443480 }
444481 }
445482}
@@ -541,6 +578,71 @@ impl SlotFunc {
541578 func ( & obj, instance, PySetterValue :: Delete , vm) ?;
542579 Ok ( vm. ctx . none ( ) )
543580 }
581+ // Sequence sub-slots
582+ SlotFunc :: SeqLength ( func) => {
583+ args. bind :: < ( ) > ( vm) ?;
584+ let len = func ( obj. sequence_unchecked ( ) , vm) ?;
585+ Ok ( vm. ctx . new_int ( len) . into ( ) )
586+ }
587+ SlotFunc :: SeqConcat ( func) => {
588+ let ( other, ) : ( PyObjectRef , ) = args. bind ( vm) ?;
589+ func ( obj. sequence_unchecked ( ) , & other, vm)
590+ }
591+ SlotFunc :: SeqRepeat ( func) => {
592+ let ( n, ) : ( isize , ) = args. bind ( vm) ?;
593+ func ( obj. sequence_unchecked ( ) , n, vm)
594+ }
595+ SlotFunc :: SeqItem ( func) => {
596+ let ( index, ) : ( isize , ) = args. bind ( vm) ?;
597+ func ( obj. sequence_unchecked ( ) , index, vm)
598+ }
599+ SlotFunc :: SeqAssItem ( func) => {
600+ let ( index, value) : ( isize , crate :: function:: OptionalArg < PyObjectRef > ) =
601+ args. bind ( vm) ?;
602+ func ( obj. sequence_unchecked ( ) , index, value. into_option ( ) , vm) ?;
603+ Ok ( vm. ctx . none ( ) )
604+ }
605+ SlotFunc :: SeqContains ( func) => {
606+ let ( item, ) : ( PyObjectRef , ) = args. bind ( vm) ?;
607+ let result = func ( obj. sequence_unchecked ( ) , & item, vm) ?;
608+ Ok ( vm. ctx . new_bool ( result) . into ( ) )
609+ }
610+ // Mapping sub-slots
611+ SlotFunc :: MapLength ( func) => {
612+ args. bind :: < ( ) > ( vm) ?;
613+ let len = func ( obj. mapping_unchecked ( ) , vm) ?;
614+ Ok ( vm. ctx . new_int ( len) . into ( ) )
615+ }
616+ SlotFunc :: MapSubscript ( func) => {
617+ let ( key, ) : ( PyObjectRef , ) = args. bind ( vm) ?;
618+ func ( obj. mapping_unchecked ( ) , & key, vm)
619+ }
620+ SlotFunc :: MapAssSubscript ( func) => {
621+ let ( key, value) : ( PyObjectRef , crate :: function:: OptionalArg < PyObjectRef > ) =
622+ args. bind ( vm) ?;
623+ func ( obj. mapping_unchecked ( ) , & key, value. into_option ( ) , vm) ?;
624+ Ok ( vm. ctx . none ( ) )
625+ }
626+ // Number sub-slots
627+ SlotFunc :: NumBoolean ( func) => {
628+ args. bind :: < ( ) > ( vm) ?;
629+ let result = func ( obj. number ( ) , vm) ?;
630+ Ok ( vm. ctx . new_bool ( result) . into ( ) )
631+ }
632+ SlotFunc :: NumUnary ( func) => {
633+ args. bind :: < ( ) > ( vm) ?;
634+ func ( obj. number ( ) , vm)
635+ }
636+ SlotFunc :: NumBinary ( func) => {
637+ let ( other, ) : ( PyObjectRef , ) = args. bind ( vm) ?;
638+ func ( & obj, & other, vm)
639+ }
640+ SlotFunc :: NumTernary ( func) => {
641+ let ( y, z) : ( PyObjectRef , crate :: function:: OptionalArg < PyObjectRef > ) =
642+ args. bind ( vm) ?;
643+ let z = z. unwrap_or_else ( || vm. ctx . none ( ) ) ;
644+ func ( & obj, & y, & z, vm)
645+ }
544646 }
545647 }
546648}
0 commit comments