@@ -359,6 +359,171 @@ test_longlong_api(PyObject* self, PyObject *args)
359359#undef F_U_TO_PY
360360#undef F_PY_TO_U
361361
362+ /* Test the PyLong_AsLongAndOverflow API. General conversion to PY_LONG
363+ is tested by test_long_api_inner. This test will concentrate on proper
364+ handling of overflow.
365+ */
366+
367+ static PyObject *
368+ test_long_and_overflow (PyObject * self )
369+ {
370+ PyObject * num , * one , * temp ;
371+ long value ;
372+ int overflow ;
373+
374+ /* Test that overflow is set properly for a large value. */
375+ /* num is a number larger than LONG_MAX even on 64-bit platforms */
376+ num = PyLong_FromString ("FFFFFFFFFFFFFFFFFFFFFFFF" , NULL , 16 );
377+ if (num == NULL )
378+ return NULL ;
379+ overflow = 1234 ;
380+ value = PyLong_AsLongAndOverflow (num , & overflow );
381+ Py_DECREF (num );
382+ if (value == -1 && PyErr_Occurred ())
383+ return NULL ;
384+ if (value != -1 )
385+ return raiseTestError ("test_long_and_overflow" ,
386+ "return value was not set to -1" );
387+ if (overflow != 1 )
388+ return raiseTestError ("test_long_and_overflow" ,
389+ "overflow was not set to 1" );
390+
391+ /* Same again, with num = LONG_MAX + 1 */
392+ num = PyLong_FromLong (LONG_MAX );
393+ if (num == NULL )
394+ return NULL ;
395+ one = PyLong_FromLong (1L );
396+ if (one == NULL ) {
397+ Py_DECREF (num );
398+ return NULL ;
399+ }
400+ temp = PyNumber_Add (num , one );
401+ Py_DECREF (one );
402+ Py_DECREF (num );
403+ num = temp ;
404+ if (num == NULL )
405+ return NULL ;
406+ overflow = 0 ;
407+ value = PyLong_AsLongAndOverflow (num , & overflow );
408+ Py_DECREF (num );
409+ if (value == -1 && PyErr_Occurred ())
410+ return NULL ;
411+ if (value != -1 )
412+ return raiseTestError ("test_long_and_overflow" ,
413+ "return value was not set to -1" );
414+ if (overflow != 1 )
415+ return raiseTestError ("test_long_and_overflow" ,
416+ "overflow was not set to 1" );
417+
418+ /* Test that overflow is set properly for a large negative value. */
419+ /* num is a number smaller than LONG_MIN even on 64-bit platforms */
420+ num = PyLong_FromString ("-FFFFFFFFFFFFFFFFFFFFFFFF" , NULL , 16 );
421+ if (num == NULL )
422+ return NULL ;
423+ overflow = 1234 ;
424+ value = PyLong_AsLongAndOverflow (num , & overflow );
425+ Py_DECREF (num );
426+ if (value == -1 && PyErr_Occurred ())
427+ return NULL ;
428+ if (value != -1 )
429+ return raiseTestError ("test_long_and_overflow" ,
430+ "return value was not set to -1" );
431+ if (overflow != -1 )
432+ return raiseTestError ("test_long_and_overflow" ,
433+ "overflow was not set to -1" );
434+
435+ /* Same again, with num = LONG_MIN - 1 */
436+ num = PyLong_FromLong (LONG_MIN );
437+ if (num == NULL )
438+ return NULL ;
439+ one = PyLong_FromLong (1L );
440+ if (one == NULL ) {
441+ Py_DECREF (num );
442+ return NULL ;
443+ }
444+ temp = PyNumber_Subtract (num , one );
445+ Py_DECREF (one );
446+ Py_DECREF (num );
447+ num = temp ;
448+ if (num == NULL )
449+ return NULL ;
450+ overflow = 0 ;
451+ value = PyLong_AsLongAndOverflow (num , & overflow );
452+ Py_DECREF (num );
453+ if (value == -1 && PyErr_Occurred ())
454+ return NULL ;
455+ if (value != -1 )
456+ return raiseTestError ("test_long_and_overflow" ,
457+ "return value was not set to -1" );
458+ if (overflow != -1 )
459+ return raiseTestError ("test_long_and_overflow" ,
460+ "overflow was not set to -1" );
461+
462+ /* Test that overflow is cleared properly for small values. */
463+ num = PyLong_FromString ("FF" , NULL , 16 );
464+ if (num == NULL )
465+ return NULL ;
466+ overflow = 1234 ;
467+ value = PyLong_AsLongAndOverflow (num , & overflow );
468+ Py_DECREF (num );
469+ if (value == -1 && PyErr_Occurred ())
470+ return NULL ;
471+ if (value != 0xFF )
472+ return raiseTestError ("test_long_and_overflow" ,
473+ "expected return value 0xFF" );
474+ if (overflow != 0 )
475+ return raiseTestError ("test_long_and_overflow" ,
476+ "overflow was not cleared" );
477+
478+ num = PyLong_FromString ("-FF" , NULL , 16 );
479+ if (num == NULL )
480+ return NULL ;
481+ overflow = 0 ;
482+ value = PyLong_AsLongAndOverflow (num , & overflow );
483+ Py_DECREF (num );
484+ if (value == -1 && PyErr_Occurred ())
485+ return NULL ;
486+ if (value != -0xFF )
487+ return raiseTestError ("test_long_and_overflow" ,
488+ "expected return value 0xFF" );
489+ if (overflow != 0 )
490+ return raiseTestError ("test_long_and_overflow" ,
491+ "overflow was set incorrectly" );
492+
493+ num = PyLong_FromLong (LONG_MAX );
494+ if (num == NULL )
495+ return NULL ;
496+ overflow = 1234 ;
497+ value = PyLong_AsLongAndOverflow (num , & overflow );
498+ Py_DECREF (num );
499+ if (value == -1 && PyErr_Occurred ())
500+ return NULL ;
501+ if (value != LONG_MAX )
502+ return raiseTestError ("test_long_and_overflow" ,
503+ "expected return value LONG_MAX" );
504+ if (overflow != 0 )
505+ return raiseTestError ("test_long_and_overflow" ,
506+ "overflow was not cleared" );
507+
508+ num = PyLong_FromLong (LONG_MIN );
509+ if (num == NULL )
510+ return NULL ;
511+ overflow = 0 ;
512+ value = PyLong_AsLongAndOverflow (num , & overflow );
513+ Py_DECREF (num );
514+ if (value == -1 && PyErr_Occurred ())
515+ return NULL ;
516+ if (value != LONG_MIN )
517+ return raiseTestError ("test_long_and_overflow" ,
518+ "expected return value LONG_MIN" );
519+ if (overflow != 0 )
520+ return raiseTestError ("test_long_and_overflow" ,
521+ "overflow was not cleared" );
522+
523+ Py_INCREF (Py_None );
524+ return Py_None ;
525+ }
526+
362527/* Test the L code for PyArg_ParseTuple. This should deliver a PY_LONG_LONG
363528 for both long and int arguments. The test may leak a little memory if
364529 it fails.
@@ -1560,6 +1725,8 @@ static PyMethodDef TestMethods[] = {
15601725 {"test_dict_iteration" , (PyCFunction )test_dict_iteration ,METH_NOARGS },
15611726 {"test_lazy_hash_inheritance" , (PyCFunction )test_lazy_hash_inheritance ,METH_NOARGS },
15621727 {"test_long_api" , (PyCFunction )test_long_api , METH_NOARGS },
1728+ {"test_long_and_overflow" , (PyCFunction )test_long_and_overflow ,
1729+ METH_NOARGS },
15631730 {"test_long_numbits" , (PyCFunction )test_long_numbits , METH_NOARGS },
15641731 {"test_k_code" , (PyCFunction )test_k_code , METH_NOARGS },
15651732 {"test_empty_argparse" , (PyCFunction )test_empty_argparse ,METH_NOARGS },
0 commit comments