@@ -273,6 +273,25 @@ unicode_copycharacters(PyObject *self, PyObject *args)
273273 return Py_BuildValue ("(Nn)" , to_copy , copied );
274274}
275275
276+ static int
277+ check_raised_systemerror (PyObject * result , char * msg )
278+ {
279+ if (result ) {
280+ // no exception
281+ PyErr_Format (PyExc_AssertionError ,
282+ "SystemError not raised: %s" ,
283+ msg );
284+ return 0 ;
285+ }
286+ if (PyErr_ExceptionMatches (PyExc_SystemError )) {
287+ // expected exception
288+ PyErr_Clear ();
289+ return 1 ;
290+ }
291+ // unexpected exception
292+ return 0 ;
293+ }
294+
276295static PyObject *
277296test_string_from_format (PyObject * self , PyObject * Py_UNUSED (ignored ))
278297{
@@ -281,16 +300,21 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
281300
282301#define CHECK_FORMAT_2 (FORMAT , EXPECTED , ARG1 , ARG2 ) \
283302 result = PyUnicode_FromFormat(FORMAT, ARG1, ARG2); \
284- if (result == NULL) \
303+ if (EXPECTED == NULL) { \
304+ if (!check_raised_systemerror(result, FORMAT)) { \
305+ goto Fail; \
306+ } \
307+ } \
308+ else if (result == NULL) \
285309 return NULL; \
286- if (!_PyUnicode_EqualToASCIIString(result, EXPECTED)) { \
310+ else if (!_PyUnicode_EqualToASCIIString(result, EXPECTED)) { \
287311 PyErr_Format(PyExc_AssertionError, \
288312 "test_string_from_format: failed at \"%s\" " \
289313 "expected \"%s\" got \"%s\"", \
290314 FORMAT, EXPECTED, PyUnicode_AsUTF8(result)); \
291315 goto Fail; \
292316 } \
293- Py_DECREF (result)
317+ Py_XDECREF (result)
294318
295319#define CHECK_FORMAT_1 (FORMAT , EXPECTED , ARG ) \
296320 CHECK_FORMAT_2(FORMAT, EXPECTED, ARG, 0)
@@ -299,16 +323,16 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
299323 CHECK_FORMAT_2(FORMAT, EXPECTED, 0, 0)
300324
301325 // Unrecognized
302- CHECK_FORMAT_2 ("%u %? %u" , "1 %? %u" , 1 , 2 );
326+ CHECK_FORMAT_2 ("%u %? %u" , NULL , 1 , 2 );
303327
304- // "%%"
328+ // "%%" (options are rejected)
305329 CHECK_FORMAT_0 ( "%%" , "%" );
306- CHECK_FORMAT_0 ( "%0%" , "%" );
307- CHECK_FORMAT_0 ("%00%" , "%" );
308- CHECK_FORMAT_0 ( "%2%" , "%" );
309- CHECK_FORMAT_0 ("%02%" , "%" );
310- CHECK_FORMAT_0 ("%.0%" , "%.0%" );
311- CHECK_FORMAT_0 ("%.2%" , "%.2%" );
330+ CHECK_FORMAT_0 ( "%0%" , NULL );
331+ CHECK_FORMAT_0 ("%00%" , NULL );
332+ CHECK_FORMAT_0 ( "%2%" , NULL );
333+ CHECK_FORMAT_0 ("%02%" , NULL );
334+ CHECK_FORMAT_0 ("%.0%" , NULL );
335+ CHECK_FORMAT_0 ("%.2%" , NULL );
312336
313337 // "%c"
314338 CHECK_FORMAT_1 ( "%c" , "c" , 'c' );
@@ -409,16 +433,6 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
409433 CHECK_FORMAT_1 ("%05zu" , "00123" , (size_t )123 );
410434 CHECK_FORMAT_1 ("%05x" , "0007b" , (int )123 );
411435
412- CHECK_FORMAT_1 ("%05d" , "-0123" , (int )-123 );
413- CHECK_FORMAT_1 ("%05i" , "-0123" , (int )-123 );
414- CHECK_FORMAT_1 ("%05ld" , "-0123" , (long )-123 );
415- CHECK_FORMAT_1 ("%05li" , "-0123" , (long )-123 );
416- CHECK_FORMAT_1 ("%05lld" , "-0123" , (long long )-123 );
417- CHECK_FORMAT_1 ("%05lli" , "-0123" , (long long )-123 );
418- CHECK_FORMAT_1 ("%05zd" , "-0123" , (Py_ssize_t )- 123 );
419- CHECK_FORMAT_1 ("%05zi" , "-0123" , (Py_ssize_t )- 123 );
420- CHECK_FORMAT_1 ("%09x" , "0ffffff85" , (int )-123 );
421-
422436 // Integers: precision < length
423437 CHECK_FORMAT_1 ("%.1d" , "123" , (int )123 );
424438 CHECK_FORMAT_1 ("%.1i" , "123" , (int )123 );
@@ -459,16 +473,6 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
459473 CHECK_FORMAT_1 ("%.5zu" , "00123" , (size_t )123 );
460474 CHECK_FORMAT_1 ("%.5x" , "0007b" , (int )123 );
461475
462- CHECK_FORMAT_1 ("%.5d" , "-00123" , (int )-123 );
463- CHECK_FORMAT_1 ("%.5i" , "-00123" , (int )-123 );
464- CHECK_FORMAT_1 ("%.5ld" , "-00123" , (long )-123 );
465- CHECK_FORMAT_1 ("%.5li" , "-00123" , (long )-123 );
466- CHECK_FORMAT_1 ("%.5lld" , "-00123" , (long long )-123 );
467- CHECK_FORMAT_1 ("%.5lli" , "-00123" , (long long )-123 );
468- CHECK_FORMAT_1 ("%.5zd" , "-00123" , (Py_ssize_t )- 123 );
469- CHECK_FORMAT_1 ("%.5zi" , "-00123" , (Py_ssize_t )- 123 );
470- CHECK_FORMAT_1 ("%.9x" , "0ffffff85" , (int )-123 );
471-
472476 // Integers: width > precision > length
473477 CHECK_FORMAT_1 ("%7.5d" , " 00123" , (int )123 );
474478 CHECK_FORMAT_1 ("%7.5i" , " 00123" , (int )123 );
@@ -484,16 +488,6 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
484488 CHECK_FORMAT_1 ("%7.5zu" , " 00123" , (size_t )123 );
485489 CHECK_FORMAT_1 ("%7.5x" , " 0007b" , (int )123 );
486490
487- CHECK_FORMAT_1 ("%7.5d" , " -00123" , (int )-123 );
488- CHECK_FORMAT_1 ("%7.5i" , " -00123" , (int )-123 );
489- CHECK_FORMAT_1 ("%7.5ld" , " -00123" , (long )-123 );
490- CHECK_FORMAT_1 ("%7.5li" , " -00123" , (long )-123 );
491- CHECK_FORMAT_1 ("%7.5lld" , " -00123" , (long long )-123 );
492- CHECK_FORMAT_1 ("%7.5lli" , " -00123" , (long long )-123 );
493- CHECK_FORMAT_1 ("%7.5zd" , " -00123" , (Py_ssize_t )- 123 );
494- CHECK_FORMAT_1 ("%7.5zi" , " -00123" , (Py_ssize_t )- 123 );
495- CHECK_FORMAT_1 ("%10.9x" , " 0ffffff85" , (int )-123 );
496-
497491 // Integers: width > precision > length, 0-flag
498492 CHECK_FORMAT_1 ("%07.5d" , "0000123" , (int )123 );
499493 CHECK_FORMAT_1 ("%07.5i" , "0000123" , (int )123 );
@@ -509,16 +503,6 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
509503 CHECK_FORMAT_1 ("%07.5zu" , "0000123" , (size_t )123 );
510504 CHECK_FORMAT_1 ("%07.5x" , "000007b" , (int )123 );
511505
512- CHECK_FORMAT_1 ("%07.5d" , "-000123" , (int )-123 );
513- CHECK_FORMAT_1 ("%07.5i" , "-000123" , (int )-123 );
514- CHECK_FORMAT_1 ("%07.5ld" , "-000123" , (long )-123 );
515- CHECK_FORMAT_1 ("%07.5li" , "-000123" , (long )-123 );
516- CHECK_FORMAT_1 ("%07.5lld" , "-000123" , (long long )-123 );
517- CHECK_FORMAT_1 ("%07.5lli" , "-000123" , (long long )-123 );
518- CHECK_FORMAT_1 ("%07.5zd" , "-000123" , (Py_ssize_t )- 123 );
519- CHECK_FORMAT_1 ("%07.5zi" , "-000123" , (Py_ssize_t )- 123 );
520- CHECK_FORMAT_1 ("%010.9x" , "00ffffff85" , (int )-123 );
521-
522506 // Integers: precision > width > length
523507 CHECK_FORMAT_1 ("%5.7d" , "0000123" , (int )123 );
524508 CHECK_FORMAT_1 ("%5.7i" , "0000123" , (int )123 );
@@ -534,16 +518,6 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
534518 CHECK_FORMAT_1 ("%5.7zu" , "0000123" , (size_t )123 );
535519 CHECK_FORMAT_1 ("%5.7x" , "000007b" , (int )123 );
536520
537- CHECK_FORMAT_1 ("%5.7d" , "-0000123" , (int )-123 );
538- CHECK_FORMAT_1 ("%5.7i" , "-0000123" , (int )-123 );
539- CHECK_FORMAT_1 ("%5.7ld" , "-0000123" , (long )-123 );
540- CHECK_FORMAT_1 ("%5.7li" , "-0000123" , (long )-123 );
541- CHECK_FORMAT_1 ("%5.7lld" , "-0000123" , (long long )-123 );
542- CHECK_FORMAT_1 ("%5.7lli" , "-0000123" , (long long )-123 );
543- CHECK_FORMAT_1 ("%5.7zd" , "-0000123" , (Py_ssize_t )- 123 );
544- CHECK_FORMAT_1 ("%5.7zi" , "-0000123" , (Py_ssize_t )- 123 );
545- CHECK_FORMAT_1 ("%9.10x" , "00ffffff85" , (int )-123 );
546-
547521 // Integers: precision > width > length, 0-flag
548522 CHECK_FORMAT_1 ("%05.7d" , "0000123" , (int )123 );
549523 CHECK_FORMAT_1 ("%05.7i" , "0000123" , (int )123 );
@@ -559,16 +533,6 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
559533 CHECK_FORMAT_1 ("%05.7zu" , "0000123" , (size_t )123 );
560534 CHECK_FORMAT_1 ("%05.7x" , "000007b" , (int )123 );
561535
562- CHECK_FORMAT_1 ("%05.7d" , "-0000123" , (int )-123 );
563- CHECK_FORMAT_1 ("%05.7i" , "-0000123" , (int )-123 );
564- CHECK_FORMAT_1 ("%05.7ld" , "-0000123" , (long )-123 );
565- CHECK_FORMAT_1 ("%05.7li" , "-0000123" , (long )-123 );
566- CHECK_FORMAT_1 ("%05.7lld" , "-0000123" , (long long )-123 );
567- CHECK_FORMAT_1 ("%05.7lli" , "-0000123" , (long long )-123 );
568- CHECK_FORMAT_1 ("%05.7zd" , "-0000123" , (Py_ssize_t )- 123 );
569- CHECK_FORMAT_1 ("%05.7zi" , "-0000123" , (Py_ssize_t )- 123 );
570- CHECK_FORMAT_1 ("%09.10x" , "00ffffff85" , (int )-123 );
571-
572536 // Integers: precision = 0, arg = 0 (empty string in C)
573537 CHECK_FORMAT_1 ("%.0d" , "0" , (int )0 );
574538 CHECK_FORMAT_1 ("%.0i" , "0" , (int )0 );
0 commit comments