mirror of
https://github.com/python/cpython.git
synced 2025-10-22 06:32:43 +00:00
Issue #10831: PyUnicode_FromFormat() supports %li, %lli and %zi formats
This commit is contained in:
parent
e7faec1aa9
commit
6d970f4713
3 changed files with 33 additions and 18 deletions
|
@ -1430,7 +1430,9 @@ class UnicodeTest(string_tests.CommonTest,
|
||||||
# Test PyUnicode_FromFormat()
|
# Test PyUnicode_FromFormat()
|
||||||
def test_from_format(self):
|
def test_from_format(self):
|
||||||
support.import_module('ctypes')
|
support.import_module('ctypes')
|
||||||
from ctypes import pythonapi, py_object, c_int
|
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:
|
if sys.maxunicode == 65535:
|
||||||
name = "PyUnicodeUCS2_FromFormat"
|
name = "PyUnicodeUCS2_FromFormat"
|
||||||
else:
|
else:
|
||||||
|
@ -1466,21 +1468,29 @@ class UnicodeTest(string_tests.CommonTest,
|
||||||
self.assertEqual(PyUnicode_FromFormat(b'[%%]'), '[%]')
|
self.assertEqual(PyUnicode_FromFormat(b'[%%]'), '[%]')
|
||||||
self.assertEqual(PyUnicode_FromFormat(b'%%%s', b'abc'), '%abc')
|
self.assertEqual(PyUnicode_FromFormat(b'%%%s', b'abc'), '%abc')
|
||||||
|
|
||||||
# test "%i"
|
# test integer formats (%i, %d, %u)
|
||||||
self.assertEqual(PyUnicode_FromFormat(b'%03i', c_int(10)), '010')
|
self.assertEqual(PyUnicode_FromFormat(b'%03i', c_int(10)), '010')
|
||||||
self.assertEqual(PyUnicode_FromFormat(b'%0.4i', c_int(10)), '0010')
|
self.assertEqual(PyUnicode_FromFormat(b'%0.4i', c_int(10)), '0010')
|
||||||
|
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')
|
||||||
|
|
||||||
# not supported: copy the raw format string. these tests are just here
|
self.assertEqual(PyUnicode_FromFormat(b'%d', c_int(-123)), '-123')
|
||||||
# to check for crashs and should not be considered as specifications
|
self.assertEqual(PyUnicode_FromFormat(b'%ld', c_long(-123)), '-123')
|
||||||
self.assertEqual(PyUnicode_FromFormat(b'%1%s', b'abc'), '%s')
|
self.assertEqual(PyUnicode_FromFormat(b'%lld', c_longlong(-123)), '-123')
|
||||||
self.assertEqual(PyUnicode_FromFormat(b'%1abc'), '%1abc')
|
self.assertEqual(PyUnicode_FromFormat(b'%zd', c_ssize_t(-123)), '-123')
|
||||||
self.assertEqual(PyUnicode_FromFormat(b'%+i', c_int(10)), '%+i')
|
|
||||||
self.assertEqual(PyUnicode_FromFormat(b'%.%s', b'abc'), '%.%s')
|
|
||||||
|
|
||||||
# other tests
|
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')
|
||||||
|
|
||||||
|
# test %A
|
||||||
text = PyUnicode_FromFormat(b'%%A:%A', 'abc\xe9\uabcd\U0010ffff')
|
text = PyUnicode_FromFormat(b'%%A:%A', 'abc\xe9\uabcd\U0010ffff')
|
||||||
self.assertEqual(text, r"%A:'abc\xe9\uabcd\U0010ffff'")
|
self.assertEqual(text, r"%A:'abc\xe9\uabcd\U0010ffff'")
|
||||||
|
|
||||||
|
# test %V
|
||||||
text = PyUnicode_FromFormat(b'repr=%V', 'abc', b'xyz')
|
text = PyUnicode_FromFormat(b'repr=%V', 'abc', b'xyz')
|
||||||
self.assertEqual(text, 'repr=abc')
|
self.assertEqual(text, 'repr=abc')
|
||||||
|
|
||||||
|
@ -1494,6 +1504,13 @@ class UnicodeTest(string_tests.CommonTest,
|
||||||
text = PyUnicode_FromFormat(b'repr=%V', None, b'abc\xff')
|
text = PyUnicode_FromFormat(b'repr=%V', None, b'abc\xff')
|
||||||
self.assertEqual(text, 'repr=abc\ufffd')
|
self.assertEqual(text, 'repr=abc\ufffd')
|
||||||
|
|
||||||
|
# not supported: copy the raw format string. these tests are just here
|
||||||
|
# to check for crashs and should not be considered as specifications
|
||||||
|
self.assertEqual(PyUnicode_FromFormat(b'%1%s', b'abc'), '%s')
|
||||||
|
self.assertEqual(PyUnicode_FromFormat(b'%1abc'), '%1abc')
|
||||||
|
self.assertEqual(PyUnicode_FromFormat(b'%+i', c_int(10)), '%+i')
|
||||||
|
self.assertEqual(PyUnicode_FromFormat(b'%.%s', b'abc'), '%.%s')
|
||||||
|
|
||||||
# Test PyUnicode_AsWideChar()
|
# Test PyUnicode_AsWideChar()
|
||||||
def test_aswidechar(self):
|
def test_aswidechar(self):
|
||||||
from _testcapi import unicode_aswidechar
|
from _testcapi import unicode_aswidechar
|
||||||
|
|
|
@ -10,6 +10,8 @@ What's New in Python 3.3 Alpha 1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #10831: PyUnicode_FromFormat() supports %li, %lli and %zi formats.
|
||||||
|
|
||||||
- Issue #10829: Refactor PyUnicode_FromFormat(), use the same function to parse
|
- Issue #10829: Refactor PyUnicode_FromFormat(), use the same function to parse
|
||||||
the format string in the 3 steps, fix crashs on invalid format strings.
|
the format string in the 3 steps, fix crashs on invalid format strings.
|
||||||
|
|
||||||
|
|
|
@ -753,20 +753,20 @@ parse_format_flags(const char *f,
|
||||||
size_tflag = 0;
|
size_tflag = 0;
|
||||||
|
|
||||||
if (*f == 'l') {
|
if (*f == 'l') {
|
||||||
if (f[1] == 'd' || f[1] == 'u') {
|
if (f[1] == 'd' || f[1] == 'u' || f[1] == 'i') {
|
||||||
longflag = 1;
|
longflag = 1;
|
||||||
++f;
|
++f;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_LONG_LONG
|
#ifdef HAVE_LONG_LONG
|
||||||
else if (f[1] == 'l' &&
|
else if (f[1] == 'l' &&
|
||||||
(f[2] == 'd' || f[2] == 'u')) {
|
(f[2] == 'd' || f[2] == 'u' || f[2] == 'i')) {
|
||||||
longlongflag = 1;
|
longlongflag = 1;
|
||||||
f += 2;
|
f += 2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/* handle the size_t flag. */
|
/* handle the size_t flag. */
|
||||||
else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
|
else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u' || f[1] == 'i')) {
|
||||||
size_tflag = 1;
|
size_tflag = 1;
|
||||||
++f;
|
++f;
|
||||||
}
|
}
|
||||||
|
@ -1044,9 +1044,10 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
||||||
*s++ = ordinal;
|
*s++ = ordinal;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'i':
|
||||||
case 'd':
|
case 'd':
|
||||||
makefmt(fmt, longflag, longlongflag, size_tflag, zeropad,
|
makefmt(fmt, longflag, longlongflag, size_tflag, zeropad,
|
||||||
width, precision, 'd');
|
width, precision, *f);
|
||||||
if (longflag)
|
if (longflag)
|
||||||
sprintf(realbuffer, fmt, va_arg(vargs, long));
|
sprintf(realbuffer, fmt, va_arg(vargs, long));
|
||||||
#ifdef HAVE_LONG_LONG
|
#ifdef HAVE_LONG_LONG
|
||||||
|
@ -1075,11 +1076,6 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
||||||
sprintf(realbuffer, fmt, va_arg(vargs, unsigned int));
|
sprintf(realbuffer, fmt, va_arg(vargs, unsigned int));
|
||||||
appendstring(realbuffer);
|
appendstring(realbuffer);
|
||||||
break;
|
break;
|
||||||
case 'i':
|
|
||||||
makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'i');
|
|
||||||
sprintf(realbuffer, fmt, va_arg(vargs, int));
|
|
||||||
appendstring(realbuffer);
|
|
||||||
break;
|
|
||||||
case 'x':
|
case 'x':
|
||||||
makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'x');
|
makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'x');
|
||||||
sprintf(realbuffer, fmt, va_arg(vargs, int));
|
sprintf(realbuffer, fmt, va_arg(vargs, int));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue