diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-09-06 19:07:53 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-09-06 19:07:53 (GMT) |
commit | ea525a2d1a798f529b015f86b174d478806ac7ec (patch) | |
tree | 4ed79494c2a6a8e3460027a246020d25c1eaca16 /Objects | |
parent | 620bb277f89ba373b8c50e1a9fb9c8ba77a245c4 (diff) | |
download | cpython-ea525a2d1a798f529b015f86b174d478806ac7ec.zip cpython-ea525a2d1a798f529b015f86b174d478806ac7ec.tar.gz cpython-ea525a2d1a798f529b015f86b174d478806ac7ec.tar.bz2 |
Issue #27078: Added BUILD_STRING opcode. Optimized f-strings evaluation.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 20 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 42 |
2 files changed, 43 insertions, 19 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 654fc02..d876dc5 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -675,13 +675,31 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) PyObject *result = NULL; _Py_IDENTIFIER(__format__); + if (format_spec != NULL && !PyUnicode_Check(format_spec)) { + PyErr_Format(PyExc_SystemError, + "Format specifier must be a string, not %.200s", + Py_TYPE(format_spec)->tp_name); + return NULL; + } + + /* Fast path for common types. */ + if (format_spec == NULL || PyUnicode_GET_LENGTH(format_spec) == 0) { + if (PyUnicode_CheckExact(obj)) { + Py_INCREF(obj); + return obj; + } + if (PyLong_CheckExact(obj)) { + return PyObject_Str(obj); + } + } + /* If no format_spec is provided, use an empty string */ if (format_spec == NULL) { empty = PyUnicode_New(0, 0); format_spec = empty; } - /* Find the (unbound!) __format__ method (a borrowed reference) */ + /* Find the (unbound!) __format__ method */ meth = _PyObject_LookupSpecial(obj, &PyId___format__); if (meth == NULL) { if (!PyErr_Occurred()) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 12d09f0..4256d05 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9892,20 +9892,10 @@ case_operation(PyObject *self, PyObject * PyUnicode_Join(PyObject *separator, PyObject *seq) { - PyObject *sep = NULL; - Py_ssize_t seplen; - PyObject *res = NULL; /* the result */ - PyObject *fseq; /* PySequence_Fast(seq) */ - Py_ssize_t seqlen; /* len(fseq) -- number of items in sequence */ + PyObject *res; + PyObject *fseq; + Py_ssize_t seqlen; PyObject **items; - PyObject *item; - Py_ssize_t sz, i, res_offset; - Py_UCS4 maxchar; - Py_UCS4 item_maxchar; - int use_memcpy; - unsigned char *res_data = NULL, *sep_data = NULL; - PyObject *last_obj; - unsigned int kind = 0; fseq = PySequence_Fast(seq, "can only join an iterable"); if (fseq == NULL) { @@ -9916,21 +9906,39 @@ PyUnicode_Join(PyObject *separator, PyObject *seq) * so we are sure that fseq won't be mutated. */ + items = PySequence_Fast_ITEMS(fseq); seqlen = PySequence_Fast_GET_SIZE(fseq); + res = _PyUnicode_JoinArray(separator, items, seqlen); + Py_DECREF(fseq); + return res; +} + +PyObject * +_PyUnicode_JoinArray(PyObject *separator, PyObject **items, Py_ssize_t seqlen) +{ + PyObject *res = NULL; /* the result */ + PyObject *sep = NULL; + Py_ssize_t seplen; + PyObject *item; + Py_ssize_t sz, i, res_offset; + Py_UCS4 maxchar; + Py_UCS4 item_maxchar; + int use_memcpy; + unsigned char *res_data = NULL, *sep_data = NULL; + PyObject *last_obj; + unsigned int kind = 0; + /* If empty sequence, return u"". */ if (seqlen == 0) { - Py_DECREF(fseq); _Py_RETURN_UNICODE_EMPTY(); } /* If singleton sequence with an exact Unicode, return that. */ last_obj = NULL; - items = PySequence_Fast_ITEMS(fseq); if (seqlen == 1) { if (PyUnicode_CheckExact(items[0])) { res = items[0]; Py_INCREF(res); - Py_DECREF(fseq); return res; } seplen = 0; @@ -10065,13 +10073,11 @@ PyUnicode_Join(PyObject *separator, PyObject *seq) assert(res_offset == PyUnicode_GET_LENGTH(res)); } - Py_DECREF(fseq); Py_XDECREF(sep); assert(_PyUnicode_CheckConsistency(res, 1)); return res; onError: - Py_DECREF(fseq); Py_XDECREF(sep); Py_XDECREF(res); return NULL; |