@@ -524,6 +524,171 @@ test_long_and_overflow(PyObject *self)
524524 return Py_None ;
525525}
526526
527+ /* Test the PyLong_AsLongLongAndOverflow API. General conversion to
528+ PY_LONG_LONG is tested by test_long_api_inner. This test will
529+ concentrate on proper handling of overflow.
530+ */
531+
532+ static PyObject *
533+ test_long_long_and_overflow (PyObject * self )
534+ {
535+ PyObject * num , * one , * temp ;
536+ PY_LONG_LONG value ;
537+ int overflow ;
538+
539+ /* Test that overflow is set properly for a large value. */
540+ /* num is a number larger than PY_LLONG_MAX on a typical machine. */
541+ num = PyLong_FromString ("FFFFFFFFFFFFFFFFFFFFFFFF" , NULL , 16 );
542+ if (num == NULL )
543+ return NULL ;
544+ overflow = 1234 ;
545+ value = PyLong_AsLongLongAndOverflow (num , & overflow );
546+ Py_DECREF (num );
547+ if (value == -1 && PyErr_Occurred ())
548+ return NULL ;
549+ if (value != -1 )
550+ return raiseTestError ("test_long_long_and_overflow" ,
551+ "return value was not set to -1" );
552+ if (overflow != 1 )
553+ return raiseTestError ("test_long_long_and_overflow" ,
554+ "overflow was not set to 1" );
555+
556+ /* Same again, with num = PY_LLONG_MAX + 1 */
557+ num = PyLong_FromLongLong (PY_LLONG_MAX );
558+ if (num == NULL )
559+ return NULL ;
560+ one = PyLong_FromLong (1L );
561+ if (one == NULL ) {
562+ Py_DECREF (num );
563+ return NULL ;
564+ }
565+ temp = PyNumber_Add (num , one );
566+ Py_DECREF (one );
567+ Py_DECREF (num );
568+ num = temp ;
569+ if (num == NULL )
570+ return NULL ;
571+ overflow = 0 ;
572+ value = PyLong_AsLongLongAndOverflow (num , & overflow );
573+ Py_DECREF (num );
574+ if (value == -1 && PyErr_Occurred ())
575+ return NULL ;
576+ if (value != -1 )
577+ return raiseTestError ("test_long_long_and_overflow" ,
578+ "return value was not set to -1" );
579+ if (overflow != 1 )
580+ return raiseTestError ("test_long_long_and_overflow" ,
581+ "overflow was not set to 1" );
582+
583+ /* Test that overflow is set properly for a large negative value. */
584+ /* num is a number smaller than PY_LLONG_MIN on a typical platform */
585+ num = PyLong_FromString ("-FFFFFFFFFFFFFFFFFFFFFFFF" , NULL , 16 );
586+ if (num == NULL )
587+ return NULL ;
588+ overflow = 1234 ;
589+ value = PyLong_AsLongLongAndOverflow (num , & overflow );
590+ Py_DECREF (num );
591+ if (value == -1 && PyErr_Occurred ())
592+ return NULL ;
593+ if (value != -1 )
594+ return raiseTestError ("test_long_long_and_overflow" ,
595+ "return value was not set to -1" );
596+ if (overflow != -1 )
597+ return raiseTestError ("test_long_long_and_overflow" ,
598+ "overflow was not set to -1" );
599+
600+ /* Same again, with num = PY_LLONG_MIN - 1 */
601+ num = PyLong_FromLongLong (PY_LLONG_MIN );
602+ if (num == NULL )
603+ return NULL ;
604+ one = PyLong_FromLong (1L );
605+ if (one == NULL ) {
606+ Py_DECREF (num );
607+ return NULL ;
608+ }
609+ temp = PyNumber_Subtract (num , one );
610+ Py_DECREF (one );
611+ Py_DECREF (num );
612+ num = temp ;
613+ if (num == NULL )
614+ return NULL ;
615+ overflow = 0 ;
616+ value = PyLong_AsLongLongAndOverflow (num , & overflow );
617+ Py_DECREF (num );
618+ if (value == -1 && PyErr_Occurred ())
619+ return NULL ;
620+ if (value != -1 )
621+ return raiseTestError ("test_long_long_and_overflow" ,
622+ "return value was not set to -1" );
623+ if (overflow != -1 )
624+ return raiseTestError ("test_long_long_and_overflow" ,
625+ "overflow was not set to -1" );
626+
627+ /* Test that overflow is cleared properly for small values. */
628+ num = PyLong_FromString ("FF" , NULL , 16 );
629+ if (num == NULL )
630+ return NULL ;
631+ overflow = 1234 ;
632+ value = PyLong_AsLongLongAndOverflow (num , & overflow );
633+ Py_DECREF (num );
634+ if (value == -1 && PyErr_Occurred ())
635+ return NULL ;
636+ if (value != 0xFF )
637+ return raiseTestError ("test_long_long_and_overflow" ,
638+ "expected return value 0xFF" );
639+ if (overflow != 0 )
640+ return raiseTestError ("test_long_long_and_overflow" ,
641+ "overflow was not cleared" );
642+
643+ num = PyLong_FromString ("-FF" , NULL , 16 );
644+ if (num == NULL )
645+ return NULL ;
646+ overflow = 0 ;
647+ value = PyLong_AsLongLongAndOverflow (num , & overflow );
648+ Py_DECREF (num );
649+ if (value == -1 && PyErr_Occurred ())
650+ return NULL ;
651+ if (value != -0xFF )
652+ return raiseTestError ("test_long_long_and_overflow" ,
653+ "expected return value 0xFF" );
654+ if (overflow != 0 )
655+ return raiseTestError ("test_long_long_and_overflow" ,
656+ "overflow was set incorrectly" );
657+
658+ num = PyLong_FromLongLong (PY_LLONG_MAX );
659+ if (num == NULL )
660+ return NULL ;
661+ overflow = 1234 ;
662+ value = PyLong_AsLongLongAndOverflow (num , & overflow );
663+ Py_DECREF (num );
664+ if (value == -1 && PyErr_Occurred ())
665+ return NULL ;
666+ if (value != PY_LLONG_MAX )
667+ return raiseTestError ("test_long_long_and_overflow" ,
668+ "expected return value PY_LLONG_MAX" );
669+ if (overflow != 0 )
670+ return raiseTestError ("test_long_long_and_overflow" ,
671+ "overflow was not cleared" );
672+
673+ num = PyLong_FromLongLong (PY_LLONG_MIN );
674+ if (num == NULL )
675+ return NULL ;
676+ overflow = 0 ;
677+ value = PyLong_AsLongLongAndOverflow (num , & overflow );
678+ Py_DECREF (num );
679+ if (value == -1 && PyErr_Occurred ())
680+ return NULL ;
681+ if (value != PY_LLONG_MIN )
682+ return raiseTestError ("test_long_long_and_overflow" ,
683+ "expected return value PY_LLONG_MIN" );
684+ if (overflow != 0 )
685+ return raiseTestError ("test_long_long_and_overflow" ,
686+ "overflow was not cleared" );
687+
688+ Py_INCREF (Py_None );
689+ return Py_None ;
690+ }
691+
527692/* Test the L code for PyArg_ParseTuple. This should deliver a PY_LONG_LONG
528693 for both long and int arguments. The test may leak a little memory if
529694 it fails.
@@ -1791,6 +1956,8 @@ static PyMethodDef TestMethods[] = {
17911956 {"getargs_L" , getargs_L , METH_VARARGS },
17921957 {"getargs_K" , getargs_K , METH_VARARGS },
17931958 {"test_longlong_api" , test_longlong_api , METH_NOARGS },
1959+ {"test_long_long_and_overflow" ,
1960+ (PyCFunction )test_long_long_and_overflow , METH_NOARGS },
17941961 {"test_L_code" , (PyCFunction )test_L_code , METH_NOARGS },
17951962 {"codec_incrementalencoder" ,
17961963 (PyCFunction )codec_incrementalencoder , METH_VARARGS },
0 commit comments