@@ -9,9 +9,9 @@ use crate::{
99} ;
1010use crossbeam_utils:: atomic:: AtomicCell ;
1111
12- type UnaryFunc < R = PyObjectRef > = AtomicCell < Option < fn ( & PyNumber , & VirtualMachine ) -> PyResult < R > > > ;
12+ type UnaryFunc < R = PyObjectRef > = AtomicCell < Option < fn ( PyNumber , & VirtualMachine ) -> PyResult < R > > > ;
1313type BinaryFunc < R = PyObjectRef > =
14- AtomicCell < Option < fn ( & PyNumber , & PyObject , & VirtualMachine ) -> PyResult < R > > > ;
14+ AtomicCell < Option < fn ( PyNumber , & PyObject , & VirtualMachine ) -> PyResult < R > > > ;
1515
1616impl PyObject {
1717 #[ inline]
@@ -20,16 +20,13 @@ impl PyObject {
2020 }
2121
2222 pub fn try_index_opt ( & self , vm : & VirtualMachine ) -> Option < PyResult < PyIntRef > > {
23- #[ allow( clippy:: question_mark) ]
24- Some ( if let Some ( i) = self . downcast_ref_if_exact :: < PyInt > ( vm) {
25- Ok ( i. to_owned ( ) )
23+ if let Some ( i) = self . downcast_ref_if_exact :: < PyInt > ( vm) {
24+ Some ( Ok ( i. to_owned ( ) ) )
2625 } else if let Some ( i) = self . payload :: < PyInt > ( ) {
27- Ok ( vm. ctx . new_bigint ( i. as_bigint ( ) ) )
28- } else if let Some ( i) = self . to_number ( ) . index ( vm) . transpose ( ) {
29- i
26+ Some ( Ok ( vm. ctx . new_bigint ( i. as_bigint ( ) ) ) )
3027 } else {
31- return None ;
32- } )
28+ self . to_number ( ) . index ( vm )
29+ }
3330 }
3431
3532 #[ inline]
@@ -57,71 +54,57 @@ impl PyObject {
5754
5855 if let Some ( i) = self . downcast_ref_if_exact :: < PyInt > ( vm) {
5956 Ok ( i. to_owned ( ) )
57+ } else if let Some ( i) = self . to_number ( ) . int ( vm) . or_else ( || self . try_index_opt ( vm) ) {
58+ i
59+ } else if let Ok ( Ok ( f) ) = vm. get_special_method ( self . to_owned ( ) , identifier ! ( vm, __trunc__) )
60+ {
61+ // TODO: Deprecate in 3.11
62+ // warnings::warn(
63+ // vm.ctx.exceptions.deprecation_warning.clone(),
64+ // "The delegation of int() to __trunc__ is deprecated.".to_owned(),
65+ // 1,
66+ // vm,
67+ // )?;
68+ let ret = f. invoke ( ( ) , vm) ?;
69+ ret. try_index ( vm) . map_err ( |_| {
70+ vm. new_type_error ( format ! (
71+ "__trunc__ returned non-Integral (type {})" ,
72+ ret. class( )
73+ ) )
74+ } )
75+ } else if let Some ( s) = self . payload :: < PyStr > ( ) {
76+ try_convert ( self , s. as_str ( ) . as_bytes ( ) , vm)
77+ } else if let Some ( bytes) = self . payload :: < PyBytes > ( ) {
78+ try_convert ( self , bytes, vm)
79+ } else if let Some ( bytearray) = self . payload :: < PyByteArray > ( ) {
80+ try_convert ( self , & bytearray. borrow_buf ( ) , vm)
81+ } else if let Ok ( buffer) = ArgBytesLike :: try_from_borrowed_object ( vm, self ) {
82+ // TODO: replace to PyBuffer
83+ try_convert ( self , & buffer. borrow_buf ( ) , vm)
6084 } else {
61- let number = self . to_number ( ) ;
62- if let Some ( i) = number. int ( vm) ? {
63- Ok ( i)
64- } else if let Some ( i) = self . try_index_opt ( vm) {
65- i
66- } else if let Ok ( Ok ( f) ) =
67- vm. get_special_method ( self . to_owned ( ) , identifier ! ( vm, __trunc__) )
68- {
69- // TODO: Deprecate in 3.11
70- // warnings::warn(
71- // vm.ctx.exceptions.deprecation_warning.clone(),
72- // "The delegation of int() to __trunc__ is deprecated.".to_owned(),
73- // 1,
74- // vm,
75- // )?;
76- let ret = f. invoke ( ( ) , vm) ?;
77- ret. try_index ( vm) . map_err ( |_| {
78- vm. new_type_error ( format ! (
79- "__trunc__ returned non-Integral (type {})" ,
80- ret. class( )
81- ) )
82- } )
83- } else if let Some ( s) = self . payload :: < PyStr > ( ) {
84- try_convert ( self , s. as_str ( ) . as_bytes ( ) , vm)
85- } else if let Some ( bytes) = self . payload :: < PyBytes > ( ) {
86- try_convert ( self , bytes, vm)
87- } else if let Some ( bytearray) = self . payload :: < PyByteArray > ( ) {
88- try_convert ( self , & bytearray. borrow_buf ( ) , vm)
89- } else if let Ok ( buffer) = ArgBytesLike :: try_from_borrowed_object ( vm, self ) {
90- // TODO: replace to PyBuffer
91- try_convert ( self , & buffer. borrow_buf ( ) , vm)
92- } else {
93- Err ( vm. new_type_error ( format ! (
94- "int() argument must be a string, a bytes-like object or a real number, not '{}'" ,
95- self . class( )
96- ) ) )
97- }
85+ Err ( vm. new_type_error ( format ! (
86+ "int() argument must be a string, a bytes-like object or a real number, not '{}'" ,
87+ self . class( )
88+ ) ) )
9889 }
9990 }
10091
101- pub fn try_float_opt ( & self , vm : & VirtualMachine ) -> PyResult < Option < PyRef < PyFloat > > > {
102- let value = if let Some ( float) = self . downcast_ref_if_exact :: < PyFloat > ( vm) {
103- Some ( float. to_owned ( ) )
92+ pub fn try_float_opt ( & self , vm : & VirtualMachine ) -> Option < PyResult < PyRef < PyFloat > > > {
93+ if let Some ( float) = self . downcast_ref_if_exact :: < PyFloat > ( vm) {
94+ Some ( Ok ( float. to_owned ( ) ) )
95+ } else if let Some ( f) = self . to_number ( ) . float ( vm) {
96+ Some ( f)
10497 } else {
105- let number = self . to_number ( ) ;
106- #[ allow( clippy:: manual_map) ]
107- if let Some ( f) = number. float ( vm) ? {
108- Some ( f)
109- } else if let Some ( i) = self . try_index_opt ( vm) {
110- let value = int:: try_to_float ( i?. as_bigint ( ) , vm) ?;
111- Some ( vm. ctx . new_float ( value) )
112- } else if let Some ( value) = self . downcast_ref :: < PyFloat > ( ) {
113- Some ( vm. ctx . new_float ( value. to_f64 ( ) ) )
114- } else {
115- None
116- }
117- } ;
118- Ok ( value)
98+ self . try_index_opt ( vm)
99+ . map ( |i| Ok ( vm. ctx . new_float ( int:: try_to_float ( i?. as_bigint ( ) , vm) ?) ) )
100+ }
119101 }
120102
121103 #[ inline]
122104 pub fn try_float ( & self , vm : & VirtualMachine ) -> PyResult < PyRef < PyFloat > > {
123- self . try_float_opt ( vm) ?
124- . ok_or_else ( || vm. new_type_error ( format ! ( "must be real number, not {}" , self . class( ) ) ) )
105+ self . try_float_opt ( vm) . ok_or_else ( || {
106+ vm. new_type_error ( format ! ( "must be real number, not {}" , self . class( ) ) )
107+ } ) ?
125108 }
126109}
127110
@@ -259,10 +242,10 @@ impl PyNumber<'_> {
259242 }
260243
261244 #[ inline]
262- pub fn int ( & self , vm : & VirtualMachine ) -> PyResult < Option < PyIntRef > > {
263- Ok ( if let Some ( f ) = self . methods ( ) . int . load ( ) {
245+ pub fn int ( self , vm : & VirtualMachine ) -> Option < PyResult < PyIntRef > > {
246+ self . methods ( ) . int . load ( ) . map ( |f| {
264247 let ret = f ( self , vm) ?;
265- Some ( if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
248+ let value = if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
266249 warnings:: warn (
267250 vm. ctx . exceptions . deprecation_warning ,
268251 format ! (
@@ -277,17 +260,16 @@ impl PyNumber<'_> {
277260 vm. ctx . new_bigint ( ret. as_bigint ( ) )
278261 } else {
279262 ret
280- } )
281- } else {
282- None
263+ } ;
264+ Ok ( value)
283265 } )
284266 }
285267
286268 #[ inline]
287- pub fn index ( & self , vm : & VirtualMachine ) -> PyResult < Option < PyIntRef > > {
288- if let Some ( f ) = self . methods ( ) . index . load ( ) {
269+ pub fn index ( self , vm : & VirtualMachine ) -> Option < PyResult < PyIntRef > > {
270+ self . methods ( ) . index . load ( ) . map ( |f| {
289271 let ret = f ( self , vm) ?;
290- if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
272+ let value = if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
291273 warnings:: warn (
292274 vm. ctx . exceptions . deprecation_warning ,
293275 format ! (
@@ -299,20 +281,19 @@ impl PyNumber<'_> {
299281 1 ,
300282 vm,
301283 ) ?;
302- Ok ( Some ( vm. ctx . new_bigint ( ret. as_bigint ( ) ) ) )
284+ vm. ctx . new_bigint ( ret. as_bigint ( ) )
303285 } else {
304- Ok ( Some ( ret) )
305- }
306- } else {
307- Ok ( None )
308- }
286+ ret
287+ } ;
288+ Ok ( value)
289+ } )
309290 }
310291
311292 #[ inline]
312- pub fn float ( & self , vm : & VirtualMachine ) -> PyResult < Option < PyRef < PyFloat > > > {
313- Ok ( if let Some ( f ) = self . methods ( ) . float . load ( ) {
293+ pub fn float ( self , vm : & VirtualMachine ) -> Option < PyResult < PyRef < PyFloat > > > {
294+ self . methods ( ) . float . load ( ) . map ( |f| {
314295 let ret = f ( self , vm) ?;
315- Some ( if !ret. class ( ) . is ( PyFloat :: class ( vm) ) {
296+ let value = if !ret. class ( ) . is ( PyFloat :: class ( vm) ) {
316297 warnings:: warn (
317298 vm. ctx . exceptions . deprecation_warning ,
318299 format ! (
@@ -327,9 +308,8 @@ impl PyNumber<'_> {
327308 vm. ctx . new_float ( ret. to_f64 ( ) )
328309 } else {
329310 ret
330- } )
331- } else {
332- None
311+ } ;
312+ Ok ( value)
333313 } )
334314 }
335315}
0 commit comments