diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 7b130ca..2b9b9e8 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -1426,7 +1426,9 @@ class UnicodeTest(string_tests.CommonTest, # Test PyUnicode_FromFormat() def test_from_format(self): support.import_module('ctypes') - from ctypes import pythonapi, py_object + from ctypes import (pythonapi, py_object, + c_int, c_long, c_longlong, c_ssize_t, + c_uint, c_ulong, c_ulonglong, c_size_t) if sys.maxunicode == 65535: name = "PyUnicodeUCS2_FromFormat" else: @@ -1451,6 +1453,21 @@ class UnicodeTest(string_tests.CommonTest, 'string, got a non-ASCII byte: 0xe9$', PyUnicode_FromFormat, b'unicode\xe9=%s', 'ascii') + self.assertEqual(PyUnicode_FromFormat(b'%i', c_int(-123)), '-123') + self.assertEqual(PyUnicode_FromFormat(b'%li', c_long(-123)), '-123') + self.assertEqual(PyUnicode_FromFormat(b'%lli', c_longlong(-123)), '-123') + self.assertEqual(PyUnicode_FromFormat(b'%zi', c_ssize_t(-123)), '-123') + + self.assertEqual(PyUnicode_FromFormat(b'%d', c_int(-123)), '-123') + self.assertEqual(PyUnicode_FromFormat(b'%ld', c_long(-123)), '-123') + self.assertEqual(PyUnicode_FromFormat(b'%lld', c_longlong(-123)), '-123') + self.assertEqual(PyUnicode_FromFormat(b'%zd', c_ssize_t(-123)), '-123') + + self.assertEqual(PyUnicode_FromFormat(b'%u', c_uint(123)), '123') + self.assertEqual(PyUnicode_FromFormat(b'%lu', c_ulong(123)), '123') + self.assertEqual(PyUnicode_FromFormat(b'%llu', c_ulonglong(123)), '123') + self.assertEqual(PyUnicode_FromFormat(b'%zu', c_size_t(123)), '123') + # other tests text = PyUnicode_FromFormat(b'%%A:%A', 'abc\xe9\uabcd\U0010ffff') self.assertEqual(text, r"%A:'abc\xe9\uabcd\U0010ffff'") diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 4567196..6edbd8d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -796,18 +796,19 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) * they don't affect the amount of space we reserve. */ if (*f == 'l') { - if (f[1] == 'd' || f[1] == 'u') { + if (f[1] == 'd' || f[1] == 'i' || f[1] == 'u') { ++f; } #ifdef HAVE_LONG_LONG else if (f[1] == 'l' && - (f[2] == 'd' || f[2] == 'u')) { + (f[2] == 'd' || f[2] == 'i'|| f[2] == 'u')) { longlongflag = 1; f += 2; } #endif } - else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { + else if (*f == 'z' && + (f[1] == 'd' || f[1] == 'i' || f[1] == 'u')) { ++f; } @@ -972,20 +973,21 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) } /* Handle %ld, %lu, %lld and %llu. */ if (*f == 'l') { - if (f[1] == 'd' || f[1] == 'u') { + if (f[1] == 'd' || f[1] == 'i' || f[1] == 'u') { longflag = 1; ++f; } #ifdef HAVE_LONG_LONG else if (f[1] == 'l' && - (f[2] == 'd' || f[2] == 'u')) { + (f[2] == 'd' || f[2] == 'i' || f[2] == 'u')) { longlongflag = 1; f += 2; } #endif } /* handle the size_t flag. */ - if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { + if (*f == 'z' && + (f[1] == 'd' || f[1] == 'i' || f[1] == 'u')) { size_tflag = 1; ++f; } @@ -995,8 +997,9 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) *s++ = va_arg(vargs, int); break; case 'd': + case 'i': makefmt(fmt, longflag, longlongflag, size_tflag, zeropad, - width, precision, 'd'); + width, precision, *f); if (longflag) sprintf(realbuffer, fmt, va_arg(vargs, long)); #ifdef HAVE_LONG_LONG @@ -1025,11 +1028,6 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) sprintf(realbuffer, fmt, va_arg(vargs, unsigned int)); appendstring(realbuffer); break; - case 'i': - makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'i'); - sprintf(realbuffer, fmt, va_arg(vargs, int)); - appendstring(realbuffer); - break; case 'x': makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'x'); sprintf(realbuffer, fmt, va_arg(vargs, int));