@@ -139,7 +139,7 @@ impl Default for PyTypeFlags {
139
139
140
140
pub ( crate ) type GenericMethod = fn ( & PyObject , FuncArgs , & VirtualMachine ) -> PyResult ;
141
141
pub ( crate ) type AsMappingFunc = fn ( & PyObject , & VirtualMachine ) -> & ' static PyMappingMethods ;
142
- pub ( crate ) type AsNumberFunc = fn ( & PyObject , & VirtualMachine ) -> Cow < ' static , PyNumberMethods > ;
142
+ pub ( crate ) type AsNumberFunc = fn ( & PyObject , & VirtualMachine ) -> & ' static PyNumberMethods ;
143
143
pub ( crate ) type HashFunc = fn ( & PyObject , & VirtualMachine ) -> PyResult < PyHash > ;
144
144
// CallFunc = GenericMethod
145
145
pub ( crate ) type GetattroFunc = fn ( & PyObject , PyStrRef , & VirtualMachine ) -> PyResult ;
@@ -340,43 +340,65 @@ fn as_sequence_generic(zelf: &PyObject, vm: &VirtualMachine) -> &'static PySeque
340
340
static_as_sequence_generic ( has_length, has_ass_item)
341
341
}
342
342
343
- fn as_number_wrapper ( zelf : & PyObject , vm : & VirtualMachine ) -> Cow < ' static , PyNumberMethods > {
344
- Cow :: Owned ( PyNumberMethods {
345
- int : then_some_closure ! (
346
- zelf. class( ) . has_attr( identifier!( vm, __int__) ) ,
347
- |num, vm| {
348
- let ret =
349
- vm. call_special_method( num. obj. to_owned( ) , identifier!( vm, __int__) , ( ) ) ?;
350
- ret. downcast:: <PyInt >( ) . map_err( |obj| {
351
- vm. new_type_error( format!( "__int__ returned non-int (type {})" , obj. class( ) ) )
352
- } )
353
- }
354
- ) ,
355
- float : then_some_closure ! (
356
- zelf. class( ) . has_attr( identifier!( vm, __float__) ) ,
357
- |num, vm| {
358
- let ret =
359
- vm. call_special_method( num. obj. to_owned( ) , identifier!( vm, __float__) , ( ) ) ?;
360
- ret. downcast:: <PyFloat >( ) . map_err( |obj| {
361
- vm. new_type_error( format!(
362
- "__float__ returned non-float (type {})" ,
363
- obj. class( )
364
- ) )
365
- } )
366
- }
367
- ) ,
368
- index : then_some_closure ! (
369
- zelf. class( ) . has_attr( identifier!( vm, __index__) ) ,
370
- |num, vm| {
371
- let ret =
372
- vm. call_special_method( num. obj. to_owned( ) , identifier!( vm, __index__) , ( ) ) ?;
373
- ret. downcast:: <PyInt >( ) . map_err( |obj| {
374
- vm. new_type_error( format!( "__index__ returned non-int (type {})" , obj. class( ) ) )
375
- } )
376
- }
377
- ) ,
378
- ..PyNumberMethods :: NOT_IMPLEMENTED
379
- } )
343
+ pub ( crate ) fn static_as_number_generic (
344
+ has_int : bool ,
345
+ has_float : bool ,
346
+ has_index : bool ,
347
+ ) -> & ' static PyNumberMethods {
348
+ static METHODS : & [ PyNumberMethods ] = & [
349
+ new_generic ( false , false , false ) ,
350
+ new_generic ( true , false , false ) ,
351
+ new_generic ( false , true , false ) ,
352
+ new_generic ( true , true , false ) ,
353
+ new_generic ( false , false , true ) ,
354
+ new_generic ( true , false , true ) ,
355
+ new_generic ( false , true , true ) ,
356
+ new_generic ( true , true , true ) ,
357
+ ] ;
358
+
359
+ fn int ( num : & PyNumber , vm : & VirtualMachine ) -> PyResult < PyRef < PyInt > > {
360
+ let ret = vm. call_special_method ( num. obj . to_owned ( ) , identifier ! ( vm, __int__) , ( ) ) ?;
361
+ ret. downcast :: < PyInt > ( ) . map_err ( |obj| {
362
+ vm. new_type_error ( format ! ( "__int__ returned non-int (type {})" , obj. class( ) ) )
363
+ } )
364
+ }
365
+ fn float ( num : & PyNumber , vm : & VirtualMachine ) -> PyResult < PyRef < PyFloat > > {
366
+ let ret = vm. call_special_method ( num. obj . to_owned ( ) , identifier ! ( vm, __float__) , ( ) ) ?;
367
+ ret. downcast :: < PyFloat > ( ) . map_err ( |obj| {
368
+ vm. new_type_error ( format ! (
369
+ "__float__ returned non-float (type {})" ,
370
+ obj. class( )
371
+ ) )
372
+ } )
373
+ }
374
+ fn index ( num : & PyNumber , vm : & VirtualMachine ) -> PyResult < PyRef < PyInt > > {
375
+ let ret = vm. call_special_method ( num. obj . to_owned ( ) , identifier ! ( vm, __index__) , ( ) ) ?;
376
+ ret. downcast :: < PyInt > ( ) . map_err ( |obj| {
377
+ vm. new_type_error ( format ! ( "__index__ returned non-int (type {})" , obj. class( ) ) )
378
+ } )
379
+ }
380
+
381
+ const fn new_generic ( has_int : bool , has_float : bool , has_index : bool ) -> PyNumberMethods {
382
+ PyNumberMethods {
383
+ int : if has_int { Some ( int) } else { None } ,
384
+ float : if has_float { Some ( float) } else { None } ,
385
+ index : if has_index { Some ( index) } else { None } ,
386
+ ..PyNumberMethods :: NOT_IMPLEMENTED
387
+ }
388
+ }
389
+
390
+ let key = bool_int ( has_int) | ( bool_int ( has_float) << 1 ) | ( bool_int ( has_index) << 2 ) ;
391
+
392
+ & METHODS [ key]
393
+ }
394
+
395
+ fn as_number_wrapper ( zelf : & PyObject , vm : & VirtualMachine ) -> & ' static PyNumberMethods {
396
+ let ( has_int, has_float, has_index) = (
397
+ zelf. class ( ) . has_attr ( identifier ! ( vm, __int__) ) ,
398
+ zelf. class ( ) . has_attr ( identifier ! ( vm, __float__) ) ,
399
+ zelf. class ( ) . has_attr ( identifier ! ( vm, __index__) ) ,
400
+ ) ;
401
+ static_as_number_generic ( has_int, has_float, has_index)
380
402
}
381
403
382
404
fn hash_wrapper ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < PyHash > {
@@ -1041,8 +1063,8 @@ pub trait AsNumber: PyPayload {
1041
1063
1042
1064
#[ inline]
1043
1065
#[ pyslot]
1044
- fn as_number ( _zelf : & PyObject , _vm : & VirtualMachine ) -> Cow < ' static , PyNumberMethods > {
1045
- Cow :: Borrowed ( & Self :: AS_NUMBER )
1066
+ fn as_number ( _zelf : & PyObject , _vm : & VirtualMachine ) -> & ' static PyNumberMethods {
1067
+ & Self :: AS_NUMBER
1046
1068
}
1047
1069
1048
1070
fn number_downcast < ' a > ( number : & ' a PyNumber ) -> & ' a Py < Self > {
0 commit comments