1- use super :: { int , PyBytes , PyInt , PyIntRef , PyStr , PyStrRef , PyTypeRef } ;
1+ use super :: { try_bigint_to_f64 , PyBytes , PyInt , PyIntRef , PyStr , PyStrRef , PyTypeRef } ;
22use crate :: common:: { float_ops, hash} ;
33use crate :: format:: FormatSpec ;
44use crate :: function:: { OptionalArg , OptionalOption } ;
@@ -51,29 +51,31 @@ impl From<f64> for PyFloat {
5151 }
5252}
5353
54- pub fn try_float_opt ( obj : & PyObjectRef , vm : & VirtualMachine ) -> PyResult < Option < f64 > > {
55- if let Some ( float) = obj. payload_if_exact :: < PyFloat > ( vm) {
56- return Ok ( Some ( float. value ) ) ;
57- }
58- if let Some ( method) = vm. get_method ( obj. clone ( ) , "__float__" ) {
59- let result = vm. invoke ( & method?, ( ) ) ?;
60- // TODO: returning strict subclasses of float in __float__ is deprecated
61- return match result. payload :: < PyFloat > ( ) {
62- Some ( float_obj) => Ok ( Some ( float_obj. value ) ) ,
63- None => Err ( vm. new_type_error ( format ! (
64- "__float__ returned non-float (type '{}')" ,
65- result. class( ) . name( )
66- ) ) ) ,
67- } ;
68- }
69- if let Some ( r) = vm. to_index_opt ( obj. clone ( ) ) . transpose ( ) ? {
70- return Ok ( Some ( int:: to_float ( r. as_bigint ( ) , vm) ?) ) ;
54+ impl PyObjectRef {
55+ pub fn try_to_f64 ( & self , vm : & VirtualMachine ) -> PyResult < Option < f64 > > {
56+ if let Some ( float) = self . payload_if_exact :: < PyFloat > ( vm) {
57+ return Ok ( Some ( float. value ) ) ;
58+ }
59+ if let Some ( method) = vm. get_method ( self . clone ( ) , "__float__" ) {
60+ let result = vm. invoke ( & method?, ( ) ) ?;
61+ // TODO: returning strict subclasses of float in __float__ is deprecated
62+ return match result. payload :: < PyFloat > ( ) {
63+ Some ( float_obj) => Ok ( Some ( float_obj. value ) ) ,
64+ None => Err ( vm. new_type_error ( format ! (
65+ "__float__ returned non-float (type '{}')" ,
66+ result. class( ) . name( )
67+ ) ) ) ,
68+ } ;
69+ }
70+ if let Some ( r) = vm. to_index_opt ( self . clone ( ) ) . transpose ( ) ? {
71+ return Ok ( Some ( try_bigint_to_f64 ( r. as_bigint ( ) , vm) ?) ) ;
72+ }
73+ Ok ( None )
7174 }
72- Ok ( None )
7375}
7476
7577pub fn try_float ( obj : & PyObjectRef , vm : & VirtualMachine ) -> PyResult < f64 > {
76- try_float_opt ( obj, vm) ?. ok_or_else ( || {
78+ obj. try_to_f64 ( vm) ?. ok_or_else ( || {
7779 vm. new_type_error ( format ! ( "must be real number, not {}" , obj. class( ) . name( ) ) )
7880 } )
7981}
@@ -82,7 +84,7 @@ pub(crate) fn to_op_float(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<Op
8284 let v = if let Some ( float) = obj. payload_if_subclass :: < PyFloat > ( vm) {
8385 Some ( float. value )
8486 } else if let Some ( int) = obj. payload_if_subclass :: < PyInt > ( vm) {
85- Some ( int :: to_float ( int. as_bigint ( ) , vm) ?)
87+ Some ( try_bigint_to_f64 ( int. as_bigint ( ) , vm) ?)
8688 } else {
8789 None
8890 } ;
@@ -111,7 +113,7 @@ fn inner_mod(v1: f64, v2: f64, vm: &VirtualMachine) -> PyResult<f64> {
111113 . ok_or_else ( || vm. new_zero_division_error ( "float mod by zero" . to_owned ( ) ) )
112114}
113115
114- pub fn try_bigint ( value : f64 , vm : & VirtualMachine ) -> PyResult < BigInt > {
116+ pub fn try_to_bigint ( value : f64 , vm : & VirtualMachine ) -> PyResult < BigInt > {
115117 match value. to_bigint ( ) {
116118 Some ( int) => Ok ( int) ,
117119 None => {
@@ -171,7 +173,7 @@ impl SlotConstructor for PyFloat {
171173 val
172174 } ;
173175
174- if let Some ( f) = try_float_opt ( & val, vm) ? {
176+ if let Some ( f) = val. try_to_f64 ( vm) ? {
175177 f
176178 } else if let Some ( s) = val. payload_if_subclass :: < PyStr > ( vm) {
177179 float_ops:: parse_str ( s. as_str ( ) . trim ( ) ) . ok_or_else ( || {
@@ -379,17 +381,17 @@ impl PyFloat {
379381
380382 #[ pymethod( magic) ]
381383 fn trunc ( & self , vm : & VirtualMachine ) -> PyResult < BigInt > {
382- try_bigint ( self . value , vm)
384+ try_to_bigint ( self . value , vm)
383385 }
384386
385387 #[ pymethod( magic) ]
386388 fn floor ( & self , vm : & VirtualMachine ) -> PyResult < BigInt > {
387- try_bigint ( self . value . floor ( ) , vm)
389+ try_to_bigint ( self . value . floor ( ) , vm)
388390 }
389391
390392 #[ pymethod( magic) ]
391393 fn ceil ( & self , vm : & VirtualMachine ) -> PyResult < BigInt > {
392- try_bigint ( self . value . ceil ( ) , vm)
394+ try_to_bigint ( self . value . ceil ( ) , vm)
393395 }
394396
395397 #[ pymethod( magic) ]
@@ -417,7 +419,7 @@ impl PyFloat {
417419 } else {
418420 self . value . round ( )
419421 } ;
420- let int = try_bigint ( value, vm) ?;
422+ let int = try_to_bigint ( value, vm) ?;
421423 vm. ctx . new_int ( int)
422424 } ;
423425 Ok ( value)
0 commit comments