@@ -41,6 +41,62 @@ impl PyObject {
4141 ) )
4242 } )
4343 }
44+
45+ pub fn try_int ( & self , vm : & VirtualMachine ) -> PyResult < PyIntRef > {
46+ fn try_convert ( obj : & PyObject , lit : & [ u8 ] , vm : & VirtualMachine ) -> PyResult < PyIntRef > {
47+ let base = 10 ;
48+ match int:: bytes_to_int ( lit, base) {
49+ Some ( i) => Ok ( PyInt :: from ( i) . into_ref ( vm) ) ,
50+ None => Err ( vm. new_value_error ( format ! (
51+ "invalid literal for int() with base {}: {}" ,
52+ base,
53+ obj. repr( vm) ?,
54+ ) ) ) ,
55+ }
56+ }
57+
58+ if let Some ( i) = self . downcast_ref_if_exact :: < PyInt > ( vm) {
59+ Ok ( i. to_owned ( ) )
60+ } 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+ }
98+ }
99+ }
44100}
45101
46102#[ derive( Default ) ]
@@ -178,24 +234,11 @@ impl PyNumber<'_> {
178234 self . methods ( ) . index . load ( ) . is_some ( )
179235 }
180236
181- pub fn int ( & self , vm : & VirtualMachine ) -> PyResult < PyIntRef > {
182- fn try_convert ( obj : & PyObject , lit : & [ u8 ] , vm : & VirtualMachine ) -> PyResult < PyIntRef > {
183- let base = 10 ;
184- match int:: bytes_to_int ( lit, base) {
185- Some ( i) => Ok ( PyInt :: from ( i) . into_ref ( vm) ) ,
186- None => Err ( vm. new_value_error ( format ! (
187- "invalid literal for int() with base {}: {}" ,
188- base,
189- obj. repr( vm) ?,
190- ) ) ) ,
191- }
192- }
193-
194- if let Some ( i) = self . obj . downcast_ref_if_exact :: < PyInt > ( vm) {
195- Ok ( i. to_owned ( ) )
196- } else if let Some ( f) = self . methods ( ) . int . load ( ) {
237+ #[ inline]
238+ pub fn int ( & self , vm : & VirtualMachine ) -> PyResult < Option < PyIntRef > > {
239+ Ok ( if let Some ( f) = self . methods ( ) . int . load ( ) {
197240 let ret = f ( self , vm) ?;
198- if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
241+ Some ( if !ret. class ( ) . is ( PyInt :: class ( vm) ) {
199242 warnings:: warn (
200243 vm. ctx . exceptions . deprecation_warning ,
201244 format ! (
@@ -207,44 +250,13 @@ impl PyNumber<'_> {
207250 1 ,
208251 vm,
209252 ) ?;
210- Ok ( vm. ctx . new_bigint ( ret. as_bigint ( ) ) )
253+ vm. ctx . new_bigint ( ret. as_bigint ( ) )
211254 } else {
212- Ok ( ret)
213- }
214- } else if self . methods ( ) . index . load ( ) . is_some ( ) {
215- self . obj . try_index ( vm)
216- } else if let Ok ( Ok ( f) ) =
217- vm. get_special_method ( self . obj . to_owned ( ) , identifier ! ( vm, __trunc__) )
218- {
219- // TODO: Deprecate in 3.11
220- // warnings::warn(
221- // vm.ctx.exceptions.deprecation_warning.clone(),
222- // "The delegation of int() to __trunc__ is deprecated.".to_owned(),
223- // 1,
224- // vm,
225- // )?;
226- let ret = f. invoke ( ( ) , vm) ?;
227- ret. try_index ( vm) . map_err ( |_| {
228- vm. new_type_error ( format ! (
229- "__trunc__ returned non-Integral (type {})" ,
230- ret. class( )
231- ) )
255+ ret
232256 } )
233- } else if let Some ( s) = self . obj . payload :: < PyStr > ( ) {
234- try_convert ( self . obj , s. as_str ( ) . as_bytes ( ) , vm)
235- } else if let Some ( bytes) = self . obj . payload :: < PyBytes > ( ) {
236- try_convert ( self . obj , bytes, vm)
237- } else if let Some ( bytearray) = self . obj . payload :: < PyByteArray > ( ) {
238- try_convert ( self . obj , & bytearray. borrow_buf ( ) , vm)
239- } else if let Ok ( buffer) = ArgBytesLike :: try_from_borrowed_object ( vm, self . obj ) {
240- // TODO: replace to PyBuffer
241- try_convert ( self . obj , & buffer. borrow_buf ( ) , vm)
242257 } else {
243- Err ( vm. new_type_error ( format ! (
244- "int() argument must be a string, a bytes-like object or a real number, not '{}'" ,
245- self . obj. class( )
246- ) ) )
247- }
258+ None
259+ } )
248260 }
249261
250262 #[ inline]
0 commit comments