summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-10-09 20:50:36 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-10-09 20:50:36 (GMT)
commit0cdad1e2bc8794cdbba8a89e2a4177a7dedec313 (patch)
tree266a4271792dc69aa5ab9e5194f4e10cd06225e1
parentbe75b8cf2310e0be0f32590a1c0df919058002e8 (diff)
downloadcpython-0cdad1e2bc8794cdbba8a89e2a4177a7dedec313.zip
cpython-0cdad1e2bc8794cdbba8a89e2a4177a7dedec313.tar.gz
cpython-0cdad1e2bc8794cdbba8a89e2a4177a7dedec313.tar.bz2
Issue #25349: Add fast path for b'%c' % int
Optimize also %% formater.
-rw-r--r--Lib/test/test_format.py2
-rw-r--r--Objects/bytesobject.c25
2 files changed, 17 insertions, 10 deletions
diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py
index 9b13632..9924fde 100644
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -300,6 +300,8 @@ class FormatTest(unittest.TestCase):
testcommon(b"%c", 7, b"\x07")
testcommon(b"%c", b"Z", b"Z")
testcommon(b"%c", bytearray(b"Z"), b"Z")
+ testcommon(b"%5c", 65, b" A")
+ testcommon(b"%-5c", 65, b"A ")
# %b will insert a series of bytes, either from a type that supports
# the Py_buffer protocol, or something that has a __bytes__ method
class FakeBytes(object):
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index fd46048..a75c54d 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -808,9 +808,8 @@ _PyBytes_Format(PyObject *format, PyObject *args)
fill = ' ';
switch (c) {
case '%':
- pbuf = "%";
- len = 1;
- break;
+ *res++ = '%';
+ continue;
case 'r':
// %r is only for 2/3 code; 3 only code should use %a
@@ -842,9 +841,9 @@ _PyBytes_Format(PyObject *format, PyObject *args)
case 'x':
case 'X':
if (PyLong_CheckExact(v)
- && width == -1 && prec == -1
- && !(flags & (F_SIGN | F_BLANK))
- && c != 'X')
+ && width == -1 && prec == -1
+ && !(flags & (F_SIGN | F_BLANK))
+ && c != 'X')
{
/* Fast path */
int alternate = flags & F_ALT;
@@ -869,7 +868,7 @@ _PyBytes_Format(PyObject *format, PyObject *args)
}
/* Fast path */
- writer.min_size -= 2; /* size preallocated by "%d" */
+ writer.min_size -= 2; /* size preallocated for "%d" */
res = _PyLong_FormatBytesWriter(&writer, res,
v, base, alternate);
if (res == NULL)
@@ -898,7 +897,7 @@ _PyBytes_Format(PyObject *format, PyObject *args)
&& !(flags & (F_SIGN | F_BLANK)))
{
/* Fast path */
- writer.min_size -= 2; /* size preallocated by "%f" */
+ writer.min_size -= 2; /* size preallocated for "%f" */
res = formatfloat(v, flags, prec, c, NULL, &writer, res);
if (res == NULL)
goto error;
@@ -919,6 +918,11 @@ _PyBytes_Format(PyObject *format, PyObject *args)
len = byte_converter(v, &onechar);
if (!len)
goto error;
+ if (width == -1) {
+ /* Fast path */
+ *res++ = onechar;
+ continue;
+ }
break;
default:
@@ -949,8 +953,9 @@ _PyBytes_Format(PyObject *format, PyObject *args)
alloc = width;
if (sign != 0 && len == width)
alloc++;
- if (alloc > 1) {
- res = _PyBytesWriter_Prepare(&writer, res, alloc - 1);
+ /* 2: size preallocated for %s */
+ if (alloc > 2) {
+ res = _PyBytesWriter_Prepare(&writer, res, alloc - 2);
if (res == NULL)
goto error;
}