* are correct. */ assert(ilow != NULL); if (ihigh == NULL) { /* only 1 arg -- it's the upper limit */ ihigh = ilow; ilow = NULL; } assert(ihigh != NULL); Py_INCREF(ihigh); /* ihigh correct now; do ilow */ if (ilow == NULL) ilow = zero; Py_INCREF(ilow); /* ilow and ihigh correct now; do istep */ if (istep == NULL) { istep = PyLong_FromLong(1L); if (istep == NULL) goto Fail; } else { Py_INCREF(istep); } if (!PyInt_Check(ilow) && !PyLong_Check(ilow)) { PyErr_Format(PyExc_TypeError, "range() integer start argument expected, got %s.", ilow->ob_type->tp_name); goto Fail; } if (!PyInt_Check(ihigh) && !PyLong_Check(ihigh)) { PyErr_Format(PyExc_TypeError, "range() integer end argument expected, got %s.", ihigh->ob_type->tp_name); goto Fail; } if (!PyInt_Check(istep) && !PyLong_Check(istep)) { PyErr_Format(PyExc_TypeError, "range() integer step argument expected, got %s.", istep->ob_type->tp_name); goto Fail; } if (PyObject_Cmp(istep, zero, &cmp_result) == -1) goto Fail; if (cmp_result == 0) { PyErr_SetString(PyExc_ValueError, "range() step argument must not be zero"); goto Fail; } if (cmp_result > 0) bign = get_len_of_range_longs(ilow, ihigh, istep); else { PyObject *neg_istep = PyNumber_Negative(istep); if (neg_istep == NULL) goto Fail; bign = get_len_of_range_longs(ihigh, ilow, neg_istep); Py_DECREF(neg_istep); } n = (int)bign; if (bign < 0 || (long)n != bign) { PyErr_SetString(PyExc_OverflowError, "range() result has too many items"); goto Fail; } v = PyList_New(n); if (v == NULL) goto Fail; curnum = ilow; Py_INCREF(curnum); for (i = 0; i < n; i++) { PyObject *w = PyNumber_Long(curnum); PyObject *tmp_num; if (w == NULL) goto Fail; PyList_SET_ITEM(v, i, w); tmp_num = PyNumber_Add(curnum, istep); if (tmp_num == NULL) goto Fail; Py_DECREF(curnum); curnum = tmp_num; } Py_DECREF(ilow); Py_DECREF(ihigh); Py_DECREF(istep); Py_DECREF(zero); Py_DECREF(curnum); return v; Fail: Py_DECREF(ilow); Py_DECREF(ihigh); Py_XDECREF(istep); Py_DECREF(zero); Py_XDECREF(curnum); Py_XDECREF(v); return NULL;} /* Return number of items in range/xrange (lo, hi, step). step > 0 * required. Return a value < 0 if & only if the true value is too * large to fit in a signed long. */static longget_len_of_range(long lo, long hi, long step){ /* ------------------------------------------------------------- If lo >= hi, the range is empty. Else if n values are in the range, the last one is lo + (n-1)*step, which must be <= hi-1. Rearranging, n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so the RHS is non-negative and so truncation is the same as the floor. Letting M be the largest positive long, the worst case for the RHS numerator is hi=M, lo=-M-1, and then hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough precision to compute the RHS exactly. ---------------------------------------------------------------*/ long n = 0; if (lo < hi) { unsigned long uhi = (unsigned long)hi; unsigned long ulo = (unsigned long)lo; unsigned long diff = uhi - ulo - 1; n = (long)(diff / (unsigned long)step + 1); } return n;} static PyObject *builtin_range(PyObject *self, PyObject *args){ long ilow = 0, ihigh = 0, istep = 1; long bign; int i, n; PyObject *v; if (PyTuple_Size(args) <= 1) { if (!PyArg_ParseTuple(args, "l;range() requires 1-3 int arguments", &ihigh)) { PyErr_Clear(); return handle_range_longs(self, args); } } else { if (!PyArg_ParseTuple(args, "ll|l;range() requires 1-3 int arguments", &ilow, &ihigh, &istep)) { PyErr_Clear(); return handle_range_longs(self, args); } } if (istep == 0) { PyErr_SetString(PyExc_ValueError, "range() step argument must not be zero"); return NULL; } if (istep > 0) bign = get_len_of_range(ilow, ihigh, istep); else bign = get_len_of_range(ihigh, ilow, -istep); n = (int)bign; if (bign < 0 || (long)n != bign) { PyErr_SetString(PyExc_OverflowError, "range() result has too many items"); return NULL; } v = PyList_New(n); if (v == NULL) return NULL; for (i = 0; i < n; i++) { PyObject *w = PyInt_FromLong(ilow); if (w == NULL) { Py_DECREF(v); return NULL; } PyList_SET_ITEM(v, i, w); ilow += istep; } return v;} PyDoc_STRVAR(range_doc,"range([start,] stop[, step]) -> list of integers\n\\n\Return a list containing an arithmetic progression of integers.\n\range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.\n\When step is given, it specifies the increment (or decrement).\n\For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!\n\These are exactly the valid indices for a list of 4 elements."); static PyObject *builtin_raw_input(PyObject *self, PyObject *args){ PyObject *v = NULL; PyObject *fin = PySys_GetObject("stdin"); PyObject *fout = PySys_GetObject("stdout"); if (!PyArg_UnpackTuple(args, "[raw_]input", 0, 1, &v)) return NULL; if (fin == NULL) { PyErr_SetString(PyExc_RuntimeError, "[raw_]input: lost sys.stdin"); return NULL; } if (fout == NULL) { PyErr_SetString(PyExc_RuntimeError, "[raw_]input: lost sys.stdout"); return NULL; } if (PyFile_SoftSpace(fout, 0)) { if (PyFile_WriteString(" ", fout) != 0) return NULL; } if (PyFile_AsFile(fin) && PyFile_AsFile(fout) && isatty(fileno(PyFile_AsFile(fin))) && isatty(fileno(PyFile_AsFile(fout)))) { PyObject *po; char *prompt; char *s; PyObject *result; if (v != NULL) { po = PyObject_Str(v); if (po == NULL) return NULL; prompt = PyString_AsString(po); if (prompt == NULL) return NULL; } else { po = NULL; prompt = ""; } s = PyOS_Readline(PyFile_AsFile(fin), PyFile_AsFile(fout), prompt); Py_XDECREF(po); if (s == NULL) { if (!PyErr_Occurred()) PyErr_SetNone(PyExc_KeyboardInterrupt); return NULL; } if (*s == '\0') { PyErr_SetNone(PyExc_EOFError); result = NULL; } else { /* strip trailing '\n' */ size_t len = strlen(s); if (len > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "[raw_]input: input too long"); result = NULL; } else { result = PyString_FromStringAndSize(s, len-1); } } PyMem_FREE(s); return result; } if (v != NULL) { if (PyFile_WriteObject(v, fout, Py_PRINT_RAW) != 0) return NULL; } return PyFile_GetLine(fin, -1);} PyDoc_STRVAR(raw_input_doc,"raw_input([prompt]) -> string\n\\n\Read a string from standard input. The trailing newline is stripped.\n\If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.\n\On Unix, GNU readline is used if enabled. The prompt string, if given,\n\is printed without a trailing newline before reading."); static PyObject *builtin_reduce(PyObject *self, PyObject *args){ PyObject *seq, *func, *result = NULL, *it; if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result)) return NULL; if (result != NULL) Py_INCREF(result); it = PyObject_GetIter(seq); if (it == NULL) { PyErr_SetString(PyExc_TypeError, "reduce() arg 2 must support iteration"); Py_XDECREF(result); return NULL; } if ((args = PyTuple_New(2)) == NULL) goto Fail; for (;;) { PyObject *op2; if (args->ob_refcnt > 1) { Py_DECREF(args); if ((args = PyTuple_New(2)) == NULL) goto Fail; } op2 = PyIter_Next(it); if (op2 == NULL) { if (PyErr_Occurred()) goto Fail; break; } if (result == NULL) result = op2; else { PyTuple_SetItem(args, 0, result); PyTuple_SetItem(args, 1, op2); if ((result = PyEval_CallObject(func, args)) == NULL) goto Fail; } } Py_DECREF(args); if (result == NULL) PyErr_SetString(PyExc_TypeError, "reduce() of empty sequence with no initial value"); Py_DECREF(it); return result; Fail: Py_XDECREF(args); Py_XDECREF(result); Py_DECREF(it); return NULL;} PyDoc_STRVAR(reduce_doc,"reduce(function, sequence[, initial]) -> value\n\\n\Apply a function of two arguments cumulatively to the items of a sequence,\n\from left to right, so as to reduce the sequence to a single value.\n\For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\((((1+2)+3)+4)+5). If initial is present, it is placed before the items\n\of the sequence in the calculation, and serves as a default when the\n\sequence is empty."); static PyObject *builtin_reload(PyObject *self, PyObject *v){ return PyImport_ReloadModule(v);} PyDoc_STRVAR(reload_doc,"reload(module) -> module\n\\n\Reload the module. The module must have been successfully imported before."); static PyObject *builtin_repr(PyObject *self, PyObject *v){ return PyObject_Repr(v);} PyDoc_STRVAR(repr_doc,"repr(object) -> string\n\\n\Return the canonical string representation of the object.\n\For most object types, eval(repr(object)) == object."); static PyObject *builtin_round(PyObject *self, PyObject *args, PyObject *kwds){ double number; double f; int ndigits = 0; int i; static char *kwlist[] = {"number", "ndigits", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|i:round", kwlist, &number, &ndigits)) return NULL; f = 1.0; i = abs(ndigits); while (--i >= 0) f = f*10.0; if (ndigits < 0) number /= f; else number *= f; if (number >= 0.0) number = floor(number + 0.5); else number = ceil(number - 0.5); if (ndigits < 0) number *= f; else number /= f; return PyFloat_FromDouble(number);} PyDoc_STRVAR(round_doc,"round(number[, ndigits]) -> floating point number\n\\n\Round a number to a given precision in decimal digits (default 0 digits).\n\This always returns a floating point number. Precision may be negative."); static PyObject *builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds){ PyObject *newlist, *v, *seq, *compare=NULL, *keyfunc=NULL, *newargs; PyObject *callable; static char *kwlist[] = {"iterable", "cmp", "key", "reverse", 0}; int reverse; /* args 1-4 should match listsort in Objects/listobject.c */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi:sorted", kwlist, &seq, &compare, &keyfunc, &reverse)) return NULL; newlist = PySequence_List(seq); if (newlist == NULL) return NULL; callable = PyObject_GetAttrString(newlist, "sort"); if (callable == NULL) { Py_DECREF(newlist); return NULL; } newargs = PyTuple_GetSlice(args, 1, 4); if (newargs == NULL) { Py_DECREF(newlist); Py_DECREF(callable); return NULL; } v = PyObject_Call(callable, newargs, kwds); Py_DECREF(newargs); Py_DECREF(callable); if (v == NULL) { Py_DECREF(newlist); return NULL; } Py_DECREF(v); return newlist;} PyDoc_STRVAR(sorted_doc,"sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list"); static PyObject *builtin_vars(PyObject *self, PyObject *args){ PyObject *v = NULL; PyObject *d; if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v)) return NULL; if (v == NULL) { d = PyEval_GetLocals(); if (d == NULL) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_SystemError, "vars(): no locals!?"); } else Py_INCREF(d); } else { d = PyObject_GetAttrString(v, "__dict__"); if (d == NULL) { PyErr_SetString(PyExc_TypeError, "vars() argument must have __dict__ attribute"); return NULL; } } return d;} PyDoc_STRVAR(vars_doc,"vars([object]) -> dictionary\n\\n\Lines 1501–2000 of 2620. Previous lines Load more
* are correct. */ assert(ilow != NULL); if (ihigh == NULL) { /* only 1 arg -- it's the upper limit */ ihigh = ilow; ilow = NULL; } assert(ihigh != NULL); Py_INCREF(ihigh); /* ihigh correct now; do ilow */ if (ilow == NULL) ilow = zero; Py_INCREF(ilow); /* ilow and ihigh correct now; do istep */ if (istep == NULL) { istep = PyLong_FromLong(1L); if (istep == NULL) goto Fail; } else { Py_INCREF(istep); } if (!PyInt_Check(ilow) && !PyLong_Check(ilow)) { PyErr_Format(PyExc_TypeError, "range() integer start argument expected, got %s.", ilow->ob_type->tp_name); goto Fail; } if (!PyInt_Check(ihigh) && !PyLong_Check(ihigh)) { PyErr_Format(PyExc_TypeError, "range() integer end argument expected, got %s.", ihigh->ob_type->tp_name); goto Fail; } if (!PyInt_Check(istep) && !PyLong_Check(istep)) { PyErr_Format(PyExc_TypeError, "range() integer step argument expected, got %s.", istep->ob_type->tp_name); goto Fail; } if (PyObject_Cmp(istep, zero, &cmp_result) == -1) goto Fail; if (cmp_result == 0) { PyErr_SetString(PyExc_ValueError, "range() step argument must not be zero"); goto Fail; } if (cmp_result > 0) bign = get_len_of_range_longs(ilow, ihigh, istep); else { PyObject *neg_istep = PyNumber_Negative(istep); if (neg_istep == NULL) goto Fail; bign = get_len_of_range_longs(ihigh, ilow, neg_istep); Py_DECREF(neg_istep); } n = (int)bign; if (bign < 0 || (long)n != bign) { PyErr_SetString(PyExc_OverflowError, "range() result has too many items"); goto Fail; } v = PyList_New(n); if (v == NULL) goto Fail; curnum = ilow; Py_INCREF(curnum); for (i = 0; i < n; i++) { PyObject *w = PyNumber_Long(curnum); PyObject *tmp_num; if (w == NULL) goto Fail; PyList_SET_ITEM(v, i, w); tmp_num = PyNumber_Add(curnum, istep); if (tmp_num == NULL) goto Fail; Py_DECREF(curnum); curnum = tmp_num; } Py_DECREF(ilow); Py_DECREF(ihigh); Py_DECREF(istep); Py_DECREF(zero); Py_DECREF(curnum); return v; Fail: Py_DECREF(ilow); Py_DECREF(ihigh); Py_XDECREF(istep); Py_DECREF(zero); Py_XDECREF(curnum); Py_XDECREF(v); return NULL; } /* Return number of items in range/xrange (lo, hi, step). step > 0 * required. Return a value < 0 if & only if the true value is too * large to fit in a signed long. */ static long get_len_of_range(long lo, long hi, long step) { /* ------------------------------------------------------------- If lo >= hi, the range is empty. Else if n values are in the range, the last one is lo + (n-1)*step, which must be <= hi-1. Rearranging, n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so the RHS is non-negative and so truncation is the same as the floor. Letting M be the largest positive long, the worst case for the RHS numerator is hi=M, lo=-M-1, and then hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough precision to compute the RHS exactly. ---------------------------------------------------------------*/ long n = 0; if (lo < hi) { unsigned long uhi = (unsigned long)hi; unsigned long ulo = (unsigned long)lo; unsigned long diff = uhi - ulo - 1; n = (long)(diff / (unsigned long)step + 1); } return n; } static PyObject * builtin_range(PyObject *self, PyObject *args) { long ilow = 0, ihigh = 0, istep = 1; long bign; int i, n; PyObject *v; if (PyTuple_Size(args) <= 1) { if (!PyArg_ParseTuple(args, "l;range() requires 1-3 int arguments", &ihigh)) { PyErr_Clear(); return handle_range_longs(self, args); } } else { if (!PyArg_ParseTuple(args, "ll|l;range() requires 1-3 int arguments", &ilow, &ihigh, &istep)) { PyErr_Clear(); return handle_range_longs(self, args); } } if (istep == 0) { PyErr_SetString(PyExc_ValueError, "range() step argument must not be zero"); return NULL; } if (istep > 0) bign = get_len_of_range(ilow, ihigh, istep); else bign = get_len_of_range(ihigh, ilow, -istep); n = (int)bign; if (bign < 0 || (long)n != bign) { PyErr_SetString(PyExc_OverflowError, "range() result has too many items"); return NULL; } v = PyList_New(n); if (v == NULL) return NULL; for (i = 0; i < n; i++) { PyObject *w = PyInt_FromLong(ilow); if (w == NULL) { Py_DECREF(v); return NULL; } PyList_SET_ITEM(v, i, w); ilow += istep; } return v; } PyDoc_STRVAR(range_doc, "range([start,] stop[, step]) -> list of integers\n\ \n\ Return a list containing an arithmetic progression of integers.\n\ range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.\n\ When step is given, it specifies the increment (or decrement).\n\ For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!\n\ These are exactly the valid indices for a list of 4 elements."); static PyObject * builtin_raw_input(PyObject *self, PyObject *args) { PyObject *v = NULL; PyObject *fin = PySys_GetObject("stdin"); PyObject *fout = PySys_GetObject("stdout"); if (!PyArg_UnpackTuple(args, "[raw_]input", 0, 1, &v)) return NULL; if (fin == NULL) { PyErr_SetString(PyExc_RuntimeError, "[raw_]input: lost sys.stdin"); return NULL; } if (fout == NULL) { PyErr_SetString(PyExc_RuntimeError, "[raw_]input: lost sys.stdout"); return NULL; } if (PyFile_SoftSpace(fout, 0)) { if (PyFile_WriteString(" ", fout) != 0) return NULL; } if (PyFile_AsFile(fin) && PyFile_AsFile(fout) && isatty(fileno(PyFile_AsFile(fin))) && isatty(fileno(PyFile_AsFile(fout)))) { PyObject *po; char *prompt; char *s; PyObject *result; if (v != NULL) { po = PyObject_Str(v); if (po == NULL) return NULL; prompt = PyString_AsString(po); if (prompt == NULL) return NULL; } else { po = NULL; prompt = ""; } s = PyOS_Readline(PyFile_AsFile(fin), PyFile_AsFile(fout), prompt); Py_XDECREF(po); if (s == NULL) { if (!PyErr_Occurred()) PyErr_SetNone(PyExc_KeyboardInterrupt); return NULL; } if (*s == '\0') { PyErr_SetNone(PyExc_EOFError); result = NULL; } else { /* strip trailing '\n' */ size_t len = strlen(s); if (len > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "[raw_]input: input too long"); result = NULL; } else { result = PyString_FromStringAndSize(s, len-1); } } PyMem_FREE(s); return result; } if (v != NULL) { if (PyFile_WriteObject(v, fout, Py_PRINT_RAW) != 0) return NULL; } return PyFile_GetLine(fin, -1); } PyDoc_STRVAR(raw_input_doc, "raw_input([prompt]) -> string\n\ \n\ Read a string from standard input. The trailing newline is stripped.\n\ If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.\n\ On Unix, GNU readline is used if enabled. The prompt string, if given,\n\ is printed without a trailing newline before reading."); static PyObject * builtin_reduce(PyObject *self, PyObject *args) { PyObject *seq, *func, *result = NULL, *it; if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result)) return NULL; if (result != NULL) Py_INCREF(result); it = PyObject_GetIter(seq); if (it == NULL) { PyErr_SetString(PyExc_TypeError, "reduce() arg 2 must support iteration"); Py_XDECREF(result); return NULL; } if ((args = PyTuple_New(2)) == NULL) goto Fail; for (;;) { PyObject *op2; if (args->ob_refcnt > 1) { Py_DECREF(args); if ((args = PyTuple_New(2)) == NULL) goto Fail; } op2 = PyIter_Next(it); if (op2 == NULL) { if (PyErr_Occurred()) goto Fail; break; } if (result == NULL) result = op2; else { PyTuple_SetItem(args, 0, result); PyTuple_SetItem(args, 1, op2); if ((result = PyEval_CallObject(func, args)) == NULL) goto Fail; } } Py_DECREF(args); if (result == NULL) PyErr_SetString(PyExc_TypeError, "reduce() of empty sequence with no initial value"); Py_DECREF(it); return result; Fail: Py_XDECREF(args); Py_XDECREF(result); Py_DECREF(it); return NULL; } PyDoc_STRVAR(reduce_doc, "reduce(function, sequence[, initial]) -> value\n\ \n\ Apply a function of two arguments cumulatively to the items of a sequence,\n\ from left to right, so as to reduce the sequence to a single value.\n\ For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\ ((((1+2)+3)+4)+5). If initial is present, it is placed before the items\n\ of the sequence in the calculation, and serves as a default when the\n\ sequence is empty."); static PyObject * builtin_reload(PyObject *self, PyObject *v) { return PyImport_ReloadModule(v); } PyDoc_STRVAR(reload_doc, "reload(module) -> module\n\ \n\ Reload the module. The module must have been successfully imported before."); static PyObject * builtin_repr(PyObject *self, PyObject *v) { return PyObject_Repr(v); } PyDoc_STRVAR(repr_doc, "repr(object) -> string\n\ \n\ Return the canonical string representation of the object.\n\ For most object types, eval(repr(object)) == object."); static PyObject * builtin_round(PyObject *self, PyObject *args, PyObject *kwds) { double number; double f; int ndigits = 0; int i; static char *kwlist[] = {"number", "ndigits", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|i:round", kwlist, &number, &ndigits)) return NULL; f = 1.0; i = abs(ndigits); while (--i >= 0) f = f*10.0; if (ndigits < 0) number /= f; else number *= f; if (number >= 0.0) number = floor(number + 0.5); else number = ceil(number - 0.5); if (ndigits < 0) number *= f; else number /= f; return PyFloat_FromDouble(number); } PyDoc_STRVAR(round_doc, "round(number[, ndigits]) -> floating point number\n\ \n\ Round a number to a given precision in decimal digits (default 0 digits).\n\ This always returns a floating point number. Precision may be negative."); static PyObject * builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *newlist, *v, *seq, *compare=NULL, *keyfunc=NULL, *newargs; PyObject *callable; static char *kwlist[] = {"iterable", "cmp", "key", "reverse", 0}; int reverse; /* args 1-4 should match listsort in Objects/listobject.c */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi:sorted", kwlist, &seq, &compare, &keyfunc, &reverse)) return NULL; newlist = PySequence_List(seq); if (newlist == NULL) return NULL; callable = PyObject_GetAttrString(newlist, "sort"); if (callable == NULL) { Py_DECREF(newlist); return NULL; } newargs = PyTuple_GetSlice(args, 1, 4); if (newargs == NULL) { Py_DECREF(newlist); Py_DECREF(callable); return NULL; } v = PyObject_Call(callable, newargs, kwds); Py_DECREF(newargs); Py_DECREF(callable); if (v == NULL) { Py_DECREF(newlist); return NULL; } Py_DECREF(v); return newlist; } PyDoc_STRVAR(sorted_doc, "sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list"); static PyObject * builtin_vars(PyObject *self, PyObject *args) { PyObject *v = NULL; PyObject *d; if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v)) return NULL; if (v == NULL) { d = PyEval_GetLocals(); if (d == NULL) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_SystemError, "vars(): no locals!?"); } else Py_INCREF(d); } else { d = PyObject_GetAttrString(v, "__dict__"); if (d == NULL) { PyErr_SetString(PyExc_TypeError, "vars() argument must have __dict__ attribute"); return NULL; } } return d; } PyDoc_STRVAR(vars_doc, "vars([object]) -> dictionary\n\ \n\