@@ -17,11 +17,11 @@ use unicode_xid::UnicodeXID;
17
17
use super :: objbytes:: PyBytes ;
18
18
use super :: objdict:: PyDict ;
19
19
use super :: objfloat;
20
- use super :: objint:: { self , PyInt } ;
20
+ use super :: objint:: { self , PyInt , PyIntRef } ;
21
21
use super :: objiter;
22
22
use super :: objnone:: PyNone ;
23
23
use super :: objsequence:: PySliceableSequence ;
24
- use super :: objslice:: PySlice ;
24
+ use super :: objslice:: PySliceRef ;
25
25
use super :: objtuple;
26
26
use super :: objtype:: { self , PyClassRef } ;
27
27
use crate :: cformat:: {
@@ -32,8 +32,8 @@ use crate::format::{FormatParseError, FormatPart, FormatPreconversor, FormatStri
32
32
use crate :: function:: { single_or_tuple_any, OptionalArg , PyFuncArgs } ;
33
33
use crate :: pyhash;
34
34
use crate :: pyobject:: {
35
- IdProtocol , IntoPyObject , ItemProtocol , PyClassImpl , PyContext , PyIterable , PyObjectRef , PyRef ,
36
- PyResult , PyValue , TryFromObject , TryIntoRef , TypeProtocol ,
35
+ Either , IdProtocol , IntoPyObject , ItemProtocol , PyClassImpl , PyContext , PyIterable ,
36
+ PyObjectRef , PyRef , PyResult , PyValue , TryFromObject , TryIntoRef , TypeProtocol ,
37
37
} ;
38
38
use crate :: vm:: VirtualMachine ;
39
39
@@ -229,8 +229,34 @@ impl PyString {
229
229
}
230
230
231
231
#[ pymethod( name = "__getitem__" ) ]
232
- fn getitem ( & self , needle : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
233
- subscript ( vm, & self . value , needle)
232
+ fn getitem ( & self , needle : Either < PyIntRef , PySliceRef > , vm : & VirtualMachine ) -> PyResult {
233
+ match needle {
234
+ Either :: A ( pos) => match pos. as_bigint ( ) . to_isize ( ) {
235
+ Some ( pos) => {
236
+ let index: usize = if pos. is_negative ( ) {
237
+ ( self . value . chars ( ) . count ( ) as isize + pos) as usize
238
+ } else {
239
+ pos. abs ( ) as usize
240
+ } ;
241
+
242
+ if let Some ( character) = self . value . chars ( ) . nth ( index) {
243
+ Ok ( vm. new_str ( character. to_string ( ) ) )
244
+ } else {
245
+ Err ( vm. new_index_error ( "string index out of range" . to_string ( ) ) )
246
+ }
247
+ }
248
+ None => Err (
249
+ vm. new_index_error ( "cannot fit 'int' into an index-sized integer" . to_string ( ) )
250
+ ) ,
251
+ } ,
252
+ Either :: B ( slice) => {
253
+ let string = self
254
+ . value
255
+ . to_string ( )
256
+ . get_slice_items ( vm, slice. as_object ( ) ) ?;
257
+ Ok ( vm. new_str ( string) )
258
+ }
259
+ }
234
260
}
235
261
236
262
#[ pymethod( name = "__gt__" ) ]
@@ -292,22 +318,18 @@ impl PyString {
292
318
}
293
319
294
320
#[ pymethod( name = "__mul__" ) ]
295
- fn mul ( & self , val : PyObjectRef , vm : & VirtualMachine ) -> PyResult < String > {
296
- if !objtype:: isinstance ( & val, & vm. ctx . int_type ( ) ) {
297
- return Err ( vm. new_type_error ( format ! ( "Cannot multiply {} and {}" , self , val) ) ) ;
298
- }
299
- objint:: get_value ( & val)
300
- . to_isize ( )
301
- . map ( |multiplier| multiplier. max ( 0 ) )
302
- . and_then ( |multiplier| multiplier. to_usize ( ) )
321
+ fn mul ( & self , multiplier : isize , vm : & VirtualMachine ) -> PyResult < String > {
322
+ multiplier
323
+ . max ( 0 )
324
+ . to_usize ( )
303
325
. map ( |multiplier| self . value . repeat ( multiplier) )
304
326
. ok_or_else ( || {
305
327
vm. new_overflow_error ( "cannot fit 'int' into an index-sized integer" . to_string ( ) )
306
328
} )
307
329
}
308
330
309
331
#[ pymethod( name = "__rmul__" ) ]
310
- fn rmul ( & self , val : PyObjectRef , vm : & VirtualMachine ) -> PyResult < String > {
332
+ fn rmul ( & self , val : isize , vm : & VirtualMachine ) -> PyResult < String > {
311
333
self . mul ( val, vm)
312
334
}
313
335
@@ -1575,37 +1597,6 @@ impl PySliceableSequence for String {
1575
1597
}
1576
1598
}
1577
1599
1578
- pub fn subscript ( vm : & VirtualMachine , value : & str , b : PyObjectRef ) -> PyResult {
1579
- if objtype:: isinstance ( & b, & vm. ctx . int_type ( ) ) {
1580
- match objint:: get_value ( & b) . to_isize ( ) {
1581
- Some ( pos) => {
1582
- let index: usize = if pos. is_negative ( ) {
1583
- ( value. chars ( ) . count ( ) as isize + pos) as usize
1584
- } else {
1585
- pos. abs ( ) as usize
1586
- } ;
1587
-
1588
- if let Some ( character) = value. chars ( ) . nth ( index) {
1589
- Ok ( vm. new_str ( character. to_string ( ) ) )
1590
- } else {
1591
- Err ( vm. new_index_error ( "string index out of range" . to_string ( ) ) )
1592
- }
1593
- }
1594
- None => {
1595
- Err ( vm. new_index_error ( "cannot fit 'int' into an index-sized integer" . to_string ( ) ) )
1596
- }
1597
- }
1598
- } else if b. payload :: < PySlice > ( ) . is_some ( ) {
1599
- let string = value. to_string ( ) . get_slice_items ( vm, & b) ?;
1600
- Ok ( vm. new_str ( string) )
1601
- } else {
1602
- Err ( vm. new_type_error ( format ! (
1603
- "indexing type {:?} with index {:?} is not supported" ,
1604
- value, b
1605
- ) ) )
1606
- }
1607
- }
1608
-
1609
1600
// help get optional string indices
1610
1601
fn adjust_indices (
1611
1602
start : OptionalArg < isize > ,
0 commit comments