@@ -159,23 +159,88 @@ def __next__(self):
159
159
class islice (object ):
160
160
@__graalpython__ .builtin_method
161
161
def __init__ (self , iterable , * args ):
162
- self ._iterable = enumerate (iter (iterable ))
163
- slice = list (args )
164
- if len (slice ) >= 2 and slice [1 ] is None :
165
- slice [1 ] = sys .maxsize
166
- self ._indexes = iter (range (* slice ))
162
+ start = 0
163
+ stop = - 1
164
+ step = 1
165
+ if len (args ) not in [1 , 2 , 3 ]:
166
+ raise TypeError ("islice(seq, stop) or islice(seq, start, stop[, step])" )
167
+ if len (args ) == 1 :
168
+ if args [0 ] != None :
169
+ stop = int (args [0 ])
170
+ else :
171
+ if args [0 ] != None :
172
+ try :
173
+ start = int (args [0 ])
174
+ except :
175
+ start = - 1
176
+ if args [1 ] != None :
177
+ try :
178
+ stop = int (args [1 ])
179
+ except :
180
+ raise ValueError ("Stop argument for islice() must be None or ean integer: 0 <= x <= sys.maxsize." )
181
+ if start < 0 or stop < - 1 or start > sys .maxsize or stop > sys .maxsize :
182
+ raise ValueError ("Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize." )
183
+ if len (args ) == 3 :
184
+ if args [2 ] != None :
185
+ try :
186
+ step = int (args [2 ])
187
+ except :
188
+ step = - 1
189
+ if step < 1 :
190
+ raise ValueError ("Step for islice() must be a positive integer or None." )
191
+
192
+ self ._it = iter (iterable )
193
+ self ._next = start
194
+ self ._stop = stop
195
+ self ._step = step
196
+ self ._cnt = 0
167
197
168
198
@__graalpython__ .builtin_method
169
199
def __iter__ (self ):
170
200
return self
171
201
172
202
@__graalpython__ .builtin_method
173
203
def __next__ (self ):
174
- index = next (self ._indexes ) # may raise StopIteration
175
- while True :
176
- i , element = next (self ._iterable ) # may raise StopIteration
177
- if i == index :
178
- return element
204
+ it = self ._it
205
+ stop = self ._stop
206
+ if not it :
207
+ raise StopIteration
208
+ while self ._cnt < self ._next :
209
+ try :
210
+ item = next (it )
211
+ except :
212
+ # C code uses any exception to clear the iterator
213
+ self ._it = None
214
+ raise
215
+ self ._cnt += 1
216
+ if stop != - 1 and self ._cnt >= stop :
217
+ self ._it = None
218
+ raise StopIteration
219
+ try :
220
+ item = next (it )
221
+ except :
222
+ self ._it = None
223
+ raise
224
+ self ._cnt += 1
225
+ oldnext = self ._next
226
+ self ._next += self ._step
227
+ if self ._next < oldnext or (stop != - 1 and self ._next > stop ):
228
+ self ._next = stop
229
+ return item
230
+
231
+ @__graalpython__ .builtin_method
232
+ def __reduce__ (self ):
233
+ if self ._it is None :
234
+ return type (self ), (iter ([]), 0 ), 0
235
+ if self ._stop == - 1 :
236
+ stop = None
237
+ else :
238
+ stop = self ._stop
239
+ return type (self ), (self ._it , self ._next , stop , self ._step ), self ._cnt
240
+
241
+ @__graalpython__ .builtin_method
242
+ def __setstate__ (self , state ):
243
+ self ._cnt = int (state )
179
244
180
245
181
246
class count (object ):
0 commit comments