#include "Python.h"
#include <ctype.h>
#include "pycore_ast.h"
#include "pycore_call.h"
#include "pycore_compile.h"
#include "pycore_long.h"
#include "pycore_object.h"
#include "pycore_pyerrors.h"
#include "pycore_pystate.h"
#include "pycore_tuple.h"
#include "pycore_ceval.h"
#include "clinic/bltinmodule.c.h"
static PyObject*
update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
{
Py_ssize_t i, j;
PyObject *base, *meth, *new_base, *result, *new_bases = NULL;
assert(PyTuple_Check(bases));
for (i = 0; i < nargs; i++) {
base = args[i];
if (PyType_Check(base)) {
if (new_bases) {
if (PyList_Append(new_bases, base) < 0) {
goto error;
}
}
continue;
}
if (_PyObject_LookupAttr(base, &_Py_ID(__mro_entries__), &meth) < 0) {
goto error;
}
if (!meth) {
if (new_bases) {
if (PyList_Append(new_bases, base) < 0) {
goto error;
}
}
continue;
}
new_base = PyObject_CallOneArg(meth, bases);
Py_DECREF(meth);
if (!new_base) {
goto error;
}
if (!PyTuple_Check(new_base)) {
PyErr_SetString(PyExc_TypeError,
"__mro_entries__ must return a tuple");
Py_DECREF(new_base);
goto error;
}
if (!new_bases) {
if (!(new_bases = PyList_New(i))) {
Py_DECREF(new_base);
goto error;
}
for (j = 0; j < i; j++) {
base = args[j];
PyList_SET_ITEM(new_bases, j, Py_NewRef(base));
}
}
j = PyList_GET_SIZE(new_bases);
if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
Py_DECREF(new_base);
goto error;
}
Py_DECREF(new_base);
}
if (!new_bases) {
return bases;
}
result = PyList_AsTuple(new_bases);
Py_DECREF(new_bases);
return result;
error:
Py_XDECREF(new_bases);
return NULL;
}
static PyObject *
builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
PyObject *kwnames)
{
PyObject *func, *name, *winner, *prep;
PyObject *cls = NULL, *cell = NULL, *ns = NULL, *meta = NULL, *orig_bases = NULL;
PyObject *mkw = NULL, *bases = NULL;
int isclass = 0;
if (nargs < 2) {
PyErr_SetString(PyExc_TypeError,
"__build_class__: not enough arguments");
return NULL;
}
func = args[0];
if (!PyFunction_Check(func)) {
PyErr_SetString(PyExc_TypeError,
"__build_class__: func must be a function");
return NULL;
}
name = args[1];
if (!PyUnicode_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"__build_class__: name is not a string");
return NULL;
}
orig_bases = _PyTuple_FromArray(args + 2, nargs - 2);
if (orig_bases == NULL)
return NULL;
bases = update_bases(orig_bases, args + 2, nargs - 2);
if (bases == NULL) {
Py_DECREF(orig_bases);
return NULL;
}
if (kwnames == NULL) {
meta = NULL;
mkw = NULL;
}
else {
mkw = _PyStack_AsDict(args + nargs, kwnames);
if (mkw == NULL) {
goto error;
}
meta = _PyDict_GetItemWithError(mkw, &_Py_ID(metaclass));
if (meta != NULL) {
Py_INCREF(meta);
if (PyDict_DelItem(mkw, &_Py_ID(metaclass)) < 0) {
goto error;
}
isclass = PyType_Check(meta);
}
else if (PyErr_Occurred()) {
goto error;
}
}
if (meta == NULL) {
if (PyTuple_GET_SIZE(bases) == 0) {
meta = (PyObject *) (&PyType_Type);
}
else {
PyObject *base0 = PyTuple_GET_ITEM(bases, 0);
meta = (PyObject *)Py_TYPE(base0);
}
Py_INCREF(meta);
isclass = 1;
}
if (isclass) {
winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta,
bases);
if (winner == NULL) {
goto error;
}
if (winner != meta) {
Py_SETREF(meta, Py_NewRef(winner));
}
}
if (_PyObject_LookupAttr(meta, &_Py_ID(__prepare__), &prep) < 0) {
ns = NULL;
}
else if (prep == NULL) {
ns = PyDict_New();
}
else {
PyObject *pargs[2] = {name, bases};
ns = PyObject_VectorcallDict(prep, pargs, 2, mkw);
Py_DECREF(prep);
}
if (ns == NULL) {
goto error;
}
if (!PyMapping_Check(ns)) {
PyErr_Format(PyExc_TypeError,
"%.200s.__prepare__() must return a mapping, not %.200s",
isclass ? ((PyTypeObject *)meta)->tp_name : "<metaclass>",
Py_TYPE(ns)->tp_name);
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) {
if (PyMapping_SetItemString(ns, "__orig_bases__", orig_bases) < 0) {
goto error;
}
}
PyObject *margs[3] = {name, bases, ns};
cls = PyObject_VectorcallDict(meta, margs, 3, mkw);
if (cls != NULL && PyType_Check(cls) && PyCell_Check(cell)) {
PyObject *cell_cls = PyCell_GET(cell);
if (cell_cls != cls) {
if (cell_cls == NULL) {
const char *msg =
"__class__ not set defining %.200R as %.200R. "
"Was __classcell__ propagated to type.__new__?";
PyErr_Format(PyExc_RuntimeError, msg, name, cls);
} else {
const char *msg =
"__class__ set to %.200R defining %.200R as %.200R";
PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls);
}
Py_SETREF(cls, NULL);
goto error;
}
}
}
error:
Py_XDECREF(cell);
Py_XDECREF(ns);
Py_XDECREF(meta);
Py_XDECREF(mkw);
if (bases != orig_bases) {
Py_DECREF(orig_bases);
}
Py_DECREF(bases);
return cls;
}
PyDoc_STRVAR(build_class_doc,
"__build_class__(func, name, /, *bases, [metaclass], **kwds) -> class\n\
\n\
Internal helper function used by the class statement.");
static PyObject *
builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals,
PyObject *locals, PyObject *fromlist, int level)
{
return PyImport_ImportModuleLevelObject(name, globals, locals,
fromlist, level);
}
static PyObject *
builtin_abs(PyObject *module, PyObject *x)
{
return PyNumber_Absolute(x);
}
static PyObject *
builtin_all(PyObject *module, PyObject *iterable)
{
PyObject *it, *item;
PyObject *(*iternext)(PyObject *);
int cmp;
it = PyObject_GetIter(iterable);
if (it == NULL)
return NULL;
iternext = *Py_TYPE(it)->tp_iternext;
for (;;) {
item = iternext(it);
if (item == NULL)
break;
cmp = PyObject_IsTrue(item);
Py_DECREF(item);
if (cmp < 0) {
Py_DECREF(it);
return NULL;
}
if (cmp == 0) {
Py_DECREF(it);
Py_RETURN_FALSE;
}
}
Py_DECREF(it);
if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
return NULL;
}
Py_RETURN_TRUE;
}
static PyObject *
builtin_any(PyObject *module, PyObject *iterable)
{
PyObject *it, *item;
PyObject *(*iternext)(PyObject *);
int cmp;
it = PyObject_GetIter(iterable);
if (it == NULL)
return NULL;
iternext = *Py_TYPE(it)->tp_iternext;
for (;;) {
item = iternext(it);
if (item == NULL)
break;
cmp = PyObject_IsTrue(item);
Py_DECREF(item);
if (cmp < 0) {
Py_DECREF(it);
return NULL;
}
if (cmp > 0) {
Py_DECREF(it);
Py_RETURN_TRUE;
}
}
Py_DECREF(it);
if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_StopIteration))
PyErr_Clear();
else
return NULL;
}
Py_RETURN_FALSE;
}
static PyObject *
builtin_ascii(PyObject *module, PyObject *obj)
{
return PyObject_ASCII(obj);
}
static PyObject *
builtin_bin(PyObject *module, PyObject *number)
{
return PyNumber_ToBase(number, 2);
}
static PyObject *
builtin_callable(PyObject *module, PyObject *obj)
{
return PyBool_FromLong((long)PyCallable_Check(obj));
}
static PyObject *
builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
{
PyObject *hook = PySys_GetObject("breakpointhook");
if (hook == NULL) {
PyErr_SetString(PyExc_RuntimeError, "lost sys.breakpointhook");
return NULL;
}
if (PySys_Audit("builtins.breakpoint", "O", hook) < 0) {
return NULL;
}
Py_INCREF(hook);
PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords);
Py_DECREF(hook);
return retval;
}
PyDoc_STRVAR(breakpoint_doc,
"breakpoint(*args, **kws)\n\
\n\
Call sys.breakpointhook(*args, **kws). sys.breakpointhook() must accept\n\
whatever arguments are passed.\n\
\n\
By default, this drops you into the pdb debugger.");
typedef struct {
PyObject_HEAD
PyObject *func;
PyObject *it;
} filterobject;
static PyObject *
filter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *func, *seq;
PyObject *it;
filterobject *lz;
if ((type == &PyFilter_Type || type->tp_init == PyFilter_Type.tp_init) &&
!_PyArg_NoKeywords("filter", kwds))
return NULL;
if (!PyArg_UnpackTuple(args, "filter", 2, 2, &func, &seq))
return NULL;
it = PyObject_GetIter(seq);
if (it == NULL)
return NULL;
lz = (filterobject *)type->tp_alloc(type, 0);
if (lz == NULL) {
Py_DECREF(it);
return NULL;
}
lz->func = Py_NewRef(func);
lz->it = it;
return (PyObject *)lz;
}
static PyObject *
filter_vectorcall(PyObject *type, PyObject * const*args,
size_t nargsf, PyObject *kwnames)
{
PyTypeObject *tp = _PyType_CAST(type);
if (tp == &PyFilter_Type && !_PyArg_NoKwnames("filter", kwnames)) {
return NULL;
}
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (!_PyArg_CheckPositional("filter", nargs, 2, 2)) {
return NULL;
}
PyObject *it = PyObject_GetIter(args[1]);
if (it == NULL) {
return NULL;
}
filterobject *lz = (filterobject *)tp->tp_alloc(tp, 0);
if (lz == NULL) {
Py_DECREF(it);
return NULL;
}
lz->func = Py_NewRef(args[0]);
lz->it = it;
return (PyObject *)lz;
}
static void
filter_dealloc(filterobject *lz)
{
PyObject_GC_UnTrack(lz);
Py_TRASHCAN_BEGIN(lz, filter_dealloc)
Py_XDECREF(lz->func);
Py_XDECREF(lz->it);
Py_TYPE(lz)->tp_free(lz);
Py_TRASHCAN_END
}
static int
filter_traverse(filterobject *lz, visitproc visit, void *arg)
{
Py_VISIT(lz->it);
Py_VISIT(lz->func);
return 0;
}
static PyObject *
filter_next(filterobject *lz)
{
PyObject *item;
PyObject *it = lz->it;
long ok;
PyObject *(*iternext)(PyObject *);
int checktrue = lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type;
iternext = *Py_TYPE(it)->tp_iternext;
for (;;) {
item = iternext(it);
if (item == NULL)
return NULL;
if (checktrue) {
ok = PyObject_IsTrue(item);
} else {
PyObject *good;
good = PyObject_CallOneArg(lz->func, item);
if (good == NULL) {
Py_DECREF(item);
return NULL;
}
ok = PyObject_IsTrue(good);
Py_DECREF(good);
}
if (ok > 0)
return item;
Py_DECREF(item);
if (ok < 0)
return NULL;
}
}
static PyObject *
filter_reduce(filterobject *lz, PyObject *Py_UNUSED(ignored))
{
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
}
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
static PyMethodDef filter_methods[] = {
{"__reduce__", _PyCFunction_CAST(filter_reduce), METH_NOARGS, reduce_doc},
{NULL, NULL}
};
PyDoc_STRVAR(filter_doc,
"filter(function or None, iterable) --> filter object\n\
\n\
Return an iterator yielding those items of iterable for which function(item)\n\
is true. If function is None, return the items that are true.");
PyTypeObject PyFilter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"filter",
sizeof(filterobject),
0,
(destructor)filter_dealloc,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
PyObject_GenericGetAttr,
0,
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE,
filter_doc,
(traverseproc)filter_traverse,
0,
0,
0,
PyObject_SelfIter,
(iternextfunc)filter_next,
filter_methods,
0,
0,
0,
0,
0,
0,
0,
0,
PyType_GenericAlloc,
filter_new,
PyObject_GC_Del,
.tp_vectorcall = (vectorcallfunc)filter_vectorcall
};
static PyObject *
builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec)
{
return PyObject_Format(value, format_spec);
}
static PyObject *
builtin_chr_impl(PyObject *module, int i)
{
return PyUnicode_FromOrdinal(i);
}
static PyObject *
builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
const char *mode, int flags, int dont_inherit,
int optimize, int feature_version)
{
PyObject *source_copy;
const char *str;
int compile_mode = -1;
int is_ast;
int start[] = {Py_file_input, Py_eval_input, Py_single_input, Py_func_type_input};
PyObject *result;
PyCompilerFlags cf = _PyCompilerFlags_INIT;
cf.cf_flags = flags | PyCF_SOURCE_IS_UTF8;
if (feature_version >= 0 && (flags & PyCF_ONLY_AST)) {
cf.cf_feature_version = feature_version;
}
if (flags &
~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_COMPILE_MASK))
{
PyErr_SetString(PyExc_ValueError,
"compile(): unrecognised flags");
goto error;
}
if (optimize < -1 || optimize > 2) {
PyErr_SetString(PyExc_ValueError,
"compile(): invalid optimize value");
goto error;
}
if (!dont_inherit) {
PyEval_MergeCompilerFlags(&cf);
}
if (strcmp(mode, "exec") == 0)
compile_mode = 0;
else if (strcmp(mode, "eval") == 0)
compile_mode = 1;
else if (strcmp(mode, "single") == 0)
compile_mode = 2;
else if (strcmp(mode, "func_type") == 0) {
if (!(flags & PyCF_ONLY_AST)) {
PyErr_SetString(PyExc_ValueError,
"compile() mode 'func_type' requires flag PyCF_ONLY_AST");
goto error;
}
compile_mode = 3;
}
else {
const char *msg;
if (flags & PyCF_ONLY_AST)
msg = "compile() mode must be 'exec', 'eval', 'single' or 'func_type'";
else
msg = "compile() mode must be 'exec', 'eval' or 'single'";
PyErr_SetString(PyExc_ValueError, msg);
goto error;
}
is_ast = PyAST_Check(source);
if (is_ast == -1)
goto error;
if (is_ast) {
if (flags & PyCF_ONLY_AST) {
result = Py_NewRef(source);
}
else {
PyArena *arena;
mod_ty mod;
arena = _PyArena_New();
if (arena == NULL)
goto error;
mod = PyAST_obj2mod(source, arena, compile_mode);
if (mod == NULL || !_PyAST_Validate(mod)) {
_PyArena_Free(arena);
goto error;
}
result = (PyObject*)_PyAST_Compile(mod, filename,
&cf, optimize, arena);
_PyArena_Free(arena);
}
goto finally;
}
str = _Py_SourceAsString(source, "compile", "string, bytes or AST", &cf, &source_copy);
if (str == NULL)
goto error;
result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize);
Py_XDECREF(source_copy);
goto finally;
error:
result = NULL;
finally:
Py_DECREF(filename);
return result;
}
static PyObject *
builtin_dir_impl(PyObject *module, PyObject *arg)
{
return PyObject_Dir(arg);
}
static PyObject *
builtin_divmod_impl(PyObject *module, PyObject *x, PyObject *y)
{
return PyNumber_Divmod(x, y);
}
static PyObject *
builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals,
PyObject *locals)
{
PyObject *result, *source_copy;
const char *str;
if (locals != Py_None && !PyMapping_Check(locals)) {
PyErr_SetString(PyExc_TypeError, "locals must be a mapping");
return NULL;
}
if (globals != Py_None && !PyDict_Check(globals)) {
PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ?
"globals must be a real dict; try eval(expr, {}, mapping)"
: "globals must be a dict");
return NULL;
}
if (globals == Py_None) {
globals = PyEval_GetGlobals();
if (locals == Py_None) {
locals = PyEval_GetLocals();
if (locals == NULL)
return NULL;
}
}
else if (locals == Py_None)
locals = globals;
if (globals == NULL || locals == NULL) {
PyErr_SetString(PyExc_TypeError,
"eval must be given globals and locals "
"when called without a frame");
return NULL;
}
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;
}
if (PyCode_Check(source)) {
if (PySys_Audit("exec", "O", source) < 0) {
return NULL;
}
if (PyCode_GetNumFree((PyCodeObject *)source) > 0) {
PyErr_SetString(PyExc_TypeError,
"code object passed to eval() may not contain free variables");
return NULL;
}
return PyEval_EvalCode(source, globals, locals);
}
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++;
(void)PyEval_MergeCompilerFlags(&cf);
result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
Py_XDECREF(source_copy);
return result;
}
static PyObject *
builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
PyObject *locals, PyObject *closure)
{
PyObject *v;
if (globals == Py_None) {
globals = PyEval_GetGlobals();
if (locals == Py_None) {
locals = PyEval_GetLocals();
if (locals == NULL)
return NULL;
}
if (!globals || !locals) {
PyErr_SetString(PyExc_SystemError,
"globals and locals cannot be NULL");
return NULL;
}
}
else if (locals == Py_None)
locals = globals;
if (!PyDict_Check(globals)) {
PyErr_Format(PyExc_TypeError, "exec() globals must be a dict, not %.100s",
Py_TYPE(globals)->tp_name);
return NULL;
}
if (!PyMapping_Check(locals)) {
PyErr_Format(PyExc_TypeError,
"locals must be a mapping or None, not %.100s",
Py_TYPE(locals)->tp_name);
return NULL;
}
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;
}
if (closure == Py_None) {
closure = NULL;
}
if (PyCode_Check(source)) {
Py_ssize_t num_free = PyCode_GetNumFree((PyCodeObject *)source);
if (num_free == 0) {
if (closure) {
PyErr_SetString(PyExc_TypeError,
"cannot use a closure with this code object");
return NULL;
}
} else {
int closure_is_ok =
closure
&& PyTuple_CheckExact(closure)
&& (PyTuple_GET_SIZE(closure) == num_free);
if (closure_is_ok) {
for (Py_ssize_t i = 0; i < num_free; i++) {
PyObject *cell = PyTuple_GET_ITEM(closure, i);
if (!PyCell_Check(cell)) {
closure_is_ok = 0;
break;
}
}
}
if (!closure_is_ok) {
PyErr_Format(PyExc_TypeError,
"code object requires a closure of exactly length %zd",
num_free);
return NULL;
}
}
if (PySys_Audit("exec", "O", source) < 0) {
return NULL;
}
if (!closure) {
v = PyEval_EvalCode(source, globals, locals);
} else {
v = PyEval_EvalCodeEx(source, globals, locals,
NULL, 0,
NULL, 0,
NULL, 0,
NULL,
closure);
}
}
else {
if (closure != NULL) {
PyErr_SetString(PyExc_TypeError,
"closure can only be used when source is a code object");
}
PyObject *source_copy;
const char *str;
PyCompilerFlags cf = _PyCompilerFlags_INIT;
cf.cf_flags = PyCF_SOURCE_IS_UTF8;
str = _Py_SourceAsString(source, "exec",
"string, bytes or code", &cf,
&source_copy);
if (str == NULL)
return NULL;
if (PyEval_MergeCompilerFlags(&cf))
v = PyRun_StringFlags(str, Py_file_input, globals,
locals, &cf);
else
v = PyRun_String(str, Py_file_input, globals, locals);
Py_XDECREF(source_copy);
}
if (v == NULL)
return NULL;
Py_DECREF(v);
Py_RETURN_NONE;
}
static PyObject *
builtin_getattr_impl(PyObject *module, PyObject *object, PyObject *name,
PyObject *default_value)
{
PyObject *result;
if (default_value != NULL) {
if (_PyObject_LookupAttr(object, name, &result) == 0) {
return Py_NewRef(default_value);
}
}
else {
result = PyObject_GetAttr(object, name);
}
return result;
}
static PyObject *
builtin_globals_impl(PyObject *module)
{
PyObject *d;
d = PyEval_GetGlobals();
return Py_XNewRef(d);
}
static PyObject *
builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name)
{
PyObject *v;
if (_PyObject_LookupAttr(obj, name, &v) < 0) {
return NULL;
}
if (v == NULL) {
Py_RETURN_FALSE;
}
Py_DECREF(v);
Py_RETURN_TRUE;
}
static PyObject *
builtin_id(PyModuleDef *self, PyObject *v)
{
PyObject *id = PyLong_FromVoidPtr(v);
if (id && PySys_Audit("builtins.id", "O", id) < 0) {
Py_DECREF(id);
return NULL;
}
return id;
}
typedef struct {
PyObject_HEAD
PyObject *iters;
PyObject *func;
} mapobject;
static PyObject *
map_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *it, *iters, *func;
mapobject *lz;
Py_ssize_t numargs, i;
if ((type == &PyMap_Type || type->tp_init == PyMap_Type.tp_init) &&
!_PyArg_NoKeywords("map", kwds))
return NULL;
numargs = PyTuple_Size(args);
if (numargs < 2) {
PyErr_SetString(PyExc_TypeError,
"map() must have at least two arguments.");
return NULL;
}
iters = PyTuple_New(numargs-1);
if (iters == NULL)
return NULL;
for (i=1 ; i<numargs ; i++) {
it = PyObject_GetIter(PyTuple_GET_ITEM(args, i));
if (it == NULL) {
Py_DECREF(iters);
return NULL;
}
PyTuple_SET_ITEM(iters, i-1, it);
}
lz = (mapobject *)type->tp_alloc(type, 0);
if (lz == NULL) {
Py_DECREF(iters);
return NULL;
}
lz->iters = iters;
func = PyTuple_GET_ITEM(args, 0);
lz->func = Py_NewRef(func);
return (PyObject *)lz;
}
static PyObject *
map_vectorcall(PyObject *type, PyObject * const*args,
size_t nargsf, PyObject *kwnames)
{
PyTypeObject *tp = _PyType_CAST(type);
if (tp == &PyMap_Type && !_PyArg_NoKwnames("map", kwnames)) {
return NULL;
}
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
if (nargs < 2) {
PyErr_SetString(PyExc_TypeError,
"map() must have at least two arguments.");
return NULL;
}
PyObject *iters = PyTuple_New(nargs-1);
if (iters == NULL) {
return NULL;
}
for (int i=1; i<nargs; i++) {
PyObject *it = PyObject_GetIter(args[i]);
if (it == NULL) {
Py_DECREF(iters);
return NULL;
}
PyTuple_SET_ITEM(iters, i-1, it);
}
mapobject *lz = (mapobject *)tp->tp_alloc(tp, 0);
if (lz == NULL) {
Py_DECREF(iters);
return NULL;
}
lz->iters = iters;
lz->func = Py_NewRef(args[0]);
return (PyObject *)lz;
}
static void
map_dealloc(mapobject *lz)
{
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->iters);
Py_XDECREF(lz->func);
Py_TYPE(lz)->tp_free(lz);
}
static int
map_traverse(mapobject *lz, visitproc visit, void *arg)
{
Py_VISIT(lz->iters);
Py_VISIT(lz->func);
return 0;
}
static PyObject *
map_next(mapobject *lz)
{
PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
PyObject **stack;
PyObject *result = NULL;
PyThreadState *tstate = _PyThreadState_GET();
const Py_ssize_t niters = PyTuple_GET_SIZE(lz->iters);
if (niters <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
stack = small_stack;
}
else {
stack = PyMem_Malloc(niters * sizeof(stack[0]));
if (stack == NULL) {
_PyErr_NoMemory(tstate);
return NULL;
}
}
Py_ssize_t nargs = 0;
for (Py_ssize_t i=0; i < niters; i++) {
PyObject *it = PyTuple_GET_ITEM(lz->iters, i);
PyObject *val = Py_TYPE(it)->tp_iternext(it);
if (val == NULL) {
goto exit;
}
stack[i] = val;
nargs++;
}
result = _PyObject_VectorcallTstate(tstate, lz->func, stack, nargs, NULL);
exit:
for (Py_ssize_t i=0; i < nargs; i++) {
Py_DECREF(stack[i]);
}
if (stack != small_stack) {
PyMem_Free(stack);
}
return result;
}
static PyObject *
map_reduce(mapobject *lz, PyObject *Py_UNUSED(ignored))
{
Py_ssize_t numargs = PyTuple_GET_SIZE(lz->iters);
PyObject *args = PyTuple_New(numargs+1);
Py_ssize_t i;
if (args == NULL)
return NULL;
PyTuple_SET_ITEM(args, 0, Py_NewRef(lz->func));
for (i = 0; i<numargs; i++){
PyObject *it = PyTuple_GET_ITEM(lz->iters, i);
PyTuple_SET_ITEM(args, i+1, Py_NewRef(it));
}
return Py_BuildValue("ON", Py_TYPE(lz), args);
}
static PyMethodDef map_methods[] = {
{"__reduce__", _PyCFunction_CAST(map_reduce), METH_NOARGS, reduce_doc},
{NULL, NULL}
};
PyDoc_STRVAR(map_doc,
"map(func, *iterables) --> map object\n\
\n\
Make an iterator that computes the function using arguments from\n\
each of the iterables. Stops when the shortest iterable is exhausted.");
PyTypeObject PyMap_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"map",
sizeof(mapobject),
0,
(destructor)map_dealloc,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
PyObject_GenericGetAttr,
0,
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE,
map_doc,
(traverseproc)map_traverse,
0,
0,
0,
PyObject_SelfIter,
(iternextfunc)map_next,
map_methods,
0,
0,
0,
0,
0,
0,
0,
0,
PyType_GenericAlloc,
map_new,
PyObject_GC_Del,
.tp_vectorcall = (vectorcallfunc)map_vectorcall
};
static PyObject *
builtin_next_impl(PyObject *module, PyObject *iterator,
PyObject *default_value)
{
PyObject *res;
if (!PyIter_Check(iterator)) {
PyErr_Format(PyExc_TypeError,
"'%.200s' object is not an iterator",
Py_TYPE(iterator)->tp_name);
return NULL;
}
res = (*Py_TYPE(iterator)->tp_iternext)(iterator);
if (res != NULL) {
return res;
} else if (default_value != NULL) {
if (PyErr_Occurred()) {
if(!PyErr_ExceptionMatches(PyExc_StopIteration))
return NULL;
PyErr_Clear();
}
return Py_NewRef(default_value);
} else if (PyErr_Occurred()) {
return NULL;
} else {
PyErr_SetNone(PyExc_StopIteration);
return NULL;
}
}
static PyObject *
builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name,
PyObject *value)
{
if (PyObject_SetAttr(obj, name, value) != 0)
return NULL;
Py_RETURN_NONE;
}
static PyObject *
builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name)
{
if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0)
return NULL;
Py_RETURN_NONE;
}
static PyObject *
builtin_hash(PyObject *module, PyObject *obj)
{
Py_hash_t x;
x = PyObject_Hash(obj);
if (x == -1)
return NULL;
return PyLong_FromSsize_t(x);
}
static PyObject *
builtin_hex(PyObject *module, PyObject *number)
{
return PyNumber_ToBase(number, 16);
}
static PyObject *
builtin_iter_impl(PyObject *module, PyObject *object, PyObject *sentinel)
{
if (sentinel == NULL)
return PyObject_GetIter(object);
if (!PyCallable_Check(object)) {
PyErr_SetString(PyExc_TypeError,
"iter(object, sentinel): object must be callable");
return NULL;
}
return PyCallIter_New(object, sentinel);
}
static PyObject *
builtin_aiter(PyObject *module, PyObject *async_iterable)
{
return PyObject_GetAIter(async_iterable);
}
PyObject *PyAnextAwaitable_New(PyObject *, PyObject *);
static PyObject *
builtin_anext_impl(PyObject *module, PyObject *aiterator,
PyObject *default_value)
{
PyTypeObject *t;
PyObject *awaitable;
t = Py_TYPE(aiterator);
if (t->tp_as_async == NULL || t->tp_as_async->am_anext == NULL) {
PyErr_Format(PyExc_TypeError,
"'%.200s' object is not an async iterator",
t->tp_name);
return NULL;
}
awaitable = (*t->tp_as_async->am_anext)(aiterator);
if (default_value == NULL) {
return awaitable;
}
PyObject* new_awaitable = PyAnextAwaitable_New(
awaitable, default_value);
Py_DECREF(awaitable);
return new_awaitable;
}
static PyObject *
builtin_len(PyObject *module, PyObject *obj)
{
Py_ssize_t res;
res = PyObject_Size(obj);
if (res < 0) {
assert(PyErr_Occurred());
return NULL;
}
return PyLong_FromSsize_t(res);
}
static PyObject *
builtin_locals_impl(PyObject *module)
{
PyObject *d;
d = PyEval_GetLocals();
return Py_XNewRef(d);
}
static PyObject *
min_max(PyObject *args, PyObject *kwds, int op)
{
PyObject *v, *it, *item, *val, *maxitem, *maxval, *keyfunc=NULL;
PyObject *emptytuple, *defaultval = NULL;
static char *kwlist[] = {"key", "default", NULL};
const char *name = op == Py_LT ? "min" : "max";
const int positional = PyTuple_Size(args) > 1;
int ret;
if (positional) {
v = args;
}
else if (!PyArg_UnpackTuple(args, name, 1, 1, &v)) {
if (PyExceptionClass_Check(PyExc_TypeError)) {
PyErr_Format(PyExc_TypeError, "%s expected at least 1 argument, got 0", name);
}
return NULL;
}
emptytuple = PyTuple_New(0);
if (emptytuple == NULL)
return NULL;
ret = PyArg_ParseTupleAndKeywords(emptytuple, kwds,
(op == Py_LT) ? "|$OO:min" : "|$OO:max",
kwlist, &keyfunc, &defaultval);
Py_DECREF(emptytuple);
if (!ret)
return NULL;
if (positional && defaultval != NULL) {
PyErr_Format(PyExc_TypeError,
"Cannot specify a default for %s() with multiple "
"positional arguments", name);
return NULL;
}
it = PyObject_GetIter(v);
if (it == NULL) {
return NULL;
}
if (keyfunc == Py_None) {
keyfunc = NULL;
}
maxitem = NULL;
maxval = NULL;
while (( item = PyIter_Next(it) )) {
if (keyfunc != NULL) {
val = PyObject_CallOneArg(keyfunc, item);
if (val == NULL)
goto Fail_it_item;
}
else {
val = Py_NewRef(item);
}
if (maxval == NULL) {
maxitem = item;
maxval = val;
}
else {
int cmp = PyObject_RichCompareBool(val, maxval, op);
if (cmp < 0)
goto Fail_it_item_and_val;
else if (cmp > 0) {
Py_DECREF(maxval);
Py_DECREF(maxitem);
maxval = val;
maxitem = item;
}
else {
Py_DECREF(item);
Py_DECREF(val);
}
}
}
if (PyErr_Occurred())
goto Fail_it;
if (maxval == NULL) {
assert(maxitem == NULL);
if (defaultval != NULL) {
maxitem = Py_NewRef(defaultval);
} else {
PyErr_Format(PyExc_ValueError,
"%s() iterable argument is empty", name);
}
}
else
Py_DECREF(maxval);
Py_DECREF(it);
return maxitem;
Fail_it_item_and_val:
Py_DECREF(val);
Fail_it_item:
Py_DECREF(item);
Fail_it:
Py_XDECREF(maxval);
Py_XDECREF(maxitem);
Py_DECREF(it);
return NULL;
}
static PyObject *
builtin_min(PyObject *self, PyObject *args, PyObject *kwds)
{
return min_max(args, kwds, Py_LT);
}
PyDoc_STRVAR(min_doc,
"min(iterable, *[, default=obj, key=func]) -> value\n\
min(arg1, arg2, *args, *[, key=func]) -> value\n\
\n\
With a single iterable argument, return its smallest item. The\n\
default keyword-only argument specifies an object to return if\n\
the provided iterable is empty.\n\
With two or more arguments, return the smallest argument.");
static PyObject *
builtin_max(PyObject *self, PyObject *args, PyObject *kwds)
{
return min_max(args, kwds, Py_GT);
}
PyDoc_STRVAR(max_doc,
"max(iterable, *[, default=obj, key=func]) -> value\n\
max(arg1, arg2, *args, *[, key=func]) -> value\n\
\n\
With a single iterable argument, return its biggest item. The\n\
default keyword-only argument specifies an object to return if\n\
the provided iterable is empty.\n\
With two or more arguments, return the largest argument.");
static PyObject *
builtin_oct(PyObject *module, PyObject *number)
{
return PyNumber_ToBase(number, 8);
}
static PyObject *
builtin_ord(PyObject *module, PyObject *c)
{
long ord;
Py_ssize_t size;
if (PyBytes_Check(c)) {
size = PyBytes_GET_SIZE(c);
if (size == 1) {
ord = (long)((unsigned char)*PyBytes_AS_STRING(c));
return PyLong_FromLong(ord);
}
}
else if (PyUnicode_Check(c)) {
size = PyUnicode_GET_LENGTH(c);
if (size == 1) {
ord = (long)PyUnicode_READ_CHAR(c, 0);
return PyLong_FromLong(ord);
}
}
else if (PyByteArray_Check(c)) {
size = PyByteArray_GET_SIZE(c);
if (size == 1) {
ord = (long)((unsigned char)*PyByteArray_AS_STRING(c));
return PyLong_FromLong(ord);
}
}
else {
PyErr_Format(PyExc_TypeError,
"ord() expected string of length 1, but " \
"%.200s found", Py_TYPE(c)->tp_name);
return NULL;
}
PyErr_Format(PyExc_TypeError,
"ord() expected a character, "
"but string of length %zd found",
size);
return NULL;
}
static PyObject *
builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp,
PyObject *mod)
{
return PyNumber_Power(base, exp, mod);
}
static PyObject *
builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep,
PyObject *end, PyObject *file, int flush)
{
int i, err;
if (file == Py_None) {
PyThreadState *tstate = _PyThreadState_GET();
file = _PySys_GetAttr(tstate, &_Py_ID(stdout));
if (file == NULL) {
PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
return NULL;
}
if (file == Py_None) {
Py_RETURN_NONE;
}
}
if (sep == Py_None) {
sep = NULL;
}
else if (sep && !PyUnicode_Check(sep)) {
PyErr_Format(PyExc_TypeError,
"sep must be None or a string, not %.200s",
Py_TYPE(sep)->tp_name);
return NULL;
}
if (end == Py_None) {
end = NULL;
}
else if (end && !PyUnicode_Check(end)) {
PyErr_Format(PyExc_TypeError,
"end must be None or a string, not %.200s",
Py_TYPE(end)->tp_name);
return NULL;
}
for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
if (i > 0) {
if (sep == NULL) {
err = PyFile_WriteString(" ", file);
}
else {
err = PyFile_WriteObject(sep, file, Py_PRINT_RAW);
}
if (err) {
return NULL;
}
}
err = PyFile_WriteObject(PyTuple_GET_ITEM(args, i), file, Py_PRINT_RAW);
if (err) {
return NULL;
}
}
if (end == NULL) {
err = PyFile_WriteString("\n", file);
}
else {
err = PyFile_WriteObject(end, file, Py_PRINT_RAW);
}
if (err) {
return NULL;
}
if (flush) {
PyObject *tmp = PyObject_CallMethodNoArgs(file, &_Py_ID(flush));
if (tmp == NULL) {
return NULL;
}
Py_DECREF(tmp);
}
Py_RETURN_NONE;
}
static PyObject *
builtin_input_impl(PyObject *module, PyObject *prompt)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *fin = _PySys_GetAttr(
tstate, &_Py_ID(stdin));
PyObject *fout = _PySys_GetAttr(
tstate, &_Py_ID(stdout));
PyObject *ferr = _PySys_GetAttr(
tstate, &_Py_ID(stderr));
PyObject *tmp;
long fd;
int tty;
if (fin == NULL || fin == Py_None) {
PyErr_SetString(PyExc_RuntimeError,
"input(): lost sys.stdin");
return NULL;
}
if (fout == NULL || fout == Py_None) {
PyErr_SetString(PyExc_RuntimeError,
"input(): lost sys.stdout");
return NULL;
}
if (ferr == NULL || ferr == Py_None) {
PyErr_SetString(PyExc_RuntimeError,
"input(): lost sys.stderr");
return NULL;
}
if (PySys_Audit("builtins.input", "O", prompt ? prompt : Py_None) < 0) {
return NULL;
}
tmp = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush));
if (tmp == NULL)
PyErr_Clear();
else
Py_DECREF(tmp);
tmp = PyObject_CallMethodNoArgs(fin, &_Py_ID(fileno));
if (tmp == NULL) {
PyErr_Clear();
tty = 0;
}
else {
fd = PyLong_AsLong(tmp);
Py_DECREF(tmp);
if (fd < 0 && PyErr_Occurred())
return NULL;
tty = fd == fileno(stdin) && isatty(fd);
}
if (tty) {
tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(fileno));
if (tmp == NULL) {
PyErr_Clear();
tty = 0;
}
else {
fd = PyLong_AsLong(tmp);
Py_DECREF(tmp);
if (fd < 0 && PyErr_Occurred())
return NULL;
tty = fd == fileno(stdout) && isatty(fd);
}
}
if (tty) {
PyObject *po = NULL;
const char *promptstr;
char *s = NULL;
PyObject *stdin_encoding = NULL, *stdin_errors = NULL;
PyObject *stdout_encoding = NULL, *stdout_errors = NULL;
const char *stdin_encoding_str, *stdin_errors_str;
PyObject *result;
size_t len;
stdin_encoding = PyObject_GetAttr(fin, &_Py_ID(encoding));
if (stdin_encoding == NULL) {
tty = 0;
goto _readline_errors;
}
stdin_errors = PyObject_GetAttr(fin, &_Py_ID(errors));
if (stdin_errors == NULL) {
tty = 0;
goto _readline_errors;
}
if (!PyUnicode_Check(stdin_encoding) ||
!PyUnicode_Check(stdin_errors))
{
tty = 0;
goto _readline_errors;
}
stdin_encoding_str = PyUnicode_AsUTF8(stdin_encoding);
if (stdin_encoding_str == NULL) {
goto _readline_errors;
}
stdin_errors_str = PyUnicode_AsUTF8(stdin_errors);
if (stdin_errors_str == NULL) {
goto _readline_errors;
}
tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush));
if (tmp == NULL)
PyErr_Clear();
else
Py_DECREF(tmp);
if (prompt != NULL) {
const char *stdout_encoding_str, *stdout_errors_str;
PyObject *stringpo;
stdout_encoding = PyObject_GetAttr(fout, &_Py_ID(encoding));
if (stdout_encoding == NULL) {
tty = 0;
goto _readline_errors;
}
stdout_errors = PyObject_GetAttr(fout, &_Py_ID(errors));
if (stdout_errors == NULL) {
tty = 0;
goto _readline_errors;
}
if (!PyUnicode_Check(stdout_encoding) ||
!PyUnicode_Check(stdout_errors))
{
tty = 0;
goto _readline_errors;
}
stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding);
if (stdout_encoding_str == NULL) {
goto _readline_errors;
}
stdout_errors_str = PyUnicode_AsUTF8(stdout_errors);
if (stdout_errors_str == NULL) {
goto _readline_errors;
}
stringpo = PyObject_Str(prompt);
if (stringpo == NULL)
goto _readline_errors;
po = PyUnicode_AsEncodedString(stringpo,
stdout_encoding_str, stdout_errors_str);
Py_CLEAR(stdout_encoding);
Py_CLEAR(stdout_errors);
Py_CLEAR(stringpo);
if (po == NULL)
goto _readline_errors;
assert(PyBytes_Check(po));
promptstr = PyBytes_AS_STRING(po);
}
else {
po = NULL;
promptstr = "";
}
s = PyOS_Readline(stdin, stdout, promptstr);
if (s == NULL) {
PyErr_CheckSignals();
if (!PyErr_Occurred())
PyErr_SetNone(PyExc_KeyboardInterrupt);
goto _readline_errors;
}
len = strlen(s);
if (len == 0) {
PyErr_SetNone(PyExc_EOFError);
result = NULL;
}
else {
if (len > PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError,
"input: input too long");
result = NULL;
}
else {
len--;
if (len != 0 && s[len-1] == '\r')
len--;
result = PyUnicode_Decode(s, len, stdin_encoding_str,
stdin_errors_str);
}
}
Py_DECREF(stdin_encoding);
Py_DECREF(stdin_errors);
Py_XDECREF(po);
PyMem_Free(s);
if (result != NULL) {
if (PySys_Audit("builtins.input/result", "O", result) < 0) {
return NULL;
}
}
return result;
_readline_errors:
Py_XDECREF(stdin_encoding);
Py_XDECREF(stdout_encoding);
Py_XDECREF(stdin_errors);
Py_XDECREF(stdout_errors);
Py_XDECREF(po);
if (tty)
return NULL;
PyErr_Clear();
}
if (prompt != NULL) {
if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0)
return NULL;
}
tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush));
if (tmp == NULL)
PyErr_Clear();
else
Py_DECREF(tmp);
return PyFile_GetLine(fin, -1);
}
static PyObject *
builtin_repr(PyObject *module, PyObject *obj)
{
return PyObject_Repr(obj);
}
static PyObject *
builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits)
{
PyObject *round, *result;
if (!_PyType_IsReady(Py_TYPE(number))) {
if (PyType_Ready(Py_TYPE(number)) < 0)
return NULL;
}
round = _PyObject_LookupSpecial(number, &_Py_ID(__round__));
if (round == NULL) {
if (!PyErr_Occurred())
PyErr_Format(PyExc_TypeError,
"type %.100s doesn't define __round__ method",
Py_TYPE(number)->tp_name);
return NULL;
}
if (ndigits == Py_None)
result = _PyObject_CallNoArgs(round);
else
result = PyObject_CallOneArg(round, ndigits);
Py_DECREF(round);
return result;
}
PyDoc_STRVAR(builtin_sorted__doc__,
"sorted($module, iterable, /, *, key=None, reverse=False)\n"
"--\n"
"\n"
"Return a new list containing all items from the iterable in ascending order.\n"
"\n"
"A custom key function can be supplied to customize the sort order, and the\n"
"reverse flag can be set to request the result in descending order.");
#define BUILTIN_SORTED_METHODDEF \
{"sorted", _PyCFunction_CAST(builtin_sorted), METH_FASTCALL | METH_KEYWORDS, builtin_sorted__doc__},
static PyObject *
builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *newlist, *v, *seq, *callable;
if (!_PyArg_UnpackStack(args, nargs, "sorted", 1, 1, &seq))
return NULL;
newlist = PySequence_List(seq);
if (newlist == NULL)
return NULL;
callable = PyObject_GetAttr(newlist, &_Py_ID(sort));
if (callable == NULL) {
Py_DECREF(newlist);
return NULL;
}
assert(nargs >= 1);
v = PyObject_Vectorcall(callable, args + 1, nargs - 1, kwnames);
Py_DECREF(callable);
if (v == NULL) {
Py_DECREF(newlist);
return NULL;
}
Py_DECREF(v);
return newlist;
}
static PyObject *
builtin_vars_impl(PyObject *module, PyObject *object)
{
PyObject *d;
if (object == NULL) {
d = Py_XNewRef(PyEval_GetLocals());
}
else {
if (_PyObject_LookupAttr(object, &_Py_ID(__dict__), &d) == 0) {
PyErr_SetString(PyExc_TypeError,
"vars() argument must have __dict__ attribute");
}
}
return d;
}
static PyObject *
builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
{
PyObject *result = start;
PyObject *temp, *item, *iter;
iter = PyObject_GetIter(iterable);
if (iter == NULL)
return NULL;
if (result == NULL) {
result = PyLong_FromLong(0);
if (result == NULL) {
Py_DECREF(iter);
return NULL;
}
} else {
if (PyUnicode_Check(result)) {
PyErr_SetString(PyExc_TypeError,
"sum() can't sum strings [use ''.join(seq) instead]");
Py_DECREF(iter);
return NULL;
}
if (PyBytes_Check(result)) {
PyErr_SetString(PyExc_TypeError,
"sum() can't sum bytes [use b''.join(seq) instead]");
Py_DECREF(iter);
return NULL;
}
if (PyByteArray_Check(result)) {
PyErr_SetString(PyExc_TypeError,
"sum() can't sum bytearray [use b''.join(seq) instead]");
Py_DECREF(iter);
return NULL;
}
Py_INCREF(result);
}
#ifndef SLOW_SUM
if (PyLong_CheckExact(result)) {
int overflow;
Py_ssize_t i_result = PyLong_AsLongAndOverflow(result, &overflow);
if (overflow == 0) {
Py_SETREF(result, NULL);
}
while(result == NULL) {
item = PyIter_Next(iter);
if (item == NULL) {
Py_DECREF(iter);
if (PyErr_Occurred())
return NULL;
return PyLong_FromSsize_t(i_result);
}
if (PyLong_CheckExact(item) || PyBool_Check(item)) {
Py_ssize_t b;
overflow = 0;
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)
: (b >= LONG_MIN - i_result)))
{
i_result += b;
Py_DECREF(item);
continue;
}
}
result = PyLong_FromSsize_t(i_result);
if (result == NULL) {
Py_DECREF(item);
Py_DECREF(iter);
return NULL;
}
temp = PyNumber_Add(result, item);
Py_DECREF(result);
Py_DECREF(item);
result = temp;
if (result == NULL) {
Py_DECREF(iter);
return NULL;
}
}
}
if (PyFloat_CheckExact(result)) {
double f_result = PyFloat_AS_DOUBLE(result);
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;
if (c && Py_IS_FINITE(c)) {
f_result += c;
}
return PyFloat_FromDouble(f_result);
}
if (PyFloat_CheckExact(item)) {
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;
}
if (PyLong_Check(item)) {
long value;
int overflow;
value = PyLong_AsLongAndOverflow(item, &overflow);
if (!overflow) {
f_result += (double)value;
Py_DECREF(item);
continue;
}
}
if (c && Py_IS_FINITE(c)) {
f_result += c;
}
result = PyFloat_FromDouble(f_result);
if (result == NULL) {
Py_DECREF(item);
Py_DECREF(iter);
return NULL;
}
temp = PyNumber_Add(result, item);
Py_DECREF(result);
Py_DECREF(item);
result = temp;
if (result == NULL) {
Py_DECREF(iter);
return NULL;
}
}
}
#endif
for(;;) {
item = PyIter_Next(iter);
if (item == NULL) {
if (PyErr_Occurred()) {
Py_SETREF(result, NULL);
}
break;
}
temp = PyNumber_Add(result, item);
Py_DECREF(result);
Py_DECREF(item);
result = temp;
if (result == NULL)
break;
}
Py_DECREF(iter);
return result;
}
static PyObject *
builtin_isinstance_impl(PyObject *module, PyObject *obj,
PyObject *class_or_tuple)
{
int retval;
retval = PyObject_IsInstance(obj, class_or_tuple);
if (retval < 0)
return NULL;
return PyBool_FromLong(retval);
}
static PyObject *
builtin_issubclass_impl(PyObject *module, PyObject *cls,
PyObject *class_or_tuple)
{
int retval;
retval = PyObject_IsSubclass(cls, class_or_tuple);
if (retval < 0)
return NULL;
return PyBool_FromLong(retval);
}
typedef struct {
PyObject_HEAD
Py_ssize_t tuplesize;
PyObject *ittuple;
PyObject *result;
int strict;
} zipobject;
static PyObject *
zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
zipobject *lz;
Py_ssize_t i;
PyObject *ittuple;
PyObject *result;
Py_ssize_t tuplesize;
int strict = 0;
if (kwds) {
PyObject *empty = PyTuple_New(0);
if (empty == NULL) {
return NULL;
}
static char *kwlist[] = {"strict", NULL};
int parsed = PyArg_ParseTupleAndKeywords(
empty, kwds, "|$p:zip", kwlist, &strict);
Py_DECREF(empty);
if (!parsed) {
return NULL;
}
}
assert(PyTuple_Check(args));
tuplesize = PyTuple_GET_SIZE(args);
ittuple = PyTuple_New(tuplesize);
if (ittuple == NULL)
return NULL;
for (i=0; i < tuplesize; ++i) {
PyObject *item = PyTuple_GET_ITEM(args, i);
PyObject *it = PyObject_GetIter(item);
if (it == NULL) {
Py_DECREF(ittuple);
return NULL;
}
PyTuple_SET_ITEM(ittuple, i, it);
}
result = PyTuple_New(tuplesize);
if (result == NULL) {
Py_DECREF(ittuple);
return NULL;
}
for (i=0 ; i < tuplesize ; i++) {
PyTuple_SET_ITEM(result, i, Py_NewRef(Py_None));
}
lz = (zipobject *)type->tp_alloc(type, 0);
if (lz == NULL) {
Py_DECREF(ittuple);
Py_DECREF(result);
return NULL;
}
lz->ittuple = ittuple;
lz->tuplesize = tuplesize;
lz->result = result;
lz->strict = strict;
return (PyObject *)lz;
}
static void
zip_dealloc(zipobject *lz)
{
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->ittuple);
Py_XDECREF(lz->result);
Py_TYPE(lz)->tp_free(lz);
}
static int
zip_traverse(zipobject *lz, visitproc visit, void *arg)
{
Py_VISIT(lz->ittuple);
Py_VISIT(lz->result);
return 0;
}
static PyObject *
zip_next(zipobject *lz)
{
Py_ssize_t i;
Py_ssize_t tuplesize = lz->tuplesize;
PyObject *result = lz->result;
PyObject *it;
PyObject *item;
PyObject *olditem;
if (tuplesize == 0)
return NULL;
if (Py_REFCNT(result) == 1) {
Py_INCREF(result);
for (i=0 ; i < tuplesize ; i++) {
it = PyTuple_GET_ITEM(lz->ittuple, i);
item = (*Py_TYPE(it)->tp_iternext)(it);
if (item == NULL) {
Py_DECREF(result);
if (lz->strict) {
goto check;
}
return NULL;
}
olditem = PyTuple_GET_ITEM(result, i);
PyTuple_SET_ITEM(result, i, item);
Py_DECREF(olditem);
}
if (!_PyObject_GC_IS_TRACKED(result)) {
_PyObject_GC_TRACK(result);
}
} else {
result = PyTuple_New(tuplesize);
if (result == NULL)
return NULL;
for (i=0 ; i < tuplesize ; i++) {
it = PyTuple_GET_ITEM(lz->ittuple, i);
item = (*Py_TYPE(it)->tp_iternext)(it);
if (item == NULL) {
Py_DECREF(result);
if (lz->strict) {
goto check;
}
return NULL;
}
PyTuple_SET_ITEM(result, i, item);
}
}
return result;
check:
if (PyErr_Occurred()) {
if (!PyErr_ExceptionMatches(PyExc_StopIteration)) {
return NULL;
}
PyErr_Clear();
}
if (i) {
const char* plural = i == 1 ? " " : "s 1-";
return PyErr_Format(PyExc_ValueError,
"zip() argument %d is shorter than argument%s%d",
i + 1, plural, i);
}
for (i = 1; i < tuplesize; i++) {
it = PyTuple_GET_ITEM(lz->ittuple, i);
item = (*Py_TYPE(it)->tp_iternext)(it);
if (item) {
Py_DECREF(item);
const char* plural = i == 1 ? " " : "s 1-";
return PyErr_Format(PyExc_ValueError,
"zip() argument %d is longer than argument%s%d",
i + 1, plural, i);
}
if (PyErr_Occurred()) {
if (!PyErr_ExceptionMatches(PyExc_StopIteration)) {
return NULL;
}
PyErr_Clear();
}
}
return NULL;
}
static PyObject *
zip_reduce(zipobject *lz, PyObject *Py_UNUSED(ignored))
{
if (lz->strict) {
return PyTuple_Pack(3, Py_TYPE(lz), lz->ittuple, Py_True);
}
return PyTuple_Pack(2, Py_TYPE(lz), lz->ittuple);
}
PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
static PyObject *
zip_setstate(zipobject *lz, PyObject *state)
{
int strict = PyObject_IsTrue(state);
if (strict < 0) {
return NULL;
}
lz->strict = strict;
Py_RETURN_NONE;
}
static PyMethodDef zip_methods[] = {
{"__reduce__", _PyCFunction_CAST(zip_reduce), METH_NOARGS, reduce_doc},
{"__setstate__", _PyCFunction_CAST(zip_setstate), METH_O, setstate_doc},
{NULL}
};
PyDoc_STRVAR(zip_doc,
"zip(*iterables, strict=False) --> Yield tuples until an input is exhausted.\n\
\n\
>>> list(zip('abcdefg', range(3), range(4)))\n\
[('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]\n\
\n\
The zip object yields n-length tuples, where n is the number of iterables\n\
passed as positional arguments to zip(). The i-th element in every tuple\n\
comes from the i-th iterable argument to zip(). This continues until the\n\
shortest argument is exhausted.\n\
\n\
If strict is true and one of the arguments is exhausted before the others,\n\
raise a ValueError.");
PyTypeObject PyZip_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"zip",
sizeof(zipobject),
0,
(destructor)zip_dealloc,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
PyObject_GenericGetAttr,
0,
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE,
zip_doc,
(traverseproc)zip_traverse,
0,
0,
0,
PyObject_SelfIter,
(iternextfunc)zip_next,
zip_methods,
0,
0,
0,
0,
0,
0,
0,
0,
PyType_GenericAlloc,
zip_new,
PyObject_GC_Del,
};
static PyMethodDef builtin_methods[] = {
{"__build_class__", _PyCFunction_CAST(builtin___build_class__),
METH_FASTCALL | METH_KEYWORDS, build_class_doc},
BUILTIN___IMPORT___METHODDEF
BUILTIN_ABS_METHODDEF
BUILTIN_ALL_METHODDEF
BUILTIN_ANY_METHODDEF
BUILTIN_ASCII_METHODDEF
BUILTIN_BIN_METHODDEF
{"breakpoint", _PyCFunction_CAST(builtin_breakpoint), METH_FASTCALL | METH_KEYWORDS, breakpoint_doc},
BUILTIN_CALLABLE_METHODDEF
BUILTIN_CHR_METHODDEF
BUILTIN_COMPILE_METHODDEF
BUILTIN_DELATTR_METHODDEF
BUILTIN_DIR_METHODDEF
BUILTIN_DIVMOD_METHODDEF
BUILTIN_EVAL_METHODDEF
BUILTIN_EXEC_METHODDEF
BUILTIN_FORMAT_METHODDEF
BUILTIN_GETATTR_METHODDEF
BUILTIN_GLOBALS_METHODDEF
BUILTIN_HASATTR_METHODDEF
BUILTIN_HASH_METHODDEF
BUILTIN_HEX_METHODDEF
BUILTIN_ID_METHODDEF
BUILTIN_INPUT_METHODDEF
BUILTIN_ISINSTANCE_METHODDEF
BUILTIN_ISSUBCLASS_METHODDEF
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},
BUILTIN_NEXT_METHODDEF
BUILTIN_ANEXT_METHODDEF
BUILTIN_OCT_METHODDEF
BUILTIN_ORD_METHODDEF
BUILTIN_POW_METHODDEF
BUILTIN_PRINT_METHODDEF
BUILTIN_REPR_METHODDEF
BUILTIN_ROUND_METHODDEF
BUILTIN_SETATTR_METHODDEF
BUILTIN_SORTED_METHODDEF
BUILTIN_SUM_METHODDEF
BUILTIN_VARS_METHODDEF
{NULL, NULL},
};
PyDoc_STRVAR(builtin_doc,
"Built-in functions, types, exceptions, and other objects.\n\
\n\
This module provides direct access to all 'built-in'\n\
identifiers of Python; for example, builtins.len is\n\
the full name for the built-in function len().\n\
\n\
This module is not normally accessed explicitly by most\n\
applications, but can be useful in modules that provide\n\
objects with the same name as a built-in value, but in\n\
which the built-in of that name is also needed.");
static struct PyModuleDef builtinsmodule = {
PyModuleDef_HEAD_INIT,
"builtins",
builtin_doc,
-1,
builtin_methods,
NULL,
NULL,
NULL,
NULL
};
PyObject *
_PyBuiltin_Init(PyInterpreterState *interp)
{
PyObject *mod, *dict, *debug;
const PyConfig *config = _PyInterpreterState_GetConfig(interp);
mod = _PyModule_CreateInitialized(&builtinsmodule, PYTHON_API_VERSION);
if (mod == NULL)
return NULL;
dict = PyModule_GetDict(mod);
#ifdef Py_TRACE_REFS
#define ADD_TO_ALL(OBJECT) _Py_AddToAllObjects((PyObject *)(OBJECT), 0)
#else
#define ADD_TO_ALL(OBJECT) (void)0
#endif
#define SETBUILTIN(NAME, OBJECT) \
if (PyDict_SetItemString(dict, NAME, (PyObject *)OBJECT) < 0) \
return NULL; \
ADD_TO_ALL(OBJECT)
SETBUILTIN("None", Py_None);
SETBUILTIN("Ellipsis", Py_Ellipsis);
SETBUILTIN("NotImplemented", Py_NotImplemented);
SETBUILTIN("False", Py_False);
SETBUILTIN("True", Py_True);
SETBUILTIN("bool", &PyBool_Type);
SETBUILTIN("memoryview", &PyMemoryView_Type);
SETBUILTIN("bytearray", &PyByteArray_Type);
SETBUILTIN("bytes", &PyBytes_Type);
SETBUILTIN("classmethod", &PyClassMethod_Type);
SETBUILTIN("complex", &PyComplex_Type);
SETBUILTIN("dict", &PyDict_Type);
SETBUILTIN("enumerate", &PyEnum_Type);
SETBUILTIN("filter", &PyFilter_Type);
SETBUILTIN("float", &PyFloat_Type);
SETBUILTIN("frozenset", &PyFrozenSet_Type);
SETBUILTIN("property", &PyProperty_Type);
SETBUILTIN("int", &PyLong_Type);
SETBUILTIN("list", &PyList_Type);
SETBUILTIN("map", &PyMap_Type);
SETBUILTIN("object", &PyBaseObject_Type);
SETBUILTIN("range", &PyRange_Type);
SETBUILTIN("reversed", &PyReversed_Type);
SETBUILTIN("set", &PySet_Type);
SETBUILTIN("slice", &PySlice_Type);
SETBUILTIN("staticmethod", &PyStaticMethod_Type);
SETBUILTIN("str", &PyUnicode_Type);
SETBUILTIN("super", &PySuper_Type);
SETBUILTIN("tuple", &PyTuple_Type);
SETBUILTIN("type", &PyType_Type);
SETBUILTIN("zip", &PyZip_Type);
debug = PyBool_FromLong(config->optimization_level == 0);
if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
Py_DECREF(debug);
return NULL;
}
Py_DECREF(debug);
return mod;
#undef ADD_TO_ALL
#undef SETBUILTIN
}