summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-09-06 19:07:53 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-09-06 19:07:53 (GMT)
commitea525a2d1a798f529b015f86b174d478806ac7ec (patch)
tree4ed79494c2a6a8e3460027a246020d25c1eaca16 /Objects
parent620bb277f89ba373b8c50e1a9fb9c8ba77a245c4 (diff)
downloadcpython-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.c20
-rw-r--r--Objects/unicodeobject.c42
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;