| /* Built-in functions */ | |
| #include "Python.h" | |
| #include "pycore_ast.h" // _PyAST_Validate() | |
| #include "pycore_call.h" // _PyObject_CallNoArgs() | |
| #include "pycore_cell.h" // PyCell_GetRef() | |
| #include "pycore_ceval.h" // _PyEval_Vector() | |
| #include "pycore_compile.h" // _PyAST_Compile() | |
| #include "pycore_fileutils.h" // _PyFile_Flush | |
| #include "pycore_floatobject.h" // _PyFloat_ExactDealloc() | |
| #include "pycore_interp.h" // _PyInterpreterState_GetConfig() | |
| #include "pycore_import.h" // _PyImport_LazyImportModuleLevelObject () | |
| #include "pycore_iterobject.h" // _PyCallIter_NewEx() | |
| #include "pycore_long.h" // _PyLong_CompactValue | |
| #include "pycore_modsupport.h" // _PyArg_NoKwnames() | |
| #include "pycore_object.h" // _Py_AddToAllObjects() | |
| #include "pycore_pyerrors.h" // _PyErr_NoMemory() | |
| #include "pycore_pystate.h" // _PyThreadState_GET() | |
| #include "pycore_pythonrun.h" // _Py_SourceAsString() | |
| #include "pycore_tuple.h" // _PyTuple_Recycle() | |
| #include "clinic/bltinmodule.c.h" | |
| #ifdef HAVE_UNISTD_H | |
| # include <unistd.h> // isatty() | |
| #endif | |
| 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 we already have made a replacement, then we append every normal base, | |
| otherwise just skip it. */ | |
| if (PyList_Append(new_bases, base) < 0) { | |
| goto error; | |
| } | |
| } | |
| continue; | |
| } | |
| if (PyObject_GetOptionalAttr(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 this is a first successful replacement, create new_bases list and | |
| copy previously encountered 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; | |
| } | |
| /* AC: cannot convert yet, waiting for *args support */ | |
| 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; /* initialize to prevent gcc warning */ | |
| if (nargs < 2) { | |
| PyErr_SetString(PyExc_TypeError, | |
| "__build_class__: not enough arguments"); | |
| return NULL; | |
| } | |
| func = args[0]; /* Better be callable */ | |
| 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; | |
| } | |
| if (PyDict_Pop(mkw, &_Py_ID(metaclass), &meta) < 0) { | |
| goto error; | |
| } | |
| if (meta != NULL) { | |
| /* metaclass is explicitly given, check if it's indeed a class */ | |
| isclass = PyType_Check(meta); | |
| } | |
| } | |
| if (meta == NULL) { | |
| /* if there are no bases, use type: */ | |
| if (PyTuple_GET_SIZE(bases) == 0) { | |
| meta = (PyObject *) (&PyType_Type); | |
| } | |
| /* else get the type of the first base */ | |
| else { | |
| PyObject *base0 = PyTuple_GET_ITEM(bases, 0); | |
| meta = (PyObject *)Py_TYPE(base0); | |
| } | |
| Py_INCREF(meta); | |
| isclass = 1; /* meta is really a class */ | |
| } | |
| if (isclass) { | |
| /* meta is really a class, so check for a more derived | |
| metaclass, or possible metaclass conflicts: */ | |
| winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta, | |
| bases); | |
| if (winner == NULL) { | |
| goto error; | |
| } | |
| if (winner != meta) { | |
| Py_SETREF(meta, Py_NewRef(winner)); | |
| } | |
| } | |
| /* else: meta is not a class, so we cannot do the metaclass | |
| calculation, so we will use the explicitly given object as it is */ | |
| if (PyObject_GetOptionalAttr(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_GetRef((PyCellObject *)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_XDECREF(cell_cls); | |
| Py_SETREF(cls, NULL); | |
| goto error; | |
| } | |
| else { | |
| Py_DECREF(cell_cls); | |
| } | |
| } | |
| } | |
| 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."); | |
| /*[clinic input] | |
| __import__ as builtin___import__ | |
| name: object | |
| globals: object(c_default="NULL") = None | |
| locals: object(c_default="NULL") = None | |
| fromlist: object(c_default="NULL") = () | |
| level: int = 0 | |
| Import a module. | |
| Because this function is meant for use by the Python | |
| interpreter and not for general use, it is better to use | |
| importlib.import_module() to programmatically import a module. | |
| The globals argument is only used to determine the context; | |
| they are not modified. The locals argument is unused. The fromlist | |
| should be a list of names to emulate ``from name import ...``, or an | |
| empty list to emulate ``import name``. | |
| When importing a module from a package, note that __import__('A.B', ...) | |
| returns package A when fromlist is empty, but its submodule B when | |
| fromlist is not empty. The level argument is used to determine whether | |
| to perform absolute or relative imports: 0 is absolute, while a positive | |
| number is the number of parent directories to search relative to the | |
| current module. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals, | |
| PyObject *locals, PyObject *fromlist, int level) | |
| /*[clinic end generated code: output=4febeda88a0cd245 input=e3096a230383f72d]*/ | |
| { | |
| return PyImport_ImportModuleLevelObject(name, globals, locals, | |
| fromlist, level); | |
| } | |
| /*[clinic input] | |
| __lazy_import__ as builtin___lazy_import__ | |
| name: object | |
| globals: object(c_default="NULL") = None | |
| locals: object(c_default="NULL") = None | |
| fromlist: object(c_default="NULL") = () | |
| level: int = 0 | |
| Lazily imports a module. | |
| Returns either the module to be imported or a imp.lazy_module object | |
| which indicates the module to be lazily imported. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin___lazy_import___impl(PyObject *module, PyObject *name, | |
| PyObject *globals, PyObject *locals, | |
| PyObject *fromlist, int level) | |
| /*[clinic end generated code: output=300f1771094b9e8c input=9c85cccd6a885b9b]*/ | |
| { | |
| PyObject *builtins; | |
| PyThreadState *tstate = PyThreadState_GET(); | |
| if (globals == NULL) { | |
| globals = PyEval_GetGlobals(); | |
| if (globals == NULL) { | |
| PyErr_SetString(PyExc_TypeError, | |
| "__lazy_import__() missing globals " | |
| "when called without a frame"); | |
| return NULL; | |
| } | |
| } | |
| if (locals == NULL) { | |
| locals = globals; | |
| } | |
| if (!PyDict_Check(globals)) { | |
| PyErr_Format(PyExc_TypeError, | |
| "expect dict for globals, got %T", globals); | |
| return NULL; | |
| } | |
| if (PyDict_GetItemRef(globals, &_Py_ID(__builtins__), &builtins) < 0) { | |
| return NULL; | |
| } | |
| if (builtins == NULL) { | |
| PyErr_SetString(PyExc_ValueError, | |
| "unable to get builtins for lazy import"); | |
| return NULL; | |
| } | |
| if (PyModule_Check(builtins)) { | |
| PyObject *builtins_dict = Py_XNewRef(PyModule_GetDict(builtins)); | |
| if (builtins_dict == NULL) { | |
| Py_DECREF(builtins); | |
| PyErr_SetString(PyExc_AttributeError, | |
| "builtins module has no dict"); | |
| return NULL; | |
| } | |
| Py_SETREF(builtins, builtins_dict); | |
| } | |
| PyObject *res = _PyImport_LazyImportModuleLevelObject( | |
| tstate, name, builtins, globals, locals, fromlist, level); | |
| Py_DECREF(builtins); | |
| return res; | |
| } | |
| /*[clinic input] | |
| abs as builtin_abs | |
| number: object | |
| / | |
| Return the absolute value of the argument. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_abs(PyObject *module, PyObject *number) | |
| /*[clinic end generated code: output=861a9db97dee0595 input=a356196903543505]*/ | |
| { | |
| return PyNumber_Absolute(number); | |
| } | |
| /*[clinic input] | |
| all as builtin_all | |
| iterable: object | |
| / | |
| Return True if bool(x) is True for all values x in the iterable. | |
| If the iterable is empty, return True. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_all(PyObject *module, PyObject *iterable) | |
| /*[clinic end generated code: output=ca2a7127276f79b3 input=1a7c5d1bc3438a21]*/ | |
| { | |
| 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; | |
| } | |
| /*[clinic input] | |
| any as builtin_any | |
| iterable: object | |
| / | |
| Return True if bool(x) is True for any x in the iterable. | |
| If the iterable is empty, return False. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_any(PyObject *module, PyObject *iterable) | |
| /*[clinic end generated code: output=fa65684748caa60e input=41d7451c23384f24]*/ | |
| { | |
| 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; | |
| } | |
| /*[clinic input] | |
| ascii as builtin_ascii | |
| obj: object | |
| / | |
| Return an ASCII-only representation of an object. | |
| As repr(), return a string containing a printable representation of an | |
| object, but escape the non-ASCII characters in the string returned by | |
| repr() using \\x, \\u or \\U escapes. This generates a string similar | |
| to that returned by repr() in Python 2. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_ascii(PyObject *module, PyObject *obj) | |
| /*[clinic end generated code: output=6d37b3f0984c7eb9 input=4c62732e1b3a3cc9]*/ | |
| { | |
| return PyObject_ASCII(obj); | |
| } | |
| /*[clinic input] | |
| bin as builtin_bin | |
| integer: object | |
| / | |
| Return the binary representation of an integer. | |
| >>> bin(2796202) | |
| '0b1010101010101010101010' | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_bin(PyObject *module, PyObject *integer) | |
| /*[clinic end generated code: output=533f9388441805cc input=d16518f148341e70]*/ | |
| { | |
| return PyNumber_ToBase(integer, 2); | |
| } | |
| /*[clinic input] | |
| callable as builtin_callable | |
| obj: object | |
| / | |
| Return whether the object is callable (i.e., some kind of function). | |
| Note that classes are callable, as are instances of classes with a | |
| __call__() method. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_callable(PyObject *module, PyObject *obj) | |
| /*[clinic end generated code: output=2b095d59d934cb7e input=1423bab99cc41f58]*/ | |
| { | |
| 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_GetAttrString("breakpointhook"); | |
| if (hook == NULL) { | |
| return NULL; | |
| } | |
| if (PySys_Audit("builtins.breakpoint", "O", hook) < 0) { | |
| Py_DECREF(hook); | |
| return NULL; | |
| } | |
| PyObject *retval = PyObject_Vectorcall(hook, args, nargs, keywords); | |
| Py_DECREF(hook); | |
| return retval; | |
| } | |
| PyDoc_STRVAR(breakpoint_doc, | |
| "breakpoint($module, /, *args, **kws)\n\ | |
| --\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; | |
| #define _filterobject_CAST(op) ((filterobject *)(op)) | |
| 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; | |
| /* Get iterator. */ | |
| it = PyObject_GetIter(seq); | |
| if (it == NULL) | |
| return NULL; | |
| /* create filterobject structure */ | |
| 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(PyObject *self) | |
| { | |
| filterobject *lz = _filterobject_CAST(self); | |
| PyObject_GC_UnTrack(lz); | |
| Py_XDECREF(lz->func); | |
| Py_XDECREF(lz->it); | |
| Py_TYPE(lz)->tp_free(lz); | |
| } | |
| static int | |
| filter_traverse(PyObject *self, visitproc visit, void *arg) | |
| { | |
| filterobject *lz = _filterobject_CAST(self); | |
| Py_VISIT(lz->it); | |
| Py_VISIT(lz->func); | |
| return 0; | |
| } | |
| static PyObject * | |
| filter_next(PyObject *self) | |
| { | |
| filterobject *lz = _filterobject_CAST(self); | |
| 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(PyObject *self, PyObject *Py_UNUSED(ignored)) | |
| { | |
| filterobject *lz = _filterobject_CAST(self); | |
| 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__", filter_reduce, METH_NOARGS, reduce_doc}, | |
| {NULL, NULL} /* sentinel */ | |
| }; | |
| PyDoc_STRVAR(filter_doc, | |
| "filter(function, iterable, /)\n\ | |
| --\n\ | |
| \n\ | |
| Return an iterator yielding those items of iterable for which\n\ | |
| function(item) is true. If function is None, return the items that\n\ | |
| are true."); | |
| PyTypeObject PyFilter_Type = { | |
| PyVarObject_HEAD_INIT(&PyType_Type, 0) | |
| "filter", /* tp_name */ | |
| sizeof(filterobject), /* tp_basicsize */ | |
| 0, /* tp_itemsize */ | |
| /* methods */ | |
| filter_dealloc, /* tp_dealloc */ | |
| 0, /* tp_vectorcall_offset */ | |
| 0, /* tp_getattr */ | |
| 0, /* tp_setattr */ | |
| 0, /* tp_as_async */ | |
| 0, /* tp_repr */ | |
| 0, /* tp_as_number */ | |
| 0, /* tp_as_sequence */ | |
| 0, /* tp_as_mapping */ | |
| 0, /* tp_hash */ | |
| 0, /* tp_call */ | |
| 0, /* tp_str */ | |
| PyObject_GenericGetAttr, /* tp_getattro */ | |
| 0, /* tp_setattro */ | |
| 0, /* tp_as_buffer */ | |
| Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | |
| Py_TPFLAGS_BASETYPE, /* tp_flags */ | |
| filter_doc, /* tp_doc */ | |
| filter_traverse, /* tp_traverse */ | |
| 0, /* tp_clear */ | |
| 0, /* tp_richcompare */ | |
| 0, /* tp_weaklistoffset */ | |
| PyObject_SelfIter, /* tp_iter */ | |
| filter_next, /* tp_iternext */ | |
| filter_methods, /* tp_methods */ | |
| 0, /* tp_members */ | |
| 0, /* tp_getset */ | |
| 0, /* tp_base */ | |
| 0, /* tp_dict */ | |
| 0, /* tp_descr_get */ | |
| 0, /* tp_descr_set */ | |
| 0, /* tp_dictoffset */ | |
| 0, /* tp_init */ | |
| PyType_GenericAlloc, /* tp_alloc */ | |
| filter_new, /* tp_new */ | |
| PyObject_GC_Del, /* tp_free */ | |
| .tp_vectorcall = filter_vectorcall | |
| }; | |
| /*[clinic input] | |
| format as builtin_format | |
| value: object | |
| format_spec: unicode(c_default="NULL") = '' | |
| / | |
| Return type(value).__format__(value, format_spec) | |
| Many built-in types implement format_spec according to the | |
| Format Specification Mini-language. See help('FORMATTING'). | |
| 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=45ef3934b86d5624]*/ | |
| { | |
| return PyObject_Format(value, format_spec); | |
| } | |
| /*[clinic input] | |
| @permit_long_summary | |
| chr as builtin_chr | |
| i: object | |
| / | |
| Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_chr(PyObject *module, PyObject *i) | |
| /*[clinic end generated code: output=d34f25b8035a9b10 input=a9b255f2d2e503f0]*/ | |
| { | |
| int overflow; | |
| long v = PyLong_AsLongAndOverflow(i, &overflow); | |
| if (v == -1 && PyErr_Occurred()) { | |
| return NULL; | |
| } | |
| if (overflow) { | |
| v = overflow < 0 ? INT_MIN : INT_MAX; | |
| /* Allow PyUnicode_FromOrdinal() to raise an exception */ | |
| } | |
| #if SIZEOF_INT < SIZEOF_LONG | |
| else if (v < INT_MIN) { | |
| v = INT_MIN; | |
| } | |
| else if (v > INT_MAX) { | |
| v = INT_MAX; | |
| } | |
| #endif | |
| return PyUnicode_FromOrdinal(v); | |
| } | |
| /*[clinic input] | |
| @permit_long_summary | |
| compile as builtin_compile | |
| source: object | |
| filename: unicode_fs_decoded | |
| mode: str | |
| flags: int = 0 | |
| dont_inherit: bool = False | |
| optimize: int = -1 | |
| * | |
| module as modname: object = None | |
| _feature_version as feature_version: int = -1 | |
| Compile source into a code object that can be executed by exec() or eval(). | |
| The source code may represent a Python module, statement or | |
| expression. | |
| The filename will be used for run-time error messages. | |
| The mode must be 'exec' to compile a module, 'single' to compile a | |
| single (interactive) statement, or 'eval' to compile an expression. | |
| The flags argument, if present, controls which future statements | |
| influence the compilation of the code. | |
| The dont_inherit argument, if true, stops the compilation inheriting | |
| the effects of any future statements in effect in the code calling | |
| compile; if absent or false these statements do influence the | |
| compilation, in addition to any features explicitly specified. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, | |
| const char *mode, int flags, int dont_inherit, | |
| int optimize, PyObject *modname, int feature_version) | |
| /*[clinic end generated code: output=9a0dce1945917a86 input=444c4fe466a97279]*/ | |
| { | |
| 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; | |
| } | |
| /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */ | |
| if (optimize < -1 || optimize > 2) { | |
| PyErr_SetString(PyExc_ValueError, | |
| "compile(): invalid optimize value"); | |
| goto error; | |
| } | |
| if (modname == Py_None) { | |
| modname = NULL; | |
| } | |
| else if (!PyUnicode_Check(modname)) { | |
| PyErr_Format(PyExc_TypeError, | |
| "compile() argument 'module' must be str or None, not %T", | |
| modname); | |
| 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) { | |
| PyArena *arena = _PyArena_New(); | |
| if (arena == NULL) { | |
| goto error; | |
| } | |
| if (flags & PyCF_ONLY_AST) { | |
| mod_ty mod = PyAST_obj2mod(source, arena, compile_mode); | |
| if (mod == NULL || !_PyAST_Validate(mod)) { | |
| _PyArena_Free(arena); | |
| goto error; | |
| } | |
| int syntax_check_only = ((flags & PyCF_OPTIMIZED_AST) == PyCF_ONLY_AST); /* unoptiomized AST */ | |
| if (_PyCompile_AstPreprocess(mod, filename, &cf, optimize, arena, | |
| syntax_check_only, modname) < 0) | |
| { | |
| _PyArena_Free(arena); | |
| goto error; | |
| } | |
| result = PyAST_mod2obj(mod); | |
| } | |
| else { | |
| mod_ty 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, modname); | |
| } | |
| _PyArena_Free(arena); | |
| goto finally; | |
| } | |
| str = _Py_SourceAsString(source, "compile", "string, bytes or AST", &cf, &source_copy); | |
| if (str == NULL) | |
| goto error; | |
| #ifdef Py_GIL_DISABLED | |
| // Disable immortalization of code constants for explicit | |
| // compile() calls to get consistent frozen outputs between the default | |
| // and free-threaded builds. | |
| _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET(); | |
| tstate->suppress_co_const_immortalization++; | |
| #endif | |
| result = _Py_CompileString(str, filename, | |
| start[compile_mode], &cf, | |
| optimize, modname); | |
| #ifdef Py_GIL_DISABLED | |
| tstate->suppress_co_const_immortalization--; | |
| #endif | |
| Py_XDECREF(source_copy); | |
| goto finally; | |
| error: | |
| result = NULL; | |
| finally: | |
| return result; | |
| } | |
| /* AC: cannot convert yet, as needs PEP 457 group support in inspect */ | |
| /*[clinic input] | |
| dir as builtin_dir | |
| object as arg: object = NULL | |
| / | |
| Return an alphabetized list of the attributes of the 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_impl(PyObject *module, PyObject *arg) | |
| /*[clinic end generated code: output=24f2c7a52c1e3b08 input=7fe1b2a5ca9ae355]*/ | |
| { | |
| return PyObject_Dir(arg); | |
| } | |
| /*[clinic input] | |
| divmod as builtin_divmod | |
| x: object | |
| y: object | |
| / | |
| Return the tuple (x//y, x%y). Invariant: div*y + mod == x. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_divmod_impl(PyObject *module, PyObject *x, PyObject *y) | |
| /*[clinic end generated code: output=b06d8a5f6e0c745e input=175ad9c84ff41a85]*/ | |
| { | |
| return PyNumber_Divmod(x, y); | |
| } | |
| /*[clinic input] | |
| eval as builtin_eval | |
| source: object | |
| / | |
| globals: object = None | |
| locals: object = None | |
| Evaluate the given source in the context of globals and locals. | |
| The source may be a string representing a Python expression | |
| or a code object as returned by compile(). | |
| The globals must be a dictionary and locals can be any mapping, | |
| defaulting to the current globals and locals. | |
| If only globals is given, locals defaults to it. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, | |
| PyObject *locals) | |
| /*[clinic end generated code: output=0a0824aa70093116 input=7c7bce5299a89062]*/ | |
| { | |
| PyThreadState *tstate = _PyThreadState_GET(); | |
| PyObject *result = NULL, *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 && !PyAnyDict_Check(globals)) { | |
| PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ? | |
| "globals must be a real dict or a frozendict; " | |
| "try eval(expr, {}, mapping)" | |
| : "globals must be a dict or a frozendict"); | |
| return NULL; | |
| } | |
| int fromframe = 0; | |
| if (globals != Py_None) { | |
| Py_INCREF(globals); | |
| } | |
| else if (_PyEval_GetFrame() != NULL) { | |
| fromframe = 1; | |
| globals = PyEval_GetGlobals(); | |
| assert(globals != NULL); | |
| Py_INCREF(globals); | |
| } | |
| else { | |
| globals = _PyEval_GetGlobalsFromRunningMain(tstate); | |
| if (globals == NULL) { | |
| if (!_PyErr_Occurred(tstate)) { | |
| PyErr_SetString(PyExc_TypeError, | |
| "eval must be given globals and locals " | |
| "when called without a frame"); | |
| } | |
| return NULL; | |
| } | |
| Py_INCREF(globals); | |
| } | |
| if (locals != Py_None) { | |
| Py_INCREF(locals); | |
| } | |
| else if (fromframe) { | |
| locals = _PyEval_GetFrameLocals(); | |
| if (locals == NULL) { | |
| assert(PyErr_Occurred()); | |
| Py_DECREF(globals); | |
| return NULL; | |
| } | |
| } | |
| else { | |
| locals = Py_NewRef(globals); | |
| } | |
| if (_PyEval_EnsureBuiltins(tstate, globals, NULL) < 0) { | |
| goto error; | |
| } | |
| if (PyCode_Check(source)) { | |
| if (PySys_Audit("exec", "O", source) < 0) { | |
| goto error; | |
| } | |
| if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { | |
| PyErr_SetString(PyExc_TypeError, | |
| "code object passed to eval() may not contain free variables"); | |
| goto error; | |
| } | |
| 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; | |
| while (*str == ' ' || *str == '\t') | |
| str++; | |
| (void)PyEval_MergeCompilerFlags(&cf); | |
| #ifdef Py_GIL_DISABLED | |
| // Don't immortalize code constants for explicit eval() calls | |
| // to avoid memory leaks. | |
| _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET(); | |
| tstate->suppress_co_const_immortalization++; | |
| #endif | |
| result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); | |
| #ifdef Py_GIL_DISABLED | |
| tstate->suppress_co_const_immortalization--; | |
| #endif | |
| Py_XDECREF(source_copy); | |
| } | |
| error: | |
| Py_XDECREF(globals); | |
| Py_XDECREF(locals); | |
| return result; | |
| } | |
| /*[clinic input] | |
| exec as builtin_exec | |
| source: object | |
| / | |
| globals: object = None | |
| locals: object = None | |
| * | |
| closure: object(c_default="NULL") = None | |
| Execute the given source in the context of globals and locals. | |
| The source may be a string representing one or more Python statements | |
| or a code object as returned by compile(). | |
| The globals must be a dictionary and locals can be any mapping, | |
| defaulting to the current globals and locals. | |
| If only globals is given, locals defaults to it. | |
| The closure must be a tuple of cellvars, and can only be used | |
| when source is a code object requiring exactly that many cellvars. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, | |
| PyObject *locals, PyObject *closure) | |
| /*[clinic end generated code: output=7579eb4e7646743d input=25e989b6d87a3a21]*/ | |
| { | |
| PyThreadState *tstate = _PyThreadState_GET(); | |
| PyObject *v; | |
| int fromframe = 0; | |
| if (globals != Py_None) { | |
| Py_INCREF(globals); | |
| } | |
| else if (_PyEval_GetFrame() != NULL) { | |
| fromframe = 1; | |
| globals = PyEval_GetGlobals(); | |
| assert(globals != NULL); | |
| Py_INCREF(globals); | |
| } | |
| else { | |
| globals = _PyEval_GetGlobalsFromRunningMain(tstate); | |
| if (globals == NULL) { | |
| if (!_PyErr_Occurred(tstate)) { | |
| PyErr_SetString(PyExc_SystemError, | |
| "globals and locals cannot be NULL"); | |
| } | |
| goto error; | |
| } | |
| Py_INCREF(globals); | |
| } | |
| if (locals != Py_None) { | |
| Py_INCREF(locals); | |
| } | |
| else if (fromframe) { | |
| locals = _PyEval_GetFrameLocals(); | |
| if (locals == NULL) { | |
| assert(PyErr_Occurred()); | |
| Py_DECREF(globals); | |
| return NULL; | |
| } | |
| } | |
| else { | |
| locals = Py_NewRef(globals); | |
| } | |
| if (!PyAnyDict_Check(globals)) { | |
| PyErr_Format(PyExc_TypeError, | |
| "exec() globals must be a dict or a frozendict, not %T", | |
| globals); | |
| goto error; | |
| } | |
| if (!PyMapping_Check(locals)) { | |
| PyErr_Format(PyExc_TypeError, | |
| "locals must be a mapping or None, not %.100s", | |
| Py_TYPE(locals)->tp_name); | |
| goto error; | |
| } | |
| if (_PyEval_EnsureBuiltins(tstate, globals, NULL) < 0) { | |
| goto error; | |
| } | |
| 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"); | |
| goto error; | |
| } | |
| } 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); | |
| goto error; | |
| } | |
| } | |
| if (PySys_Audit("exec", "O", source) < 0) { | |
| goto error; | |
| } | |
| 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"); | |
| goto error; | |
| } | |
| 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) | |
| goto error; | |
| 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) | |
| goto error; | |
| Py_DECREF(globals); | |
| Py_DECREF(locals); | |
| Py_DECREF(v); | |
| Py_RETURN_NONE; | |
| error: | |
| Py_XDECREF(globals); | |
| Py_XDECREF(locals); | |
| return NULL; | |
| } | |
| /* AC: cannot convert yet, as needs PEP 457 group support in inspect */ | |
| static PyObject * | |
| builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | |
| { | |
| PyObject *v, *name, *result; | |
| if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) | |
| return NULL; | |
| v = args[0]; | |
| name = args[1]; | |
| if (nargs > 2) { | |
| if (PyObject_GetOptionalAttr(v, name, &result) == 0) { | |
| PyObject *dflt = args[2]; | |
| return Py_NewRef(dflt); | |
| } | |
| } | |
| else { | |
| result = PyObject_GetAttr(v, name); | |
| } | |
| return result; | |
| } | |
| PyDoc_STRVAR(getattr_doc, | |
| "getattr(object, name[, default]) -> value\n\ | |
| \n\ | |
| Get a named attribute from an object.\n\ | |
| \n\ | |
| getattr(x, 'y') is equivalent to x.y.\n\ | |
| When a default argument is given, it is returned when the attribute\n\ | |
| doesn't exist; without it, an exception is raised in that case."); | |
| /*[clinic input] | |
| globals as builtin_globals | |
| Return the dictionary containing the current scope's global variables. | |
| NOTE: Updates to this dictionary *will* affect name lookups in the | |
| current global scope and vice-versa. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_globals_impl(PyObject *module) | |
| /*[clinic end generated code: output=e5dd1527067b94d2 input=6d725a9b48d1eaeb]*/ | |
| { | |
| PyObject *globals; | |
| if (_PyEval_GetFrame() != NULL) { | |
| globals = PyEval_GetGlobals(); | |
| assert(globals != NULL); | |
| return Py_NewRef(globals); | |
| } | |
| PyThreadState *tstate = _PyThreadState_GET(); | |
| globals = _PyEval_GetGlobalsFromRunningMain(tstate); | |
| if (globals == NULL) { | |
| if (_PyErr_Occurred(tstate)) { | |
| return NULL; | |
| } | |
| Py_RETURN_NONE; | |
| } | |
| return Py_NewRef(globals); | |
| } | |
| /*[clinic input] | |
| hasattr as builtin_hasattr | |
| obj: object | |
| name: object | |
| / | |
| Return whether the object has an attribute with the given name. | |
| This is done by calling getattr(obj, name) and catching AttributeError. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name) | |
| /*[clinic end generated code: output=a7aff2090a4151e5 input=0faec9787d979542]*/ | |
| { | |
| PyObject *v; | |
| if (PyObject_GetOptionalAttr(obj, name, &v) < 0) { | |
| return NULL; | |
| } | |
| if (v == NULL) { | |
| Py_RETURN_FALSE; | |
| } | |
| Py_DECREF(v); | |
| Py_RETURN_TRUE; | |
| } | |
| /* AC: gdb's integration with CPython relies on builtin_id having | |
| * the *exact* parameter names of "self" and "v", so we ensure we | |
| * preserve those name rather than using the AC defaults. | |
| */ | |
| /*[clinic input] | |
| id as builtin_id | |
| self: self(type="PyModuleDef *") | |
| obj as v: object | |
| / | |
| Return the identity of an object. | |
| This is guaranteed to be unique among simultaneously existing objects. | |
| (CPython uses the object's memory address.) | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_id_impl(PyModuleDef *self, PyObject *v) | |
| /*[clinic end generated code: output=4908a6782ed343e9 input=5a534136419631f4]*/ | |
| { | |
| PyObject *id = PyLong_FromVoidPtr(v); | |
| if (id && PySys_Audit("builtins.id", "O", id) < 0) { | |
| Py_DECREF(id); | |
| return NULL; | |
| } | |
| return id; | |
| } | |
| /* map object ************************************************************/ | |
| typedef struct { | |
| PyObject_HEAD | |
| PyObject *iters; | |
| PyObject *func; | |
| int strict; | |
| } mapobject; | |
| #define _mapobject_CAST(op) ((mapobject *)(op)) | |
| static PyObject * | |
| map_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| { | |
| PyObject *it, *iters, *func; | |
| mapobject *lz; | |
| Py_ssize_t numargs, i; | |
| 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:map", kwlist, &strict); | |
| Py_DECREF(empty); | |
| if (!parsed) { | |
| 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++) { | |
| /* Get iterator. */ | |
| it = PyObject_GetIter(PyTuple_GET_ITEM(args, i)); | |
| if (it == NULL) { | |
| Py_DECREF(iters); | |
| return NULL; | |
| } | |
| PyTuple_SET_ITEM(iters, i-1, it); | |
| } | |
| /* create mapobject structure */ | |
| 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); | |
| lz->strict = strict; | |
| return (PyObject *)lz; | |
| } | |
| static PyObject * | |
| map_vectorcall(PyObject *type, PyObject * const*args, | |
| size_t nargsf, PyObject *kwnames) | |
| { | |
| PyTypeObject *tp = _PyType_CAST(type); | |
| Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | |
| if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) != 0) { | |
| // Fallback to map_new() | |
| PyThreadState *tstate = _PyThreadState_GET(); | |
| return _PyObject_MakeTpCall(tstate, type, args, nargs, kwnames); | |
| } | |
| 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]); | |
| lz->strict = 0; | |
| return (PyObject *)lz; | |
| } | |
| static void | |
| map_dealloc(PyObject *self) | |
| { | |
| mapobject *lz = _mapobject_CAST(self); | |
| PyObject_GC_UnTrack(lz); | |
| Py_XDECREF(lz->iters); | |
| Py_XDECREF(lz->func); | |
| Py_TYPE(lz)->tp_free(lz); | |
| } | |
| static int | |
| map_traverse(PyObject *self, visitproc visit, void *arg) | |
| { | |
| mapobject *lz = _mapobject_CAST(self); | |
| Py_VISIT(lz->iters); | |
| Py_VISIT(lz->func); | |
| return 0; | |
| } | |
| static PyObject * | |
| map_next(PyObject *self) | |
| { | |
| mapobject *lz = _mapobject_CAST(self); | |
| Py_ssize_t i; | |
| 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 (i = 0; i < niters; i++) { | |
| PyObject *it = PyTuple_GET_ITEM(lz->iters, i); | |
| PyObject *val = Py_TYPE(it)->tp_iternext(it); | |
| if (val == NULL) { | |
| if (lz->strict) { | |
| goto check; | |
| } | |
| goto exit_no_result; | |
| } | |
| stack[i] = val; | |
| nargs++; | |
| } | |
| result = _PyObject_VectorcallTstate(tstate, lz->func, stack, nargs, NULL); | |
| goto exit; | |
| check: | |
| if (PyErr_Occurred()) { | |
| if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { | |
| // next() on argument i raised an exception (not StopIteration) | |
| goto exit_no_result; | |
| } | |
| PyErr_Clear(); | |
| } | |
| if (i) { | |
| // ValueError: map() argument 2 is shorter than argument 1 | |
| // ValueError: map() argument 3 is shorter than arguments 1-2 | |
| const char* plural = i == 1 ? " " : "s 1-"; | |
| PyErr_Format(PyExc_ValueError, | |
| "map() argument %zd is shorter than argument%s%zd", | |
| i + 1, plural, i); | |
| goto exit_no_result; | |
| } | |
| for (i = 1; i < niters; i++) { | |
| PyObject *it = PyTuple_GET_ITEM(lz->iters, i); | |
| PyObject *val = (*Py_TYPE(it)->tp_iternext)(it); | |
| if (val) { | |
| Py_DECREF(val); | |
| const char* plural = i == 1 ? " " : "s 1-"; | |
| PyErr_Format(PyExc_ValueError, | |
| "map() argument %zd is longer than argument%s%zd", | |
| i + 1, plural, i); | |
| goto exit_no_result; | |
| } | |
| if (PyErr_Occurred()) { | |
| if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { | |
| // next() on argument i raised an exception (not StopIteration) | |
| goto exit_no_result; | |
| } | |
| PyErr_Clear(); | |
| } | |
| // Argument i is exhausted. So far so good... | |
| } | |
| // All arguments are exhausted. Success! | |
| exit_no_result: | |
| assert(result == NULL); | |
| exit: | |
| for (i = 0; i < nargs; i++) { | |
| Py_DECREF(stack[i]); | |
| } | |
| if (stack != small_stack) { | |
| PyMem_Free(stack); | |
| } | |
| return result; | |
| } | |
| static PyObject * | |
| map_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) | |
| { | |
| mapobject *lz = _mapobject_CAST(self); | |
| 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)); | |
| } | |
| if (lz->strict) { | |
| return Py_BuildValue("ONO", Py_TYPE(lz), args, Py_True); | |
| } | |
| return Py_BuildValue("ON", Py_TYPE(lz), args); | |
| } | |
| PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); | |
| static PyObject * | |
| map_setstate(PyObject *self, PyObject *state) | |
| { | |
| int strict = PyObject_IsTrue(state); | |
| if (strict < 0) { | |
| return NULL; | |
| } | |
| mapobject *lz = _mapobject_CAST(self); | |
| lz->strict = strict; | |
| Py_RETURN_NONE; | |
| } | |
| static PyMethodDef map_methods[] = { | |
| {"__reduce__", map_reduce, METH_NOARGS, reduce_doc}, | |
| {"__setstate__", map_setstate, METH_O, setstate_doc}, | |
| {NULL, NULL} /* sentinel */ | |
| }; | |
| PyDoc_STRVAR(map_doc, | |
| "map(function, iterable, /, *iterables, strict=False)\n\ | |
| --\n\ | |
| \n\ | |
| Make an iterator that computes the function using arguments from\n\ | |
| each of the iterables. Stops when the shortest iterable is exhausted.\n\ | |
| \n\ | |
| If strict is true and one of the arguments is exhausted before the\n\ | |
| others, raise a ValueError."); | |
| PyTypeObject PyMap_Type = { | |
| PyVarObject_HEAD_INIT(&PyType_Type, 0) | |
| "map", /* tp_name */ | |
| sizeof(mapobject), /* tp_basicsize */ | |
| 0, /* tp_itemsize */ | |
| /* methods */ | |
| map_dealloc, /* tp_dealloc */ | |
| 0, /* tp_vectorcall_offset */ | |
| 0, /* tp_getattr */ | |
| 0, /* tp_setattr */ | |
| 0, /* tp_as_async */ | |
| 0, /* tp_repr */ | |
| 0, /* tp_as_number */ | |
| 0, /* tp_as_sequence */ | |
| 0, /* tp_as_mapping */ | |
| 0, /* tp_hash */ | |
| 0, /* tp_call */ | |
| 0, /* tp_str */ | |
| PyObject_GenericGetAttr, /* tp_getattro */ | |
| 0, /* tp_setattro */ | |
| 0, /* tp_as_buffer */ | |
| Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | |
| Py_TPFLAGS_BASETYPE, /* tp_flags */ | |
| map_doc, /* tp_doc */ | |
| map_traverse, /* tp_traverse */ | |
| 0, /* tp_clear */ | |
| 0, /* tp_richcompare */ | |
| 0, /* tp_weaklistoffset */ | |
| PyObject_SelfIter, /* tp_iter */ | |
| map_next, /* tp_iternext */ | |
| map_methods, /* tp_methods */ | |
| 0, /* tp_members */ | |
| 0, /* tp_getset */ | |
| 0, /* tp_base */ | |
| 0, /* tp_dict */ | |
| 0, /* tp_descr_get */ | |
| 0, /* tp_descr_set */ | |
| 0, /* tp_dictoffset */ | |
| 0, /* tp_init */ | |
| PyType_GenericAlloc, /* tp_alloc */ | |
| map_new, /* tp_new */ | |
| PyObject_GC_Del, /* tp_free */ | |
| .tp_vectorcall = map_vectorcall | |
| }; | |
| /* AC: cannot convert yet, as needs PEP 457 group support in inspect */ | |
| static PyObject * | |
| builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | |
| { | |
| PyObject *it, *res; | |
| if (!_PyArg_CheckPositional("next", nargs, 1, 2)) | |
| return NULL; | |
| it = args[0]; | |
| if (!PyIter_Check(it)) { | |
| PyErr_Format(PyExc_TypeError, | |
| "'%.200s' object is not an iterator", | |
| Py_TYPE(it)->tp_name); | |
| return NULL; | |
| } | |
| res = (*Py_TYPE(it)->tp_iternext)(it); | |
| if (res != NULL) { | |
| return res; | |
| } else if (nargs > 1) { | |
| PyObject *def = args[1]; | |
| if (PyErr_Occurred()) { | |
| if(!PyErr_ExceptionMatches(PyExc_StopIteration)) | |
| return NULL; | |
| PyErr_Clear(); | |
| } | |
| return Py_NewRef(def); | |
| } else if (PyErr_Occurred()) { | |
| return NULL; | |
| } else { | |
| PyErr_SetNone(PyExc_StopIteration); | |
| return NULL; | |
| } | |
| } | |
| PyDoc_STRVAR(next_doc, | |
| "next(iterator[, default])\n\ | |
| \n\ | |
| Return the next item from the iterator. If default is given and the\n\ | |
| iterator is exhausted, it is returned instead of raising StopIteration."); | |
| /*[clinic input] | |
| setattr as builtin_setattr | |
| obj: object | |
| name: object | |
| value: object | |
| / | |
| Sets the named attribute on the given object to the specified value. | |
| setattr(x, 'y', v) is equivalent to ``x.y = v`` | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name, | |
| PyObject *value) | |
| /*[clinic end generated code: output=dc2ce1d1add9acb4 input=5e26417f2e8598d4]*/ | |
| { | |
| if (PyObject_SetAttr(obj, name, value) != 0) | |
| return NULL; | |
| Py_RETURN_NONE; | |
| } | |
| /*[clinic input] | |
| delattr as builtin_delattr | |
| obj: object | |
| name: object | |
| / | |
| Deletes the named attribute from the given object. | |
| delattr(x, 'y') is equivalent to ``del x.y`` | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name) | |
| /*[clinic end generated code: output=85134bc58dff79fa input=164865623abe7216]*/ | |
| { | |
| if (PyObject_DelAttr(obj, name) < 0) { | |
| return NULL; | |
| } | |
| Py_RETURN_NONE; | |
| } | |
| /*[clinic input] | |
| hash as builtin_hash | |
| obj: object | |
| / | |
| Return the integer hash value for the given object. | |
| Two objects that compare equal must also have the same hash value, but | |
| the reverse is not necessarily true. Hash values may differ between | |
| Python processes. Not all objects are hashable; calling hash() on an | |
| unhashable object raises TypeError. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_hash(PyObject *module, PyObject *obj) | |
| /*[clinic end generated code: output=237668e9d7688db7 input=70a242ff65f6717c]*/ | |
| { | |
| Py_hash_t x; | |
| x = PyObject_Hash(obj); | |
| if (x == -1) | |
| return NULL; | |
| return PyLong_FromSsize_t(x); | |
| } | |
| /*[clinic input] | |
| hex as builtin_hex | |
| integer: object | |
| / | |
| Return the hexadecimal representation of an integer. | |
| >>> hex(12648430) | |
| '0xc0ffee' | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_hex(PyObject *module, PyObject *integer) | |
| /*[clinic end generated code: output=e5de857ba61aae08 input=3bef4746efc62fac]*/ | |
| { | |
| return PyNumber_ToBase(integer, 16); | |
| } | |
| /*[clinic input] | |
| @text_signature "($module, object, /, [stop_value], *, stop_exception=StopIteration)" | |
| iter as builtin_iter | |
| object: object | |
| / | |
| stop_value: object = NULL | |
| * | |
| stop_exception: 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 stop value or raises the specified exception. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_iter_impl(PyObject *module, PyObject *object, PyObject *stop_value, | |
| PyObject *stop_exception) | |
| /*[clinic end generated code: output=eb9c9ae8f77bf400 input=d3a2f767f29d9ae6]*/ | |
| { | |
| if (stop_value == NULL && stop_exception == NULL) { | |
| return PyObject_GetIter(object); | |
| } | |
| if (!PyCallable_Check(object)) { | |
| PyErr_SetString(PyExc_TypeError, | |
| "iter(): the first argument must be callable"); | |
| return NULL; | |
| } | |
| return _PyCallIter_NewEx(object, stop_value, stop_exception); | |
| } | |
| /*[clinic input] | |
| @text_signature "($module, object, /, [stop_value], *, stop_exception=StopAsyncIteration)" | |
| aiter as builtin_aiter | |
| object: object | |
| / | |
| stop_value: object = NULL | |
| * | |
| stop_exception: object = NULL | |
| Return an AsyncIterator for an AsyncIterable object. | |
| In the second form, the callable is called and its result is awaited | |
| until it returns the stop value or raises the specified exception. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_aiter_impl(PyObject *module, PyObject *object, PyObject *stop_value, | |
| PyObject *stop_exception) | |
| /*[clinic end generated code: output=2865edb3fbc45693 input=2adb37d12adafd0c]*/ | |
| { | |
| if (stop_value == NULL && stop_exception == NULL) { | |
| return PyObject_GetAIter(object); | |
| } | |
| if (!PyCallable_Check(object)) { | |
| PyErr_SetString(PyExc_TypeError, | |
| "aiter(): the first argument must be callable"); | |
| return NULL; | |
| } | |
| return _PyACallIter_New(object, stop_value, stop_exception); | |
| } | |
| /*[clinic input] | |
| len as builtin_len | |
| obj: object | |
| / | |
| Return the number of items in a container. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_len(PyObject *module, PyObject *obj) | |
| /*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/ | |
| { | |
| Py_ssize_t res; | |
| res = PyObject_Size(obj); | |
| if (res < 0) { | |
| assert(PyErr_Occurred()); | |
| return NULL; | |
| } | |
| return PyLong_FromSsize_t(res); | |
| } | |
| /*[clinic input] | |
| locals as builtin_locals | |
| Return a dictionary containing the current scope's local variables. | |
| NOTE: Whether or not updates to this dictionary will affect name | |
| lookups in the local scope and vice-versa is *implementation | |
| dependent* and not covered by any backwards compatibility | |
| guarantees. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_locals_impl(PyObject *module) | |
| /*[clinic end generated code: output=b46c94015ce11448 input=989cc75c22167c42]*/ | |
| { | |
| PyObject *locals; | |
| if (_PyEval_GetFrame() != NULL) { | |
| locals = _PyEval_GetFrameLocals(); | |
| assert(locals != NULL || PyErr_Occurred()); | |
| return locals; | |
| } | |
| PyThreadState *tstate = _PyThreadState_GET(); | |
| locals = _PyEval_GetGlobalsFromRunningMain(tstate); | |
| if (locals == NULL) { | |
| if (_PyErr_Occurred(tstate)) { | |
| return NULL; | |
| } | |
| Py_RETURN_NONE; | |
| } | |
| return Py_NewRef(locals); | |
| } | |
| static PyObject * | |
| min_max(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, int op) | |
| { | |
| PyObject *it = NULL, *item, *val, *maxitem, *maxval, *keyfunc=NULL; | |
| PyObject *defaultval = NULL; | |
| static const char * const keywords[] = {"key", "default", NULL}; | |
| static _PyArg_Parser _parser_min = {"|$OO:min", keywords, 0}; | |
| static _PyArg_Parser _parser_max = {"|$OO:max", keywords, 0}; | |
| const char *name = (op == Py_LT) ? "min" : "max"; | |
| _PyArg_Parser *_parser = (op == Py_LT) ? &_parser_min : &_parser_max; | |
| if (nargs == 0) { | |
| PyErr_Format(PyExc_TypeError, "%s expected at least 1 argument, got 0", name); | |
| return NULL; | |
| } | |
| if (kwnames != NULL && !_PyArg_ParseStackAndKeywords(args + nargs, 0, kwnames, _parser, | |
| &keyfunc, &defaultval)) { | |
| return NULL; | |
| } | |
| const int positional = nargs > 1; // False iff nargs == 1 | |
| if (positional && defaultval != NULL) { | |
| PyErr_Format(PyExc_TypeError, | |
| "Cannot specify a default for %s() with multiple " | |
| "positional arguments", name); | |
| return NULL; | |
| } | |
| if (!positional) { | |
| it = PyObject_GetIter(args[0]); | |
| if (it == NULL) { | |
| return NULL; | |
| } | |
| } | |
| if (keyfunc == Py_None) { | |
| keyfunc = NULL; | |
| } | |
| maxitem = NULL; /* the result */ | |
| maxval = NULL; /* the value associated with the result */ | |
| while (1) { | |
| if (it == NULL) { | |
| if (nargs-- <= 0) { | |
| break; | |
| } | |
| item = *args++; | |
| Py_INCREF(item); | |
| } | |
| else { | |
| item = PyIter_Next(it); | |
| if (item == NULL) { | |
| if (PyErr_Occurred()) { | |
| goto Fail_it; | |
| } | |
| break; | |
| } | |
| } | |
| /* get the value from the key function */ | |
| if (keyfunc != NULL) { | |
| val = PyObject_CallOneArg(keyfunc, item); | |
| if (val == NULL) | |
| goto Fail_it_item; | |
| } | |
| /* no key function; the value is the item */ | |
| else { | |
| val = Py_NewRef(item); | |
| } | |
| /* maximum value and item are unset; set them */ | |
| if (maxval == NULL) { | |
| maxitem = item; | |
| maxval = val; | |
| } | |
| /* maximum value and item are set; update them as necessary */ | |
| 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 (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_XDECREF(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_XDECREF(it); | |
| return NULL; | |
| } | |
| /* AC: cannot convert yet, waiting for *args support */ | |
| static PyObject * | |
| builtin_min(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) | |
| { | |
| return min_max(args, nargs, kwnames, 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 positional arguments, return the smallest argument."); | |
| /* AC: cannot convert yet, waiting for *args support */ | |
| static PyObject * | |
| builtin_max(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) | |
| { | |
| return min_max(args, nargs, kwnames, 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 positional arguments, return the largest argument."); | |
| /*[clinic input] | |
| oct as builtin_oct | |
| integer: object | |
| / | |
| Return the octal representation of an integer. | |
| >>> oct(342391) | |
| '0o1234567' | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_oct(PyObject *module, PyObject *integer) | |
| /*[clinic end generated code: output=8c15f2145a74c390 input=b97c377b15fedf8d]*/ | |
| { | |
| return PyNumber_ToBase(integer, 8); | |
| } | |
| /*[clinic input] | |
| ord as builtin_ord | |
| character as c: object | |
| / | |
| Return the ordinal value of a character. | |
| If the argument is a one-character string, return the Unicode code | |
| point of that character. | |
| If the argument is a bytes or bytearray object of length 1, return its | |
| single byte value. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_ord(PyObject *module, PyObject *c) | |
| /*[clinic end generated code: output=4fa5e87a323bae71 input=98d38480432e1177]*/ | |
| { | |
| 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)) { | |
| /* XXX Hopefully this is temporary */ | |
| 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; | |
| } | |
| /*[clinic input] | |
| @permit_long_summary | |
| pow as builtin_pow | |
| base: object | |
| exp: object | |
| mod: object = None | |
| Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments | |
| Some types, such as ints, are able to use a more efficient algorithm | |
| when invoked using the three argument form. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, | |
| PyObject *mod) | |
| /*[clinic end generated code: output=3ca1538221bbf15f input=0cd5c3ecc8003aec]*/ | |
| { | |
| return PyNumber_Power(base, exp, mod); | |
| } | |
| /*[clinic input] | |
| print as builtin_print | |
| *objects: array | |
| sep: object(c_default="Py_None") = ' ' | |
| string inserted between values, default a space. | |
| end: object(c_default="Py_None") = '\n' | |
| string appended after the last value, default a newline. | |
| file: object = None | |
| a file-like object (stream); defaults to the current sys.stdout. | |
| flush: bool = False | |
| whether to forcibly flush the stream. | |
| Prints the values to a stream, or to sys.stdout by default. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_print_impl(PyObject *module, PyObject * const *objects, | |
| Py_ssize_t objects_length, PyObject *sep, PyObject *end, | |
| PyObject *file, int flush) | |
| /*[clinic end generated code: output=38d8def56c837bcc input=ff35cb3d59ee8115]*/ | |
| { | |
| int i, err; | |
| if (file == Py_None) { | |
| file = PySys_GetAttr(&_Py_ID(stdout)); | |
| if (file == NULL) { | |
| return NULL; | |
| } | |
| /* sys.stdout may be None when FILE* stdout isn't connected */ | |
| if (file == Py_None) { | |
| Py_DECREF(file); | |
| Py_RETURN_NONE; | |
| } | |
| } | |
| else { | |
| Py_INCREF(file); | |
| } | |
| 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); | |
| Py_DECREF(file); | |
| 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); | |
| Py_DECREF(file); | |
| return NULL; | |
| } | |
| for (i = 0; i < objects_length; i++) { | |
| if (i > 0) { | |
| if (sep == NULL) { | |
| err = PyFile_WriteString(" ", file); | |
| } | |
| else { | |
| err = PyFile_WriteObject(sep, file, Py_PRINT_RAW); | |
| } | |
| if (err) { | |
| Py_DECREF(file); | |
| return NULL; | |
| } | |
| } | |
| err = PyFile_WriteObject(objects[i], file, Py_PRINT_RAW); | |
| if (err) { | |
| Py_DECREF(file); | |
| return NULL; | |
| } | |
| } | |
| if (end == NULL) { | |
| err = PyFile_WriteString("\n", file); | |
| } | |
| else { | |
| err = PyFile_WriteObject(end, file, Py_PRINT_RAW); | |
| } | |
| if (err) { | |
| Py_DECREF(file); | |
| return NULL; | |
| } | |
| if (flush) { | |
| if (_PyFile_Flush(file) < 0) { | |
| Py_DECREF(file); | |
| return NULL; | |
| } | |
| } | |
| Py_DECREF(file); | |
| Py_RETURN_NONE; | |
| } | |
| /*[clinic input] | |
| input as builtin_input | |
| prompt: object(c_default="NULL") = "" | |
| / | |
| Read a string from standard input. The trailing newline is stripped. | |
| The prompt string, if given, is printed to standard output without a | |
| trailing newline before reading input. | |
| If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise | |
| EOFError. | |
| On *nix systems, readline is used if available. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_input_impl(PyObject *module, PyObject *prompt) | |
| /*[clinic end generated code: output=83db5a191e7a0d60 input=ebb939c954639427]*/ | |
| { | |
| PyObject *fin = NULL; | |
| PyObject *fout = NULL; | |
| PyObject *ferr = NULL; | |
| PyObject *tmp; | |
| long fd; | |
| int tty; | |
| /* Check that stdin/out/err are intact */ | |
| fin = PySys_GetAttr(&_Py_ID(stdin)); | |
| if (fin == NULL) { | |
| goto error; | |
| } | |
| if (fin == Py_None) { | |
| PyErr_SetString(PyExc_RuntimeError, "lost sys.stdin"); | |
| goto error; | |
| } | |
| fout = PySys_GetAttr(&_Py_ID(stdout)); | |
| if (fout == NULL) { | |
| goto error; | |
| } | |
| if (fout == Py_None) { | |
| PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); | |
| goto error; | |
| } | |
| ferr = PySys_GetAttr(&_Py_ID(stderr)); | |
| if (ferr == NULL) { | |
| goto error; | |
| } | |
| if (ferr == Py_None) { | |
| PyErr_SetString(PyExc_RuntimeError, "lost sys.stderr"); | |
| goto error; | |
| } | |
| if (PySys_Audit("builtins.input", "O", prompt ? prompt : Py_None) < 0) { | |
| goto error; | |
| } | |
| /* First of all, flush stderr */ | |
| if (_PyFile_Flush(ferr) < 0) { | |
| PyErr_Clear(); | |
| } | |
| /* We should only use (GNU) readline if Python's sys.stdin and | |
| sys.stdout are the same as C's stdin and stdout, because we | |
| need to pass it those. */ | |
| 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()) { | |
| goto error; | |
| } | |
| 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()) | |
| goto error; | |
| tty = fd == fileno(stdout) && isatty(fd); | |
| } | |
| } | |
| /* If we're interactive, use (GNU) readline */ | |
| 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 is a text stream, so it must have an encoding. */ | |
| 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; | |
| } | |
| if (_PyFile_Flush(fout) < 0) { | |
| PyErr_Clear(); | |
| } | |
| if (prompt != NULL) { | |
| /* We have a prompt, encode it as stdout would */ | |
| 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); | |
| if ((Py_ssize_t)strlen(promptstr) != PyBytes_GET_SIZE(po)) { | |
| PyErr_SetString(PyExc_ValueError, | |
| "input: prompt string cannot contain null characters"); | |
| goto _readline_errors; | |
| } | |
| } | |
| 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--; /* strip trailing '\n' */ | |
| if (len != 0 && s[len-1] == '\r') | |
| len--; /* strip trailing '\r' */ | |
| 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) { | |
| goto error; | |
| } | |
| } | |
| Py_DECREF(fin); | |
| Py_DECREF(fout); | |
| Py_DECREF(ferr); | |
| 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) | |
| goto error; | |
| PyErr_Clear(); | |
| } | |
| /* Fallback if we're not interactive */ | |
| if (prompt != NULL) { | |
| if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0) | |
| goto error; | |
| } | |
| if (_PyFile_Flush(fout) < 0) { | |
| PyErr_Clear(); | |
| } | |
| tmp = PyFile_GetLine(fin, -1); | |
| Py_DECREF(fin); | |
| Py_DECREF(fout); | |
| Py_DECREF(ferr); | |
| return tmp; | |
| error: | |
| Py_XDECREF(fin); | |
| Py_XDECREF(fout); | |
| Py_XDECREF(ferr); | |
| return NULL; | |
| } | |
| /*[clinic input] | |
| repr as builtin_repr | |
| obj: object | |
| / | |
| Return the canonical string representation of the object. | |
| For many object types, including most builtins, eval(repr(obj)) == obj. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_repr(PyObject *module, PyObject *obj) | |
| /*[clinic end generated code: output=7ed3778c44fd0194 input=1c9e6d66d3e3be04]*/ | |
| { | |
| return PyObject_Repr(obj); | |
| } | |
| /*[clinic input] | |
| round as builtin_round | |
| number: object | |
| ndigits: object = None | |
| Round a number to a given precision in decimal digits. | |
| The return value is an integer if ndigits is omitted or None. | |
| Otherwise the return value has the same type as the number. ndigits | |
| may be negative. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) | |
| /*[clinic end generated code: output=ff0d9dd176c02ede input=bdcb7c67bf4a4320]*/ | |
| { | |
| PyObject *result; | |
| if (ndigits == Py_None) { | |
| result = _PyObject_MaybeCallSpecialNoArgs(number, &_Py_ID(__round__)); | |
| } | |
| else { | |
| result = _PyObject_MaybeCallSpecialOneArg(number, &_Py_ID(__round__), | |
| ndigits); | |
| } | |
| if (result == NULL && !PyErr_Occurred()) { | |
| PyErr_Format(PyExc_TypeError, | |
| "type %.100s doesn't define __round__ method", | |
| Py_TYPE(number)->tp_name); | |
| } | |
| return result; | |
| } | |
| /*AC: we need to keep the kwds dict intact to easily call into the | |
| * list.sort method, which isn't currently supported in AC. So we just use | |
| * the initially generated signature with a custom implementation. | |
| */ | |
| /* [disabled clinic input] | |
| sorted as builtin_sorted | |
| iterable as seq: object | |
| key as keyfunc: object = None | |
| reverse: object = False | |
| Return a new list containing all items from the iterable in ascending order. | |
| A custom key function can be supplied to customize the sort order, and | |
| the reverse flag can be set to request the result in descending order. | |
| [end disabled clinic input]*/ | |
| 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; | |
| /* Keyword arguments are passed through list.sort() which will check | |
| them. */ | |
| 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; | |
| } | |
| /* AC: cannot convert yet, as needs PEP 457 group support in inspect */ | |
| /*[clinic input] | |
| vars as builtin_vars | |
| object as v: object = NULL | |
| / | |
| Show vars. | |
| Without arguments, equivalent to locals(). | |
| With an argument, equivalent to object.__dict__. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_vars_impl(PyObject *module, PyObject *v) | |
| /*[clinic end generated code: output=a64017e4a4dc53fc input=577550318240f012]*/ | |
| { | |
| PyObject *d; | |
| if (v == NULL) { | |
| if (_PyEval_GetFrame() != NULL) { | |
| d = _PyEval_GetFrameLocals(); | |
| } | |
| else { | |
| PyThreadState *tstate = _PyThreadState_GET(); | |
| d = _PyEval_GetGlobalsFromRunningMain(tstate); | |
| if (d == NULL) { | |
| if (!_PyErr_Occurred(tstate)) { | |
| d = _PyEval_GetFrameLocals(); | |
| assert(_PyErr_Occurred(tstate)); | |
| } | |
| } | |
| else { | |
| Py_INCREF(d); | |
| } | |
| } | |
| } | |
| else { | |
| if (PyObject_GetOptionalAttr(v, &_Py_ID(__dict__), &d) == 0) { | |
| PyErr_SetString(PyExc_TypeError, | |
| "vars() argument must have __dict__ attribute"); | |
| } | |
| } | |
| return d; | |
| } | |
| /* 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 | |
| */ | |
| typedef struct { | |
| double hi; /* high-order bits for a running sum */ | |
| double lo; /* a running compensation for lost low-order bits */ | |
| } CompensatedSum; | |
| static inline CompensatedSum | |
| cs_from_double(double x) | |
| { | |
| return (CompensatedSum) {x}; | |
| } | |
| static inline CompensatedSum | |
| cs_add(CompensatedSum total, double x) | |
| { | |
| double t = total.hi + x; | |
| if (fabs(total.hi) >= fabs(x)) { | |
| total.lo += (total.hi - t) + x; | |
| } | |
| else { | |
| total.lo += (x - t) + total.hi; | |
| } | |
| return (CompensatedSum) {t, total.lo}; | |
| } | |
| static inline double | |
| cs_to_double(CompensatedSum total) | |
| { | |
| /* 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 (total.lo && isfinite(total.lo)) { | |
| return total.hi + total.lo; | |
| } | |
| return total.hi; | |
| } | |
| /*[clinic input] | |
| @permit_long_summary | |
| sum as builtin_sum | |
| iterable: object | |
| / | |
| start: object(c_default="NULL") = 0 | |
| Return the sum of a 'start' value (default: 0) plus an iterable of numbers | |
| When the iterable is empty, return the start value. | |
| This function is intended specifically for use with numeric values and | |
| may reject non-numeric types. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) | |
| /*[clinic end generated code: output=df758cec7d1d302f input=d464d57815196b73]*/ | |
| { | |
| 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 { | |
| /* reject string values for 'start' parameter */ | |
| 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 | |
| /* Fast addition by keeping temporary sums in C instead of new Python objects. | |
| Assumes all inputs are the same type. If the assumption fails, default | |
| to the more general routine. | |
| */ | |
| if (PyLong_CheckExact(result)) { | |
| int overflow; | |
| Py_ssize_t i_result = PyLong_AsLongAndOverflow(result, &overflow); | |
| /* If this already overflowed, don't even enter the loop. */ | |
| 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; | |
| /* Single digits are common, fast, and cannot overflow on unpacking. */ | |
| if (_PyLong_IsCompact((PyLongObject *)item)) { | |
| b = _PyLong_CompactValue((PyLongObject *)item); | |
| } | |
| else { | |
| b = PyLong_AsLongAndOverflow(item, &overflow); | |
| } | |
| if (overflow == 0 && | |
| (i_result >= 0 ? (b <= PY_SSIZE_T_MAX - i_result) | |
| : (b >= PY_SSIZE_T_MIN - i_result))) | |
| { | |
| i_result += b; | |
| Py_DECREF(item); | |
| continue; | |
| } | |
| } | |
| /* Either overflowed or is not an int. Restore real objects and process normally */ | |
| 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)) { | |
| CompensatedSum re_sum = cs_from_double(PyFloat_AS_DOUBLE(result)); | |
| Py_SETREF(result, NULL); | |
| while(result == NULL) { | |
| item = PyIter_Next(iter); | |
| if (item == NULL) { | |
| Py_DECREF(iter); | |
| if (PyErr_Occurred()) | |
| return NULL; | |
| return PyFloat_FromDouble(cs_to_double(re_sum)); | |
| } | |
| if (PyFloat_CheckExact(item)) { | |
| re_sum = cs_add(re_sum, PyFloat_AS_DOUBLE(item)); | |
| _Py_DECREF_SPECIALIZED(item, _PyFloat_ExactDealloc); | |
| continue; | |
| } | |
| if (PyLong_Check(item)) { | |
| double value = PyLong_AsDouble(item); | |
| if (value != -1.0 || !PyErr_Occurred()) { | |
| re_sum = cs_add(re_sum, value); | |
| Py_DECREF(item); | |
| continue; | |
| } | |
| else { | |
| Py_DECREF(item); | |
| Py_DECREF(iter); | |
| return NULL; | |
| } | |
| } | |
| result = PyFloat_FromDouble(cs_to_double(re_sum)); | |
| 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 (PyComplex_CheckExact(result)) { | |
| Py_complex z = PyComplex_AsCComplex(result); | |
| CompensatedSum re_sum = cs_from_double(z.real); | |
| CompensatedSum im_sum = cs_from_double(z.imag); | |
| Py_SETREF(result, NULL); | |
| while (result == NULL) { | |
| item = PyIter_Next(iter); | |
| if (item == NULL) { | |
| Py_DECREF(iter); | |
| if (PyErr_Occurred()) { | |
| return NULL; | |
| } | |
| return PyComplex_FromDoubles(cs_to_double(re_sum), | |
| cs_to_double(im_sum)); | |
| } | |
| if (PyComplex_CheckExact(item)) { | |
| z = PyComplex_AsCComplex(item); | |
| re_sum = cs_add(re_sum, z.real); | |
| im_sum = cs_add(im_sum, z.imag); | |
| Py_DECREF(item); | |
| continue; | |
| } | |
| if (PyLong_Check(item)) { | |
| double value = PyLong_AsDouble(item); | |
| if (value != -1.0 || !PyErr_Occurred()) { | |
| re_sum = cs_add(re_sum, value); | |
| Py_DECREF(item); | |
| continue; | |
| } | |
| else { | |
| Py_DECREF(item); | |
| Py_DECREF(iter); | |
| return NULL; | |
| } | |
| } | |
| if (PyFloat_Check(item)) { | |
| double value = PyFloat_AS_DOUBLE(item); | |
| re_sum = cs_add(re_sum, value); | |
| _Py_DECREF_SPECIALIZED(item, _PyFloat_ExactDealloc); | |
| continue; | |
| } | |
| result = PyComplex_FromDoubles(cs_to_double(re_sum), | |
| cs_to_double(im_sum)); | |
| 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) { | |
| /* error, or end-of-sequence */ | |
| if (PyErr_Occurred()) { | |
| Py_SETREF(result, NULL); | |
| } | |
| break; | |
| } | |
| /* It's tempting to use PyNumber_InPlaceAdd instead of | |
| PyNumber_Add here, to avoid quadratic running time | |
| when doing 'sum(list_of_lists, [])'. However, this | |
| would produce a change in behaviour: a snippet like | |
| empty = [] | |
| sum([[x] for x in range(10)], empty) | |
| would change the value of empty. In fact, using | |
| in-place addition rather that binary addition for | |
| any of the steps introduces subtle behavior changes: | |
| https://bugs.python.org/issue18305 */ | |
| temp = PyNumber_Add(result, item); | |
| Py_DECREF(result); | |
| Py_DECREF(item); | |
| result = temp; | |
| if (result == NULL) | |
| break; | |
| } | |
| Py_DECREF(iter); | |
| return result; | |
| } | |
| /*[clinic input] | |
| @permit_long_summary | |
| isinstance as builtin_isinstance | |
| obj: object | |
| class_or_tuple: object | |
| / | |
| Return whether an object is an instance of a class or of a subclass thereof. | |
| A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the | |
| target to check against. This is equivalent to ``isinstance(x, A) or | |
| isinstance(x, B) or ...`` etc. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_isinstance_impl(PyObject *module, PyObject *obj, | |
| PyObject *class_or_tuple) | |
| /*[clinic end generated code: output=6faf01472c13b003 input=5d74d547df498f38]*/ | |
| { | |
| int retval; | |
| retval = PyObject_IsInstance(obj, class_or_tuple); | |
| if (retval < 0) | |
| return NULL; | |
| return PyBool_FromLong(retval); | |
| } | |
| /*[clinic input] | |
| issubclass as builtin_issubclass | |
| cls: object | |
| class_or_tuple: object | |
| / | |
| Return whether 'cls' is derived from another class or is the same class. | |
| A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the | |
| target to check against. This is equivalent to ``issubclass(x, A) or | |
| issubclass(x, B) or ...``. | |
| [clinic start generated code]*/ | |
| static PyObject * | |
| builtin_issubclass_impl(PyObject *module, PyObject *cls, | |
| PyObject *class_or_tuple) | |
| /*[clinic end generated code: output=358412410cd7a250 input=a91ce96345a6705d]*/ | |
| { | |
| 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; /* tuple of iterators */ | |
| PyObject *result; | |
| int strict; | |
| } zipobject; | |
| #define _zipobject_CAST(op) ((zipobject *)(op)) | |
| static PyObject * | |
| zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| { | |
| zipobject *lz; | |
| Py_ssize_t i; | |
| PyObject *ittuple; /* tuple of iterators */ | |
| 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; | |
| } | |
| } | |
| /* args must be a tuple */ | |
| assert(PyTuple_Check(args)); | |
| tuplesize = PyTuple_GET_SIZE(args); | |
| /* obtain iterators */ | |
| 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); | |
| } | |
| /* create a result holder */ | |
| 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)); | |
| } | |
| /* create zipobject structure */ | |
| 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(PyObject *self) | |
| { | |
| zipobject *lz = _zipobject_CAST(self); | |
| PyObject_GC_UnTrack(lz); | |
| Py_XDECREF(lz->ittuple); | |
| Py_XDECREF(lz->result); | |
| Py_TYPE(lz)->tp_free(lz); | |
| } | |
| static int | |
| zip_traverse(PyObject *self, visitproc visit, void *arg) | |
| { | |
| zipobject *lz = _zipobject_CAST(self); | |
| Py_VISIT(lz->ittuple); | |
| Py_VISIT(lz->result); | |
| return 0; | |
| } | |
| static PyObject * | |
| zip_next(PyObject *self) | |
| { | |
| zipobject *lz = _zipobject_CAST(self); | |
| 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 (_PyObject_IsUniquelyReferenced(result)) { | |
| 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); | |
| } | |
| // bpo-42536: The GC may have untracked this result tuple. Since we're | |
| // recycling it, make sure it's tracked again: | |
| _PyTuple_Recycle(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)) { | |
| // next() on argument i raised an exception (not StopIteration) | |
| return NULL; | |
| } | |
| PyErr_Clear(); | |
| } | |
| if (i) { | |
| // ValueError: zip() argument 2 is shorter than argument 1 | |
| // ValueError: zip() argument 3 is shorter than arguments 1-2 | |
| const char* plural = i == 1 ? " " : "s 1-"; | |
| return PyErr_Format(PyExc_ValueError, | |
| "zip() argument %zd is shorter than argument%s%zd", | |
| 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 %zd is longer than argument%s%zd", | |
| i + 1, plural, i); | |
| } | |
| if (PyErr_Occurred()) { | |
| if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { | |
| // next() on argument i raised an exception (not StopIteration) | |
| return NULL; | |
| } | |
| PyErr_Clear(); | |
| } | |
| // Argument i is exhausted. So far so good... | |
| } | |
| // All arguments are exhausted. Success! | |
| return NULL; | |
| } | |
| static PyObject * | |
| zip_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) | |
| { | |
| zipobject *lz = _zipobject_CAST(self); | |
| /* Just recreate the zip with the internal iterator tuple */ | |
| if (lz->strict) { | |
| return PyTuple_Pack(3, Py_TYPE(lz), lz->ittuple, Py_True); | |
| } | |
| return _PyTuple_FromPair((PyObject *)Py_TYPE(lz), lz->ittuple); | |
| } | |
| static PyObject * | |
| zip_setstate(PyObject *self, PyObject *state) | |
| { | |
| int strict = PyObject_IsTrue(state); | |
| if (strict < 0) { | |
| return NULL; | |
| } | |
| zipobject *lz = _zipobject_CAST(self); | |
| lz->strict = strict; | |
| Py_RETURN_NONE; | |
| } | |
| static PyMethodDef zip_methods[] = { | |
| {"__reduce__", zip_reduce, METH_NOARGS, reduce_doc}, | |
| {"__setstate__", zip_setstate, METH_O, setstate_doc}, | |
| {NULL} /* sentinel */ | |
| }; | |
| PyDoc_STRVAR(zip_doc, | |
| "zip(*iterables, strict=False)\n\ | |
| --\n\ | |
| \n\ | |
| The zip object yields n-length tuples, where n is the number of\n\ | |
| iterables passed as positional arguments to zip(). The i-th element\n\ | |
| in every tuple comes from the i-th iterable argument to zip(). This\n\ | |
| continues until the shortest argument is exhausted.\n\ | |
| \n\ | |
| If strict is true and one of the arguments is exhausted before the\n\ | |
| others, raise a ValueError.\n\ | |
| \n\ | |
| >>> list(zip('abcdefg', range(3), range(4)))\n\ | |
| [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]"); | |
| PyTypeObject PyZip_Type = { | |
| PyVarObject_HEAD_INIT(&PyType_Type, 0) | |
| "zip", /* tp_name */ | |
| sizeof(zipobject), /* tp_basicsize */ | |
| 0, /* tp_itemsize */ | |
| /* methods */ | |
| zip_dealloc, /* tp_dealloc */ | |
| 0, /* tp_vectorcall_offset */ | |
| 0, /* tp_getattr */ | |
| 0, /* tp_setattr */ | |
| 0, /* tp_as_async */ | |
| 0, /* tp_repr */ | |
| 0, /* tp_as_number */ | |
| 0, /* tp_as_sequence */ | |
| 0, /* tp_as_mapping */ | |
| 0, /* tp_hash */ | |
| 0, /* tp_call */ | |
| 0, /* tp_str */ | |
| PyObject_GenericGetAttr, /* tp_getattro */ | |
| 0, /* tp_setattro */ | |
| 0, /* tp_as_buffer */ | |
| Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | | |
| Py_TPFLAGS_BASETYPE, /* tp_flags */ | |
| zip_doc, /* tp_doc */ | |
| zip_traverse, /* tp_traverse */ | |
| 0, /* tp_clear */ | |
| 0, /* tp_richcompare */ | |
| 0, /* tp_weaklistoffset */ | |
| PyObject_SelfIter, /* tp_iter */ | |
| zip_next, /* tp_iternext */ | |
| zip_methods, /* tp_methods */ | |
| 0, /* tp_members */ | |
| 0, /* tp_getset */ | |
| 0, /* tp_base */ | |
| 0, /* tp_dict */ | |
| 0, /* tp_descr_get */ | |
| 0, /* tp_descr_set */ | |
| 0, /* tp_dictoffset */ | |
| 0, /* tp_init */ | |
| PyType_GenericAlloc, /* tp_alloc */ | |
| zip_new, /* tp_new */ | |
| PyObject_GC_Del, /* tp_free */ | |
| }; | |
| static PyMethodDef builtin_methods[] = { | |
| {"__build_class__", _PyCFunction_CAST(builtin___build_class__), | |
| METH_FASTCALL | METH_KEYWORDS, build_class_doc}, | |
| BUILTIN___IMPORT___METHODDEF | |
| BUILTIN___LAZY_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 | |
| {"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, getattr_doc}, | |
| 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_FASTCALL | METH_KEYWORDS, max_doc}, | |
| {"min", _PyCFunction_CAST(builtin_min), METH_FASTCALL | METH_KEYWORDS, min_doc}, | |
| {"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, next_doc}, | |
| 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, /* multiple "initialization" just copies the module dict. */ | |
| builtin_methods, | |
| NULL, | |
| NULL, | |
| NULL, | |
| NULL | |
| }; | |
| /* Builtins implemented in Python. | |
| Lib/_pybuiltins.py is frozen into the interpreter as a bootstrap module | |
| (see Tools/build/freeze_modules.py), so it can be imported here before | |
| the import system exists. The names in its __all__ are copied into the | |
| builtins dict. */ | |
| int | |
| _PyBuiltin_InitPythonFunctions(PyObject *dict) | |
| { | |
| if (PyImport_ImportFrozenModule("_pybuiltins") <= 0) { | |
| if (!PyErr_Occurred()) { | |
| PyErr_SetString(PyExc_ImportError, | |
| "frozen module _pybuiltins not found"); | |
| } | |
| return -1; | |
| } | |
| PyObject *mod = PyImport_AddModuleRef("_pybuiltins"); | |
| if (mod == NULL) { | |
| return -1; | |
| } | |
| int rc = -1; | |
| PyObject *all = PyObject_GetAttr(mod, &_Py_ID(__all__)); | |
| if (all == NULL) { | |
| goto done; | |
| } | |
| Py_ssize_t n = PyList_Size(all); | |
| if (n < 0) { | |
| goto done; | |
| } | |
| for (Py_ssize_t i = 0; i < n; i++) { | |
| PyObject *name = PyList_GET_ITEM(all, i); | |
| PyObject *func = PyObject_GetAttr(mod, name); | |
| if (func == NULL) { | |
| goto done; | |
| } | |
| int r = PyDict_SetItem(dict, name, func); | |
| Py_DECREF(func); | |
| if (r < 0) { | |
| goto done; | |
| } | |
| } | |
| rc = 0; | |
| done: | |
| Py_XDECREF(all); | |
| Py_DECREF(mod); | |
| return rc; | |
| } | |
| 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; | |
| #ifdef Py_GIL_DISABLED | |
| PyUnstable_Module_SetGIL(mod, Py_MOD_GIL_NOT_USED); | |
| #endif | |
| dict = PyModule_GetDict(mod); | |
| #ifdef Py_TRACE_REFS | |
| /* "builtins" exposes a number of statically allocated objects | |
| * that, before this code was added in 2.3, never showed up in | |
| * the list of "all objects" maintained by Py_TRACE_REFS. As a | |
| * result, programs leaking references to None and False (etc) | |
| * couldn't be diagnosed by examining sys.getobjects(0). | |
| */ | |
| #define ADD_TO_ALL(OBJECT) _Py_AddToAllObjects((PyObject *)(OBJECT)) | |
| #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("frozendict", &PyFrozenDict_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("sentinel", &PySentinel_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 | |
| } |