aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Python/bltinmodule.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-02-12 07:53:52 +0300
committershadchin <shadchin@yandex-team.com>2024-02-12 08:07:36 +0300
commitce1b7ca3171f9158180640c6a02a74b4afffedea (patch)
treee47c1e8391b1b0128262c1e9b1e6ed4c8fff2348 /contrib/tools/python3/src/Python/bltinmodule.c
parent57350d96f030db90f220ce50ee591d5c5d403df7 (diff)
downloadydb-ce1b7ca3171f9158180640c6a02a74b4afffedea.tar.gz
Update Python from 3.11.8 to 3.12.2
Diffstat (limited to 'contrib/tools/python3/src/Python/bltinmodule.c')
-rw-r--r--contrib/tools/python3/src/Python/bltinmodule.c403
1 files changed, 220 insertions, 183 deletions
diff --git a/contrib/tools/python3/src/Python/bltinmodule.c b/contrib/tools/python3/src/Python/bltinmodule.c
index f30040507b..84fbc33a48 100644
--- a/contrib/tools/python3/src/Python/bltinmodule.c
+++ b/contrib/tools/python3/src/Python/bltinmodule.c
@@ -5,6 +5,7 @@
#include "pycore_ast.h" // _PyAST_Validate()
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_compile.h" // _PyAST_Compile()
+#include "pycore_long.h" // _PyLong_CompactValue
#include "pycore_object.h" // _Py_AddToAllObjects()
#include "pycore_pyerrors.h" // _PyErr_NoMemory()
#include "pycore_pystate.h" // _PyThreadState_GET()
@@ -63,8 +64,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
}
for (j = 0; j < i; j++) {
base = args[j];
- PyList_SET_ITEM(new_bases, j, base);
- Py_INCREF(base);
+ PyList_SET_ITEM(new_bases, j, Py_NewRef(base));
}
}
j = PyList_GET_SIZE(new_bases);
@@ -169,9 +169,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
goto error;
}
if (winner != meta) {
- Py_DECREF(meta);
- meta = winner;
- Py_INCREF(meta);
+ Py_SETREF(meta, Py_NewRef(winner));
}
}
/* else: meta is not a class, so we cannot do the metaclass
@@ -198,6 +196,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
goto error;
}
PyThreadState *tstate = _PyThreadState_GET();
+ EVAL_CALL_STAT_INC(EVAL_CALL_BUILD_CLASS);
cell = _PyEval_Vector(tstate, (PyFunctionObject *)func, ns, NULL, 0, NULL);
if (cell != NULL) {
if (bases != orig_bases) {
@@ -220,8 +219,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
"__class__ set to %.200R defining %.200R as %.200R";
PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls);
}
- Py_DECREF(cls);
- cls = NULL;
+ Py_SETREF(cls, NULL);
goto error;
}
}
@@ -678,16 +676,19 @@ format as builtin_format
format_spec: unicode(c_default="NULL") = ''
/
-Return value.__format__(format_spec)
+Return type(value).__format__(value, format_spec)
+
+Many built-in types implement format_spec according to the
+Format Specification Mini-language. See help('FORMATTING').
-format_spec defaults to the empty string.
-See the Format Specification Mini-Language section of help('FORMATTING') for
-details.
+If type(value) does not supply a method named __format__
+and format_spec is empty, then str(value) is returned.
+See also help('SPECIALMETHODS').
[clinic start generated code]*/
static PyObject *
builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec)
-/*[clinic end generated code: output=2f40bdfa4954b077 input=88339c93ea522b33]*/
+/*[clinic end generated code: output=2f40bdfa4954b077 input=45ef3934b86d5624]*/
{
return PyObject_Format(value, format_spec);
}
@@ -716,7 +717,7 @@ compile as builtin_compile
filename: object(converter="PyUnicode_FSDecoder")
mode: str
flags: int = 0
- dont_inherit: bool(accept={int}) = False
+ dont_inherit: bool = False
optimize: int = -1
*
_feature_version as feature_version: int = -1
@@ -739,7 +740,7 @@ static PyObject *
builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
const char *mode, int flags, int dont_inherit,
int optimize, int feature_version)
-/*[clinic end generated code: output=b0c09c84f116d3d7 input=40171fb92c1d580d]*/
+/*[clinic end generated code: output=b0c09c84f116d3d7 input=cc78e20e7c7682ba]*/
{
PyObject *source_copy;
const char *str;
@@ -802,8 +803,7 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
goto error;
if (is_ast) {
if (flags & PyCF_ONLY_AST) {
- Py_INCREF(source);
- result = source;
+ result = Py_NewRef(source);
}
else {
PyArena *arena;
@@ -840,31 +840,33 @@ finally:
return result;
}
-/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+/*[clinic input]
+dir as builtin_dir
+
+ arg: object = NULL
+ /
+
+Show attributes of an object.
+
+If called without an argument, return the names in the current scope.
+Else, return an alphabetized list of names comprising (some of) the attributes
+of the given object, and of attributes reachable from it.
+If the object supplies a method named __dir__, it will be used; otherwise
+the default dir() logic is used and returns:
+ for a module object: the module's attributes.
+ for a class object: its attributes, and recursively the attributes
+ of its bases.
+ for any other object: its attributes, its class's attributes, and
+ recursively the attributes of its class's base classes.
+[clinic start generated code]*/
+
static PyObject *
-builtin_dir(PyObject *self, PyObject *args)
+builtin_dir_impl(PyObject *module, PyObject *arg)
+/*[clinic end generated code: output=24f2c7a52c1e3b08 input=ed6d6ccb13d52251]*/
{
- PyObject *arg = NULL;
-
- if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg))
- return NULL;
return PyObject_Dir(arg);
}
-PyDoc_STRVAR(dir_doc,
-"dir([object]) -> list of strings\n"
-"\n"
-"If called without an argument, return the names in the current scope.\n"
-"Else, return an alphabetized list of names comprising (some of) the attributes\n"
-"of the given object, and of attributes reachable from it.\n"
-"If the object supplies a method named __dir__, it will be used; otherwise\n"
-"the default dir() logic is used and returns:\n"
-" for a module object: the module's attributes.\n"
-" for a class object: its attributes, and recursively the attributes\n"
-" of its bases.\n"
-" for any other object: its attributes, its class's attributes, and\n"
-" recursively the attributes of its class's base classes.");
-
/*[clinic input]
divmod as builtin_divmod
@@ -905,7 +907,7 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
PyObject *locals)
/*[clinic end generated code: output=0a0824aa70093116 input=11ee718a8640e527]*/
{
- PyObject *result, *source_copy;
+ PyObject *result = NULL, *source_copy;
const char *str;
if (locals != Py_None && !PyMapping_Check(locals)) {
@@ -921,19 +923,25 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
if (globals == Py_None) {
globals = PyEval_GetGlobals();
if (locals == Py_None) {
- locals = PyEval_GetLocals();
+ locals = _PyEval_GetFrameLocals();
if (locals == NULL)
return NULL;
}
+ else {
+ Py_INCREF(locals);
+ }
}
else if (locals == Py_None)
- locals = globals;
+ locals = Py_NewRef(globals);
+ else {
+ Py_INCREF(locals);
+ }
if (globals == NULL || locals == NULL) {
PyErr_SetString(PyExc_TypeError,
"eval must be given globals and locals "
"when called without a frame");
- return NULL;
+ goto error;
}
int r = PyDict_Contains(globals, &_Py_ID(__builtins__));
@@ -941,34 +949,38 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
r = PyDict_SetItem(globals, &_Py_ID(__builtins__), PyEval_GetBuiltins());
}
if (r < 0) {
- return NULL;
+ goto error;
}
if (PyCode_Check(source)) {
if (PySys_Audit("exec", "O", source) < 0) {
- return NULL;
+ goto error;
}
if (PyCode_GetNumFree((PyCodeObject *)source) > 0) {
PyErr_SetString(PyExc_TypeError,
"code object passed to eval() may not contain free variables");
- return NULL;
+ goto error;
}
- return PyEval_EvalCode(source, globals, locals);
+ result = PyEval_EvalCode(source, globals, locals);
}
+ else {
+ PyCompilerFlags cf = _PyCompilerFlags_INIT;
+ cf.cf_flags = PyCF_SOURCE_IS_UTF8;
+ str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy);
+ if (str == NULL)
+ goto error;
- PyCompilerFlags cf = _PyCompilerFlags_INIT;
- cf.cf_flags = PyCF_SOURCE_IS_UTF8;
- str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy);
- if (str == NULL)
- return NULL;
+ while (*str == ' ' || *str == '\t')
+ str++;
- while (*str == ' ' || *str == '\t')
- str++;
+ (void)PyEval_MergeCompilerFlags(&cf);
+ result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
+ Py_XDECREF(source_copy);
+ }
- (void)PyEval_MergeCompilerFlags(&cf);
- result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
- Py_XDECREF(source_copy);
+ error:
+ Py_XDECREF(locals);
return result;
}
@@ -1003,36 +1015,43 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
if (globals == Py_None) {
globals = PyEval_GetGlobals();
if (locals == Py_None) {
- locals = PyEval_GetLocals();
+ locals = _PyEval_GetFrameLocals();
if (locals == NULL)
return NULL;
}
+ else {
+ Py_INCREF(locals);
+ }
if (!globals || !locals) {
PyErr_SetString(PyExc_SystemError,
"globals and locals cannot be NULL");
return NULL;
}
}
- else if (locals == Py_None)
- locals = globals;
+ else if (locals == Py_None) {
+ locals = Py_NewRef(globals);
+ }
+ else {
+ Py_INCREF(locals);
+ }
if (!PyDict_Check(globals)) {
PyErr_Format(PyExc_TypeError, "exec() globals must be a dict, not %.100s",
Py_TYPE(globals)->tp_name);
- return NULL;
+ goto error;
}
if (!PyMapping_Check(locals)) {
PyErr_Format(PyExc_TypeError,
"locals must be a mapping or None, not %.100s",
Py_TYPE(locals)->tp_name);
- return NULL;
+ goto error;
}
int r = PyDict_Contains(globals, &_Py_ID(__builtins__));
if (r == 0) {
r = PyDict_SetItem(globals, &_Py_ID(__builtins__), PyEval_GetBuiltins());
}
if (r < 0) {
- return NULL;
+ goto error;
}
if (closure == Py_None) {
@@ -1045,7 +1064,7 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
if (closure) {
PyErr_SetString(PyExc_TypeError,
"cannot use a closure with this code object");
- return NULL;
+ goto error;
}
} else {
int closure_is_ok =
@@ -1065,12 +1084,12 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
PyErr_Format(PyExc_TypeError,
"code object requires a closure of exactly length %zd",
num_free);
- return NULL;
+ goto error;
}
}
if (PySys_Audit("exec", "O", source) < 0) {
- return NULL;
+ goto error;
}
if (!closure) {
@@ -1097,7 +1116,7 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
"string, bytes or code", &cf,
&source_copy);
if (str == NULL)
- return NULL;
+ goto error;
if (PyEval_MergeCompilerFlags(&cf))
v = PyRun_StringFlags(str, Py_file_input, globals,
locals, &cf);
@@ -1106,43 +1125,50 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
Py_XDECREF(source_copy);
}
if (v == NULL)
- return NULL;
+ goto error;
+ Py_DECREF(locals);
Py_DECREF(v);
Py_RETURN_NONE;
+
+ error:
+ Py_XDECREF(locals);
+ return NULL;
}
-/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+/*[clinic input]
+getattr as builtin_getattr
+
+ object: object
+ name: object
+ default: object = NULL
+ /
+
+Get a named attribute from an object.
+
+getattr(x, 'y') is equivalent to x.y
+When a default argument is given, it is returned when the attribute doesn't
+exist; without it, an exception is raised in that case.
+[clinic start generated code]*/
+
static PyObject *
-builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+builtin_getattr_impl(PyObject *module, PyObject *object, PyObject *name,
+ PyObject *default_value)
+/*[clinic end generated code: output=74ad0e225e3f701c input=d7562cd4c3556171]*/
{
- PyObject *v, *name, *result;
-
- if (!_PyArg_CheckPositional("getattr", nargs, 2, 3))
- return NULL;
+ PyObject *result;
- v = args[0];
- name = args[1];
- if (nargs > 2) {
- if (_PyObject_LookupAttr(v, name, &result) == 0) {
- PyObject *dflt = args[2];
- Py_INCREF(dflt);
- return dflt;
+ if (default_value != NULL) {
+ if (_PyObject_LookupAttr(object, name, &result) == 0) {
+ return Py_NewRef(default_value);
}
}
else {
- result = PyObject_GetAttr(v, name);
+ result = PyObject_GetAttr(object, name);
}
return result;
}
-PyDoc_STRVAR(getattr_doc,
-"getattr(object, name[, default]) -> value\n\
-\n\
-Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\
-When a default argument is given, it is returned when the attribute doesn't\n\
-exist; without it, an exception is raised in that case.");
-
/*[clinic input]
globals as builtin_globals
@@ -1160,8 +1186,7 @@ builtin_globals_impl(PyObject *module)
PyObject *d;
d = PyEval_GetGlobals();
- Py_XINCREF(d);
- return d;
+ return Py_XNewRef(d);
}
@@ -1388,12 +1413,10 @@ map_reduce(mapobject *lz, PyObject *Py_UNUSED(ignored))
Py_ssize_t i;
if (args == NULL)
return NULL;
- Py_INCREF(lz->func);
- PyTuple_SET_ITEM(args, 0, lz->func);
+ PyTuple_SET_ITEM(args, 0, Py_NewRef(lz->func));
for (i = 0; i<numargs; i++){
PyObject *it = PyTuple_GET_ITEM(lz->iters, i);
- Py_INCREF(it);
- PyTuple_SET_ITEM(args, i+1, it);
+ PyTuple_SET_ITEM(args, i+1, Py_NewRef(it));
}
return Py_BuildValue("ON", Py_TYPE(lz), args);
@@ -1457,35 +1480,43 @@ PyTypeObject PyMap_Type = {
};
-/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+/*[clinic input]
+next as builtin_next
+
+ iterator: object
+ default: object = NULL
+ /
+
+Return the next item from the iterator.
+
+If default is given and the iterator is exhausted,
+it is returned instead of raising StopIteration.
+[clinic start generated code]*/
+
static PyObject *
-builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+builtin_next_impl(PyObject *module, PyObject *iterator,
+ PyObject *default_value)
+/*[clinic end generated code: output=a38a94eeb447fef9 input=180f9984f182020f]*/
{
- PyObject *it, *res;
-
- if (!_PyArg_CheckPositional("next", nargs, 1, 2))
- return NULL;
+ PyObject *res;
- it = args[0];
- if (!PyIter_Check(it)) {
+ if (!PyIter_Check(iterator)) {
PyErr_Format(PyExc_TypeError,
"'%.200s' object is not an iterator",
- Py_TYPE(it)->tp_name);
+ Py_TYPE(iterator)->tp_name);
return NULL;
}
- res = (*Py_TYPE(it)->tp_iternext)(it);
+ res = (*Py_TYPE(iterator)->tp_iternext)(iterator);
if (res != NULL) {
return res;
- } else if (nargs > 1) {
- PyObject *def = args[1];
+ } else if (default_value != NULL) {
if (PyErr_Occurred()) {
if(!PyErr_ExceptionMatches(PyExc_StopIteration))
return NULL;
PyErr_Clear();
}
- Py_INCREF(def);
- return def;
+ return Py_NewRef(default_value);
} else if (PyErr_Occurred()) {
return NULL;
} else {
@@ -1494,12 +1525,6 @@ builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
}
}
-PyDoc_STRVAR(next_doc,
-"next(iterator[, default])\n\
-\n\
-Return the next item from the iterator. If default is given and the iterator\n\
-is exhausted, it is returned instead of raising StopIteration.");
-
/*[clinic input]
setattr as builtin_setattr
@@ -1592,34 +1617,33 @@ builtin_hex(PyObject *module, PyObject *number)
}
-/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+/*[clinic input]
+iter as builtin_iter
+
+ object: object
+ sentinel: object = NULL
+ /
+
+Get an iterator from an object.
+
+In the first form, the argument must supply its own iterator, or be a sequence.
+In the second form, the callable is called until it returns the sentinel.
+[clinic start generated code]*/
+
static PyObject *
-builtin_iter(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+builtin_iter_impl(PyObject *module, PyObject *object, PyObject *sentinel)
+/*[clinic end generated code: output=12cf64203c195a94 input=a5d64d9d81880ba6]*/
{
- PyObject *v;
-
- if (!_PyArg_CheckPositional("iter", nargs, 1, 2))
- return NULL;
- v = args[0];
- if (nargs == 1)
- return PyObject_GetIter(v);
- if (!PyCallable_Check(v)) {
+ if (sentinel == NULL)
+ return PyObject_GetIter(object);
+ if (!PyCallable_Check(object)) {
PyErr_SetString(PyExc_TypeError,
- "iter(v, w): v must be callable");
+ "iter(object, sentinel): object must be callable");
return NULL;
}
- PyObject *sentinel = args[1];
- return PyCallIter_New(v, sentinel);
+ return PyCallIter_New(object, sentinel);
}
-PyDoc_STRVAR(iter_doc,
-"iter(iterable) -> iterator\n\
-iter(callable, sentinel) -> iterator\n\
-\n\
-Get an iterator from an object. In the first form, the argument must\n\
-supply its own iterator, or be a sequence.\n\
-In the second form, the callable is called until it returns the sentinel.");
-
/*[clinic input]
aiter as builtin_aiter
@@ -1718,11 +1742,7 @@ static PyObject *
builtin_locals_impl(PyObject *module)
/*[clinic end generated code: output=b46c94015ce11448 input=7874018d478d5c4b]*/
{
- PyObject *d;
-
- d = PyEval_GetLocals();
- Py_XINCREF(d);
- return d;
+ return _PyEval_GetFrameLocals();
}
@@ -1783,8 +1803,7 @@ min_max(PyObject *args, PyObject *kwds, int op)
}
/* no key function; the value is the item */
else {
- val = item;
- Py_INCREF(val);
+ val = Py_NewRef(item);
}
/* maximum value and item are unset; set them */
@@ -1814,11 +1833,10 @@ min_max(PyObject *args, PyObject *kwds, int op)
if (maxval == NULL) {
assert(maxitem == NULL);
if (defaultval != NULL) {
- Py_INCREF(defaultval);
- maxitem = defaultval;
+ maxitem = Py_NewRef(defaultval);
} else {
PyErr_Format(PyExc_ValueError,
- "%s() arg is an empty sequence", name);
+ "%s() iterable argument is empty", name);
}
}
else
@@ -2341,7 +2359,7 @@ builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits)
{
PyObject *round, *result;
- if (Py_TYPE(number)->tp_dict == NULL) {
+ if (!_PyType_IsReady(Py_TYPE(number))) {
if (PyType_Ready(Py_TYPE(number)) < 0)
return NULL;
}
@@ -2425,21 +2443,29 @@ builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject
}
-/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
+/*[clinic input]
+vars as builtin_vars
+
+ object: object = NULL
+ /
+
+Show vars.
+
+Without arguments, equivalent to locals().
+With an argument, equivalent to object.__dict__.
+[clinic start generated code]*/
+
static PyObject *
-builtin_vars(PyObject *self, PyObject *args)
+builtin_vars_impl(PyObject *module, PyObject *object)
+/*[clinic end generated code: output=840a7f64007a3e0a input=80cbdef9182c4ba3]*/
{
- PyObject *v = NULL;
PyObject *d;
- if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v))
- return NULL;
- if (v == NULL) {
- d = PyEval_GetLocals();
- Py_XINCREF(d);
+ if (object == NULL) {
+ d = _PyEval_GetFrameLocals();
}
else {
- if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &d) == 0) {
+ if (_PyObject_LookupAttr(object, &_Py_ID(__dict__), &d) == 0) {
PyErr_SetString(PyExc_TypeError,
"vars() argument must have __dict__ attribute");
}
@@ -2447,12 +2473,6 @@ builtin_vars(PyObject *self, PyObject *args)
return d;
}
-PyDoc_STRVAR(vars_doc,
-"vars([object]) -> dictionary\n\
-\n\
-Without arguments, equivalent to locals().\n\
-With an argument, equivalent to object.__dict__.");
-
/*[clinic input]
sum as builtin_sum
@@ -2515,11 +2535,10 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
*/
if (PyLong_CheckExact(result)) {
int overflow;
- long i_result = PyLong_AsLongAndOverflow(result, &overflow);
+ Py_ssize_t i_result = PyLong_AsLongAndOverflow(result, &overflow);
/* If this already overflowed, don't even enter the loop. */
if (overflow == 0) {
- Py_DECREF(result);
- result = NULL;
+ Py_SETREF(result, NULL);
}
while(result == NULL) {
item = PyIter_Next(iter);
@@ -2527,18 +2546,17 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
Py_DECREF(iter);
if (PyErr_Occurred())
return NULL;
- return PyLong_FromLong(i_result);
+ return PyLong_FromSsize_t(i_result);
}
if (PyLong_CheckExact(item) || PyBool_Check(item)) {
- long b;
+ Py_ssize_t b;
overflow = 0;
/* Single digits are common, fast, and cannot overflow on unpacking. */
- switch (Py_SIZE(item)) {
- case -1: b = -(sdigit) ((PyLongObject*)item)->ob_digit[0]; break;
- // Note: the continue goes to the top of the "while" loop that iterates over the elements
- case 0: Py_DECREF(item); continue;
- case 1: b = ((PyLongObject*)item)->ob_digit[0]; break;
- default: b = PyLong_AsLongAndOverflow(item, &overflow); break;
+ if (_PyLong_IsCompact((PyLongObject *)item)) {
+ b = _PyLong_CompactValue((PyLongObject *)item);
+ }
+ else {
+ b = PyLong_AsLongAndOverflow(item, &overflow);
}
if (overflow == 0 &&
(i_result >= 0 ? (b <= LONG_MAX - i_result)
@@ -2550,7 +2568,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
}
}
/* Either overflowed or is not an int. Restore real objects and process normally */
- result = PyLong_FromLong(i_result);
+ result = PyLong_FromSsize_t(i_result);
if (result == NULL) {
Py_DECREF(item);
Py_DECREF(iter);
@@ -2569,18 +2587,36 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
if (PyFloat_CheckExact(result)) {
double f_result = PyFloat_AS_DOUBLE(result);
- Py_DECREF(result);
- result = NULL;
+ double c = 0.0;
+ Py_SETREF(result, NULL);
while(result == NULL) {
item = PyIter_Next(iter);
if (item == NULL) {
Py_DECREF(iter);
if (PyErr_Occurred())
return NULL;
+ /* Avoid losing the sign on a negative result,
+ and don't let adding the compensation convert
+ an infinite or overflowed sum to a NaN. */
+ if (c && Py_IS_FINITE(c)) {
+ f_result += c;
+ }
return PyFloat_FromDouble(f_result);
}
if (PyFloat_CheckExact(item)) {
- f_result += PyFloat_AS_DOUBLE(item);
+ // Improved Kahan–Babuška algorithm by Arnold Neumaier
+ // Neumaier, A. (1974), Rundungsfehleranalyse einiger Verfahren
+ // zur Summation endlicher Summen. Z. angew. Math. Mech.,
+ // 54: 39-51. https://doi.org/10.1002/zamm.19740540106
+ // https://en.wikipedia.org/wiki/Kahan_summation_algorithm#Further_enhancements
+ double x = PyFloat_AS_DOUBLE(item);
+ double t = f_result + x;
+ if (fabs(f_result) >= fabs(x)) {
+ c += (f_result - t) + x;
+ } else {
+ c += (x - t) + f_result;
+ }
+ f_result = t;
_Py_DECREF_SPECIALIZED(item, _PyFloat_ExactDealloc);
continue;
}
@@ -2594,6 +2630,9 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
continue;
}
}
+ if (c && Py_IS_FINITE(c)) {
+ f_result += c;
+ }
result = PyFloat_FromDouble(f_result);
if (result == NULL) {
Py_DECREF(item);
@@ -2617,8 +2656,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
if (item == NULL) {
/* error, or end-of-sequence */
if (PyErr_Occurred()) {
- Py_DECREF(result);
- result = NULL;
+ Py_SETREF(result, NULL);
}
break;
}
@@ -2759,8 +2797,7 @@ zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
for (i=0 ; i < tuplesize ; i++) {
- Py_INCREF(Py_None);
- PyTuple_SET_ITEM(result, i, Py_None);
+ PyTuple_SET_ITEM(result, i, Py_NewRef(Py_None));
}
/* create zipobject structure */
@@ -2987,12 +3024,12 @@ static PyMethodDef builtin_methods[] = {
BUILTIN_CHR_METHODDEF
BUILTIN_COMPILE_METHODDEF
BUILTIN_DELATTR_METHODDEF
- {"dir", builtin_dir, METH_VARARGS, dir_doc},
+ BUILTIN_DIR_METHODDEF
BUILTIN_DIVMOD_METHODDEF
BUILTIN_EVAL_METHODDEF
BUILTIN_EXEC_METHODDEF
BUILTIN_FORMAT_METHODDEF
- {"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, getattr_doc},
+ BUILTIN_GETATTR_METHODDEF
BUILTIN_GLOBALS_METHODDEF
BUILTIN_HASATTR_METHODDEF
BUILTIN_HASH_METHODDEF
@@ -3001,13 +3038,13 @@ static PyMethodDef builtin_methods[] = {
BUILTIN_INPUT_METHODDEF
BUILTIN_ISINSTANCE_METHODDEF
BUILTIN_ISSUBCLASS_METHODDEF
- {"iter", _PyCFunction_CAST(builtin_iter), METH_FASTCALL, iter_doc},
+ BUILTIN_ITER_METHODDEF
BUILTIN_AITER_METHODDEF
BUILTIN_LEN_METHODDEF
BUILTIN_LOCALS_METHODDEF
{"max", _PyCFunction_CAST(builtin_max), METH_VARARGS | METH_KEYWORDS, max_doc},
{"min", _PyCFunction_CAST(builtin_min), METH_VARARGS | METH_KEYWORDS, min_doc},
- {"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, next_doc},
+ BUILTIN_NEXT_METHODDEF
BUILTIN_ANEXT_METHODDEF
BUILTIN_OCT_METHODDEF
BUILTIN_ORD_METHODDEF
@@ -3018,7 +3055,7 @@ static PyMethodDef builtin_methods[] = {
BUILTIN_SETATTR_METHODDEF
BUILTIN_SORTED_METHODDEF
BUILTIN_SUM_METHODDEF
- {"vars", builtin_vars, METH_VARARGS, vars_doc},
+ BUILTIN_VARS_METHODDEF
{NULL, NULL},
};