diff -urp Python-2.7.5.orig/Python/bltinmodule.c Python-2.7.5/Python/bltinmodule.c --- Python-2.7.5.orig/Python/bltinmodule.c 2013-05-12 06:32:53.000000000 +0300 +++ Python-2.7.5/Python/bltinmodule.c 2013-07-04 10:38:53.000000000 +0300 @@ -2313,13 +2313,6 @@ builtin_sum(PyObject *self, PyObject *ar return NULL; } } else { - /* reject string values for 'start' parameter */ - if (PyObject_TypeCheck(result, &PyBaseString_Type)) { - PyErr_SetString(PyExc_TypeError, - "sum() can't sum strings [use ''.join(seq) instead]"); - Py_DECREF(iter); - return NULL; - } Py_INCREF(result); } @@ -2399,6 +2392,97 @@ builtin_sum(PyObject *self, PyObject *ar } } } + + long subclass_flags = 0; + if (PyList_CheckExact(result)) + subclass_flags = Py_TPFLAGS_LIST_SUBCLASS; + else if (PyTuple_CheckExact(result)) + subclass_flags = Py_TPFLAGS_TUPLE_SUBCLASS; + else if (PyString_CheckExact(result)) + subclass_flags = Py_TPFLAGS_STRING_SUBCLASS; + + if (subclass_flags) { + PyObject *l_result = PyList_New(0); + if (l_result == NULL) { + Py_DECREF(result); + Py_DECREF(iter); + return NULL; + } + temp = _PyList_Extend((PyListObject*)l_result, result); + Py_DECREF(result); + result = NULL; + if (temp == NULL) { + Py_DECREF(l_result); + Py_DECREF(iter); + return NULL; + } + Py_DECREF(temp); + for (;;) { + item = PyIter_Next(iter); + if (item == NULL) { + if (PyErr_Occurred()) { + Py_DECREF(l_result); + return NULL; + } + break; + } + if (!PyType_FastSubclass(Py_TYPE(item), subclass_flags)) + break; + temp = _PyList_Extend((PyListObject*)l_result, item); + if (temp == NULL) + break; + Py_DECREF(item); + Py_DECREF(temp); + } + /* Not a subclass, could not extend, or end of sequence. Restore real objects ... */ + if (subclass_flags == Py_TPFLAGS_LIST_SUBCLASS) + result = l_result; + else if (subclass_flags == Py_TPFLAGS_TUPLE_SUBCLASS) { + result = PyList_AsTuple(l_result); + Py_DECREF(l_result); + if (result == NULL) { + Py_DECREF(item); + Py_DECREF(iter); + return NULL; + } + } + else /* subclass_flags == Py_TPFLAGS_STRING_SUBCLASS */ { + char *p; + Py_ssize_t i; + PyObject *char_string; + size_t sz = PyList_GET_SIZE(l_result); + /* Allocate result space. */ + result = PyString_FromStringAndSize((char*)NULL, sz); + if (result == NULL) { + Py_DECREF(l_result); + Py_DECREF(item); + Py_DECREF(iter); + return NULL; + } + /* Catenate everything. */ + p = PyString_AS_STRING(result); + for (i = 0; i < sz; ++i) { + char_string = PyList_GET_ITEM(l_result, i); + *p++ = *PyString_AS_STRING(char_string); + } + Py_DECREF(l_result); + } + /* ... and process normally */ + if (item == NULL) { + Py_DECREF(iter); + return result; + } + else { + temp = PyNumber_Add(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } + } #endif for(;;) {