Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(182486)

Delta Between Two Patch Sets: Objects/sliceobject.c

Issue 14794: slice.indices raises OverflowError
Left Patch Set: Created 6 years, 8 months ago
Right Patch Set: Created 6 years, 8 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_slice.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 Written by Jim Hugunin and Chris Chase. 2 Written by Jim Hugunin and Chris Chase.
3 3
4 This includes both the singular ellipsis object and slice objects. 4 This includes both the singular ellipsis object and slice objects.
5 5
6 Guido, feel free to do whatever you want in the way of copyrights 6 Guido, feel free to do whatever you want in the way of copyrights
7 for this file. 7 for this file.
8 */ 8 */
9 9
10 /* 10 /*
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 return PyUnicode_FromFormat("slice(%R, %R, %R)", r->start, r->stop, r->step) ; 292 return PyUnicode_FromFormat("slice(%R, %R, %R)", r->start, r->stop, r->step) ;
293 } 293 }
294 294
295 static PyMemberDef slice_members[] = { 295 static PyMemberDef slice_members[] = {
296 {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY}, 296 {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY},
297 {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY}, 297 {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY},
298 {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY}, 298 {"step", T_OBJECT, offsetof(PySliceObject, step), READONLY},
299 {0} 299 {0}
300 }; 300 };
301 301
302 /* Helper function to convert a slice argument to a PyLong, and raise TypeError
303 with a suitable message on failure. */
304
305 static PyObject*
306 evaluate_slice_index(PyObject *v)
307 {
308 if (PyIndex_Check(v)) {
storchaka 2012/11/04 12:29:34 Why not EAFP? PyObject *index = PyNumber_Index(v)
309 return PyNumber_Index(v);
310 }
311 else {
312 PyErr_SetString(PyExc_TypeError,
313 "slice indices must be integers or "
314 "None or have an __index__ method");
315 return NULL;
316 }
317 }
318
319 /* Implementation of slice.indices. */
320
302 static PyObject* 321 static PyObject*
303 slice_indices(PySliceObject* self, PyObject* len) 322 slice_indices(PySliceObject* self, PyObject* len)
304 { 323 {
305 PyObject *start=NULL, *stop=NULL, *step=NULL; 324 PyObject *start=NULL, *stop=NULL, *step=NULL;
306 PyObject *length=NULL, *upper=NULL, *lower=NULL, *zero=NULL; 325 PyObject *length=NULL, *upper=NULL, *lower=NULL, *zero=NULL;
307 int step_is_negative, cmp; 326 int step_is_negative, cmp;
308 327
309 zero = PyLong_FromLong(0L); 328 zero = PyLong_FromLong(0L);
310 if (zero == NULL) 329 if (zero == NULL)
311 return NULL; 330 return NULL;
312 331
313 /* Compute step and length as integers. */ 332 /* Compute step and length as integers. */
314 length = PyNumber_Index(len); 333 length = PyNumber_Index(len);
315 if (length == NULL) 334 if (length == NULL)
316 goto error; 335 goto error;
317 336
318 if (self->step == Py_None) 337 if (self->step == Py_None)
319 step = PyLong_FromLong(1L); 338 step = PyLong_FromLong(1L);
320 else 339 else
321 step = PyNumber_Index(self->step); 340 step = evaluate_slice_index(self->step);
322 if (step == NULL) 341 if (step == NULL)
323 goto error; 342 goto error;
324 343
325 /* Raise ValueError for negative length or zero step. */ 344 /* Raise ValueError for negative length or zero step. */
326 cmp = PyObject_RichCompareBool(length, zero, Py_LT); 345 cmp = PyObject_RichCompareBool(length, zero, Py_LT);
327 if (cmp < 0) { 346 if (cmp < 0) {
328 goto error; 347 goto error;
329 } 348 }
330 if (cmp) { 349 if (cmp) {
331 PyErr_SetString(PyExc_ValueError, 350 PyErr_SetString(PyExc_ValueError,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 upper = length; 382 upper = length;
364 Py_INCREF(upper); 383 Py_INCREF(upper);
365 } 384 }
366 385
367 /* Compute start. */ 386 /* Compute start. */
368 if (self->start == Py_None) { 387 if (self->start == Py_None) {
369 start = step_is_negative ? upper : lower; 388 start = step_is_negative ? upper : lower;
370 Py_INCREF(start); 389 Py_INCREF(start);
371 } 390 }
372 else { 391 else {
373 start = PyNumber_Index(self->start); 392 start = evaluate_slice_index(self->start);
374 if (start == NULL) 393 if (start == NULL)
375 goto error; 394 goto error;
376 395
377 cmp = PyObject_RichCompareBool(start, zero, Py_LT); 396 cmp = PyObject_RichCompareBool(start, zero, Py_LT);
378 if (cmp < 0) 397 if (cmp < 0)
379 goto error; 398 goto error;
380 if (cmp) { 399 if (cmp) {
381 /* start += length */ 400 /* start += length */
382 PyObject *tmp = PyNumber_Add(start, length); 401 PyObject *tmp = PyNumber_Add(start, length);
383 Py_DECREF(start); 402 Py_DECREF(start);
384 start = tmp; 403 start = tmp;
385 if (start == NULL) 404 if (start == NULL)
386 goto error; 405 goto error;
387 406
388 cmp = PyObject_RichCompareBool(start, lower, Py_LE); 407 cmp = PyObject_RichCompareBool(start, lower, Py_LT);
389 if (cmp < 0) 408 if (cmp < 0)
390 goto error; 409 goto error;
391 if (cmp) { 410 if (cmp) {
411 Py_INCREF(lower);
392 Py_DECREF(start); 412 Py_DECREF(start);
393 Py_INCREF(lower);
394 start = lower; 413 start = lower;
395 } 414 }
396 } 415 }
397 else { 416 else {
398 cmp = PyObject_RichCompareBool(start, upper, Py_GE); 417 cmp = PyObject_RichCompareBool(start, upper, Py_GT);
storchaka 2012/11/04 10:55:06 This is only bikeshedding, but I prefer Py_GT here
399 if (cmp < 0) 418 if (cmp < 0)
400 goto error; 419 goto error;
401 if (cmp) { 420 if (cmp) {
421 Py_INCREF(upper);
402 Py_DECREF(start); 422 Py_DECREF(start);
403 Py_INCREF(upper);
404 start = upper; 423 start = upper;
405 } 424 }
406 } 425 }
407 } 426 }
408 427
409 /* Compute stop. */ 428 /* Compute stop. */
410 if (self->stop == Py_None) { 429 if (self->stop == Py_None) {
411 stop = step_is_negative ? lower : upper; 430 stop = step_is_negative ? lower : upper;
412 Py_INCREF(stop); 431 Py_INCREF(stop);
413 } 432 }
414 else { 433 else {
415 stop = PyNumber_Index(self->stop); 434 stop = evaluate_slice_index(self->stop);
416 if (stop == NULL) 435 if (stop == NULL)
417 goto error; 436 goto error;
418 437
419 cmp = PyObject_RichCompareBool(stop, zero, Py_LT); 438 cmp = PyObject_RichCompareBool(stop, zero, Py_LT);
420 if (cmp < 0) 439 if (cmp < 0)
421 goto error; 440 goto error;
422 if (cmp) { 441 if (cmp) {
423 /* stop += length */ 442 /* stop += length */
424 PyObject *tmp = PyNumber_Add(stop, length); 443 PyObject *tmp = PyNumber_Add(stop, length);
425 Py_DECREF(stop); 444 Py_DECREF(stop);
426 stop = tmp; 445 stop = tmp;
427 if (stop == NULL) 446 if (stop == NULL)
428 goto error; 447 goto error;
429 448
430 cmp = PyObject_RichCompareBool(stop, lower, Py_LE); 449 cmp = PyObject_RichCompareBool(stop, lower, Py_LT);
431 if (cmp < 0) 450 if (cmp < 0)
432 goto error; 451 goto error;
433 if (cmp) { 452 if (cmp) {
453 Py_INCREF(lower);
434 Py_DECREF(stop); 454 Py_DECREF(stop);
435 Py_INCREF(lower);
436 stop = lower; 455 stop = lower;
437 } 456 }
438 } 457 }
439 else { 458 else {
440 cmp = PyObject_RichCompareBool(stop, upper, Py_GE); 459 cmp = PyObject_RichCompareBool(stop, upper, Py_GT);
441 if (cmp < 0) 460 if (cmp < 0)
442 goto error; 461 goto error;
443 if (cmp) { 462 if (cmp) {
463 Py_INCREF(upper);
444 Py_DECREF(stop); 464 Py_DECREF(stop);
445 Py_INCREF(upper);
446 stop = upper; 465 stop = upper;
447 } 466 }
448 } 467 }
449 } 468 }
450 469
451 Py_DECREF(upper); 470 Py_DECREF(upper);
452 Py_DECREF(lower); 471 Py_DECREF(lower);
453 Py_DECREF(length); 472 Py_DECREF(length);
454 Py_DECREF(zero); 473 Py_DECREF(zero);
455 return Py_BuildValue("(NNN)", start, stop, step); 474 return Py_BuildValue("(NNN)", start, stop, step);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 0, /* tp_getset */ 600 0, /* tp_getset */
582 0, /* tp_base */ 601 0, /* tp_base */
583 0, /* tp_dict */ 602 0, /* tp_dict */
584 0, /* tp_descr_get */ 603 0, /* tp_descr_get */
585 0, /* tp_descr_set */ 604 0, /* tp_descr_set */
586 0, /* tp_dictoffset */ 605 0, /* tp_dictoffset */
587 0, /* tp_init */ 606 0, /* tp_init */
588 0, /* tp_alloc */ 607 0, /* tp_alloc */
589 slice_new, /* tp_new */ 608 slice_new, /* tp_new */
590 }; 609 };
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+