diff options
Diffstat (limited to 'Python/bltinmodule.c')
| -rw-r--r-- | Python/bltinmodule.c | 163 | 
1 files changed, 96 insertions, 67 deletions
| diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 9f5db2afe1..69e5f08b0e 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -21,16 +21,18 @@     Don't forget to modify PyUnicode_DecodeFSDefault() if you touch any of the     values for Py_FileSystemDefaultEncoding!  */ -#ifdef HAVE_MBCS -const char *Py_FileSystemDefaultEncoding = "mbcs"; +#if defined(__APPLE__) +const char *Py_FileSystemDefaultEncoding = "utf-8";  int Py_HasFileSystemDefaultEncoding = 1; -#elif defined(__APPLE__) +#elif defined(MS_WINDOWS) +/* may be changed by initfsencoding(), but should never be free()d */  const char *Py_FileSystemDefaultEncoding = "utf-8";  int Py_HasFileSystemDefaultEncoding = 1;  #else  const char *Py_FileSystemDefaultEncoding = NULL; /* set by initfsencoding() */  int Py_HasFileSystemDefaultEncoding = 0;  #endif +const char *Py_FileSystemDefaultEncodeErrors = "surrogateescape";  _Py_IDENTIFIER(__builtins__);  _Py_IDENTIFIER(__dict__); @@ -52,8 +54,8 @@ _Py_IDENTIFIER(stderr);  static PyObject *  builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)  { -    PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *cell; -    PyObject *cls = NULL; +    PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns; +    PyObject *cls = NULL, *cell = NULL;      Py_ssize_t nargs;      int isclass = 0;   /* initialize to prevent gcc warning */ @@ -155,16 +157,8 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)          }      }      else { -        PyObject *pargs = PyTuple_Pack(2, name, bases); -        if (pargs == NULL) { -            Py_DECREF(prep); -            Py_DECREF(meta); -            Py_XDECREF(mkw); -            Py_DECREF(bases); -            return NULL; -        } -        ns = PyEval_CallObjectWithKeywords(prep, pargs, mkw); -        Py_DECREF(pargs); +        PyObject *pargs[2] = {name, bases}; +        ns = _PyObject_FastCallDict(prep, pargs, 2, mkw);          Py_DECREF(prep);      }      if (ns == NULL) { @@ -177,16 +171,40 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)                               NULL, 0, NULL, 0, NULL, 0, NULL,                               PyFunction_GET_CLOSURE(func));      if (cell != NULL) { -        PyObject *margs; -        margs = PyTuple_Pack(3, name, bases, ns); -        if (margs != NULL) { -            cls = PyEval_CallObjectWithKeywords(meta, margs, mkw); -            Py_DECREF(margs); +        PyObject *margs[3] = {name, bases, ns}; +        cls = _PyObject_FastCallDict(meta, margs, 3, mkw); +        if (cls != NULL && PyType_Check(cls) && PyCell_Check(cell)) { +            PyObject *cell_cls = PyCell_GET(cell); +            if (cell_cls != cls) { +                /* TODO: In 3.7, DeprecationWarning will become RuntimeError. +                 *       At that point, cell_error won't be needed. +                 */ +                int cell_error; +                if (cell_cls == NULL) { +                    const char *msg = +                        "__class__ not set defining %.200R as %.200R. " +                        "Was __classcell__ propagated to type.__new__?"; +                    cell_error = PyErr_WarnFormat( +                        PyExc_DeprecationWarning, 1, msg, name, cls); +                } else { +                    const char *msg = +                        "__class__ set to %.200R defining %.200R as %.200R"; +                    PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls); +                    cell_error = 1; +                } +                if (cell_error) { +                    Py_DECREF(cls); +                    cls = NULL; +                    goto error; +                } else { +                    /* Fill in the cell, since type.__new__ didn't do it */ +                    PyCell_Set(cell, cls); +                } +            }          } -        if (cls != NULL && PyCell_Check(cell)) -            PyCell_Set(cell, cls); -        Py_DECREF(cell);      } +error: +    Py_XDECREF(cell);      Py_DECREF(ns);      Py_DECREF(meta);      Py_XDECREF(mkw); @@ -331,7 +349,7 @@ builtin_any(PyObject *module, PyObject *iterable)              Py_DECREF(it);              return NULL;          } -        if (cmp == 1) { +        if (cmp > 0) {              Py_DECREF(it);              Py_RETURN_TRUE;          } @@ -469,6 +487,7 @@ filter_next(filterobject *lz)      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 (;;) { @@ -476,12 +495,11 @@ filter_next(filterobject *lz)          if (item == NULL)              return NULL; -        if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) { +        if (checktrue) {              ok = PyObject_IsTrue(item);          } else {              PyObject *good; -            good = PyObject_CallFunctionObjArgs(lz->func, -                                                item, NULL); +            good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);              if (good == NULL) {                  Py_DECREF(item);                  return NULL; @@ -1168,26 +1186,43 @@ map_traverse(mapobject *lz, visitproc visit, void *arg)  static PyObject *  map_next(mapobject *lz)  { -    PyObject *val; -    PyObject *argtuple; -    PyObject *result; -    Py_ssize_t numargs, i; +    PyObject *small_stack[5]; +    PyObject **stack; +    Py_ssize_t niters, nargs, i; +    PyObject *result = NULL; -    numargs = PyTuple_Size(lz->iters); -    argtuple = PyTuple_New(numargs); -    if (argtuple == NULL) -        return NULL; +    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(); +            return NULL; +        } +    } -    for (i=0 ; i<numargs ; i++) { -        val = PyIter_Next(PyTuple_GET_ITEM(lz->iters, i)); +    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) { -            Py_DECREF(argtuple); -            return NULL; +            goto exit;          } -        PyTuple_SET_ITEM(argtuple, i, val); +        stack[i] = val; +        nargs++; +    } + +    result = _PyObject_FastCall(lz->func, stack, nargs); + +exit: +    for (i=0; i < nargs; i++) { +        Py_DECREF(stack[i]); +    } +    if (stack != small_stack) { +        PyMem_Free(stack);      } -    result = PyObject_Call(lz->func, argtuple, NULL); -    Py_DECREF(argtuple);      return result;  } @@ -1779,7 +1814,7 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds)          if (do_flush == -1)              return NULL;          else if (do_flush) { -            tmp = _PyObject_CallMethodId(file, &PyId_flush, ""); +            tmp = _PyObject_CallMethodId(file, &PyId_flush, NULL);              if (tmp == NULL)                  return NULL;              else @@ -1845,7 +1880,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)      }      /* First of all, flush stderr */ -    tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); +    tmp = _PyObject_CallMethodId(ferr, &PyId_flush, NULL);      if (tmp == NULL)          PyErr_Clear();      else @@ -1854,7 +1889,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)      /* 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_CallMethodId(fin, &PyId_fileno, ""); +    tmp = _PyObject_CallMethodId(fin, &PyId_fileno, NULL);      if (tmp == NULL) {          PyErr_Clear();          tty = 0; @@ -1867,7 +1902,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)          tty = fd == fileno(stdin) && isatty(fd);      }      if (tty) { -        tmp = _PyObject_CallMethodId(fout, &PyId_fileno, ""); +        tmp = _PyObject_CallMethodId(fout, &PyId_fileno, NULL);          if (tmp == NULL) {              PyErr_Clear();              tty = 0; @@ -1898,11 +1933,11 @@ builtin_input_impl(PyObject *module, PyObject *prompt)              /* stdin is a text stream, so it must have an                 encoding. */              goto _readline_errors; -        stdin_encoding_str = _PyUnicode_AsString(stdin_encoding); -        stdin_errors_str = _PyUnicode_AsString(stdin_errors); +        stdin_encoding_str = PyUnicode_AsUTF8(stdin_encoding); +        stdin_errors_str = PyUnicode_AsUTF8(stdin_errors);          if (!stdin_encoding_str || !stdin_errors_str)              goto _readline_errors; -        tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); +        tmp = _PyObject_CallMethodId(fout, &PyId_flush, NULL);          if (tmp == NULL)              PyErr_Clear();          else @@ -1915,8 +1950,8 @@ builtin_input_impl(PyObject *module, PyObject *prompt)              stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors);              if (!stdout_encoding || !stdout_errors)                  goto _readline_errors; -            stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); -            stdout_errors_str = _PyUnicode_AsString(stdout_errors); +            stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding); +            stdout_errors_str = PyUnicode_AsUTF8(stdout_errors);              if (!stdout_encoding_str || !stdout_errors_str)                  goto _readline_errors;              stringpo = PyObject_Str(prompt); @@ -1929,9 +1964,8 @@ builtin_input_impl(PyObject *module, PyObject *prompt)              Py_CLEAR(stringpo);              if (po == NULL)                  goto _readline_errors; -            promptstr = PyBytes_AsString(po); -            if (promptstr == NULL) -                goto _readline_errors; +            assert(PyBytes_Check(po)); +            promptstr = PyBytes_AS_STRING(po);          }          else {              po = NULL; @@ -1983,7 +2017,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)          if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0)              return NULL;      } -    tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); +    tmp = _PyObject_CallMethodId(fout, &PyId_flush, NULL);      if (tmp == NULL)          PyErr_Clear();      else @@ -2087,10 +2121,11 @@ PyDoc_STRVAR(builtin_sorted__doc__,  static PyObject *  builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds)  { -    PyObject *newlist, *v, *seq, *keyfunc=NULL, *newargs; +    PyObject *newlist, *v, *seq, *keyfunc=NULL, **newargs;      PyObject *callable;      static char *kwlist[] = {"iterable", "key", "reverse", 0};      int reverse; +    Py_ssize_t nargs;      /* args 1-3 should match listsort in Objects/listobject.c */      if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi:sorted", @@ -2107,15 +2142,9 @@ builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds)          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); +    newargs = &PyTuple_GET_ITEM(args, 1); +    nargs = PyTuple_GET_SIZE(args) - 1; +    v = _PyObject_FastCallDict(callable, newargs, nargs, kwds);      Py_DECREF(callable);      if (v == NULL) {          Py_DECREF(newlist); @@ -2710,10 +2739,10 @@ _PyBuiltin_Init(void)      SETBUILTIN("zip",                   &PyZip_Type);      debug = PyBool_FromLong(Py_OptimizeFlag == 0);      if (PyDict_SetItemString(dict, "__debug__", debug) < 0) { -        Py_XDECREF(debug); +        Py_DECREF(debug);          return NULL;      } -    Py_XDECREF(debug); +    Py_DECREF(debug);      return mod;  #undef ADD_TO_ALL | 
