diff options
Diffstat (limited to 'Python/bltinmodule.c')
| -rw-r--r-- | Python/bltinmodule.c | 209 | 
1 files changed, 133 insertions, 76 deletions
| diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index d4bf677..bf90aba 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -6,6 +6,9 @@  #include "node.h"  #include "code.h" +#include "asdl.h" +#include "ast.h" +  #include <ctype.h>  #ifdef HAVE_LANGINFO_H @@ -18,20 +21,20 @@     Don't forget to modify PyUnicode_DecodeFSDefault() if you touch any of the     values for Py_FileSystemDefaultEncoding!  */ -#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) +#ifdef HAVE_MBCS  const char *Py_FileSystemDefaultEncoding = "mbcs";  int Py_HasFileSystemDefaultEncoding = 1;  #elif defined(__APPLE__)  const char *Py_FileSystemDefaultEncoding = "utf-8";  int Py_HasFileSystemDefaultEncoding = 1; -#elif defined(HAVE_LANGINFO_H) && defined(CODESET) +#else  const char *Py_FileSystemDefaultEncoding = NULL; /* set by initfsencoding() */  int Py_HasFileSystemDefaultEncoding = 0; -#else -const char *Py_FileSystemDefaultEncoding = "utf-8"; -int Py_HasFileSystemDefaultEncoding = 1;  #endif +_Py_IDENTIFIER(fileno); +_Py_IDENTIFIER(flush); +  static PyObject *  builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)  { @@ -39,6 +42,7 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)      PyObject *cls = NULL;      Py_ssize_t nargs;      int isclass; +    _Py_IDENTIFIER(__prepare__);      assert(args != NULL);      if (!PyTuple_Check(args)) { @@ -99,6 +103,7 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)          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: */ @@ -118,7 +123,7 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)      }      /* else: meta is not a class, so we cannot do the metaclass         calculation, so we will use the explicitly given object as it is */ -    prep = PyObject_GetAttrString(meta, "__prepare__"); +    prep = _PyObject_GetAttrId(meta, &PyId___prepare__);      if (prep == NULL) {          if (PyErr_ExceptionMatches(PyExc_AttributeError)) {              PyErr_Clear(); @@ -179,21 +184,18 @@ builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)  {      static char *kwlist[] = {"name", "globals", "locals", "fromlist",                               "level", 0}; -    char *name; -    PyObject *globals = NULL; -    PyObject *locals = NULL; -    PyObject *fromlist = NULL; -    int level = -1; +    PyObject *name, *globals = NULL, *locals = NULL, *fromlist = NULL; +    int level = 0; -    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|OOOi:__import__", +    if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|OOOi:__import__",                      kwlist, &name, &globals, &locals, &fromlist, &level))          return NULL; -    return PyImport_ImportModuleLevel(name, globals, locals, -                                      fromlist, level); +    return PyImport_ImportModuleLevelObject(name, globals, locals, +                                            fromlist, level);  }  PyDoc_STRVAR(import_doc, -"__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\ +"__import__(name, globals=None, locals=None, fromlist=(), level=0) -> module\n\  \n\  Import a module. Because this function is meant for use by the Python\n\  interpreter and not for general use it is better to use\n\ @@ -206,8 +208,7 @@ empty list to emulate ``import name''.\n\  When importing a module from a package, note that __import__('A.B', ...)\n\  returns package A when fromlist is empty, but its submodule B when\n\  fromlist is not empty.  Level is used to determine whether to perform \n\ -absolute or relative imports.  -1 is the original strategy of attempting\n\ -both absolute and relative imports, 0 is absolute, a positive number\n\ +absolute or relative imports. 0 is absolute while a positive number\n\  is the number of parent directories to search relative to the current module."); @@ -438,6 +439,19 @@ filter_next(filterobject *lz)      }  } +static PyObject * +filter_reduce(filterobject *lz) +{ +    return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); + +static PyMethodDef filter_methods[] = { +    {"__reduce__",   (PyCFunction)filter_reduce,   METH_NOARGS, reduce_doc}, +    {NULL,           NULL}           /* sentinel */ +}; +  PyDoc_STRVAR(filter_doc,  "filter(function or None, iterable) --> filter object\n\  \n\ @@ -474,7 +488,7 @@ PyTypeObject PyFilter_Type = {      0,                                  /* tp_weaklistoffset */      PyObject_SelfIter,                  /* tp_iter */      (iternextfunc)filter_next,          /* tp_iternext */ -    0,                                  /* tp_methods */ +    filter_methods,                     /* tp_methods */      0,                                  /* tp_members */      0,                                  /* tp_getset */      0,                                  /* tp_base */ @@ -518,17 +532,10 @@ builtin_chr(PyObject *self, PyObject *args)      return PyUnicode_FromOrdinal(x);  } -PyDoc_VAR(chr_doc) = PyDoc_STR( +PyDoc_STRVAR(chr_doc,  "chr(i) -> Unicode character\n\  \n\ -Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff." -) -#ifndef Py_UNICODE_WIDE -PyDoc_STR( -"\nIf 0x10000 <= i, a surrogate pair is returned." -) -#endif -; +Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.");  static char * @@ -539,8 +546,8 @@ source_as_string(PyObject *cmd, char *funcname, char *what, PyCompilerFlags *cf)      if (PyUnicode_Check(cmd)) {          cf->cf_flags |= PyCF_IGNORE_COOKIE; -        cmd = _PyUnicode_AsDefaultEncodedString(cmd, NULL); -        if (cmd == NULL) +        str = PyUnicode_AsUTF8AndSize(cmd, &size); +        if (str == NULL)              return NULL;      }      else if (!PyObject_CheckReadBuffer(cmd)) { @@ -549,9 +556,10 @@ source_as_string(PyObject *cmd, char *funcname, char *what, PyCompilerFlags *cf)            funcname, what);          return NULL;      } -    if (PyObject_AsReadBuffer(cmd, (const void **)&str, &size) < 0) { +    else if (PyObject_AsReadBuffer(cmd, (const void **)&str, &size) < 0) {          return NULL;      } +      if (strlen(str) != size) {          PyErr_SetString(PyExc_TypeError,                          "source code string cannot contain null bytes"); @@ -640,6 +648,10 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)                  PyArena_Free(arena);                  goto error;              } +            if (!PyAST_Validate(mod)) { +                PyArena_Free(arena); +                goto error; +            }              result = (PyObject*)PyAST_CompileEx(mod, filename,                                                  &cf, optimize, arena);              PyArena_Free(arena); @@ -1058,6 +1070,31 @@ map_next(mapobject *lz)      return result;  } +static PyObject * +map_reduce(mapobject *lz) +{ +    Py_ssize_t numargs = PyTuple_GET_SIZE(lz->iters); +    PyObject *args = PyTuple_New(numargs+1); +    Py_ssize_t i; +    if (args == NULL) +        return NULL; +    Py_INCREF(lz->func); +    PyTuple_SET_ITEM(args, 0, lz->func); +    for (i = 0; i<numargs; i++){ +        PyObject *it = PyTuple_GET_ITEM(lz->iters, i); +        Py_INCREF(it); +        PyTuple_SET_ITEM(args, i+1, it); +    } + +    return Py_BuildValue("ON", Py_TYPE(lz), args); +} + +static PyMethodDef map_methods[] = { +    {"__reduce__",   (PyCFunction)map_reduce,   METH_NOARGS, reduce_doc}, +    {NULL,           NULL}           /* sentinel */ +}; + +  PyDoc_STRVAR(map_doc,  "map(func, *iterables) --> map object\n\  \n\ @@ -1094,7 +1131,7 @@ PyTypeObject PyMap_Type = {      0,                                  /* tp_weaklistoffset */      PyObject_SelfIter,                  /* tp_iter */      (iternextfunc)map_next,     /* tp_iternext */ -    0,                                  /* tp_methods */ +    map_methods,                        /* tp_methods */      0,                                  /* tp_members */      0,                                  /* tp_getset */      0,                                  /* tp_base */ @@ -1118,7 +1155,7 @@ builtin_next(PyObject *self, PyObject *args)          return NULL;      if (!PyIter_Check(it)) {          PyErr_Format(PyExc_TypeError, -            "%.200s object is not an iterator", +            "'%.200s' object is not an iterator",              it->ob_type->tp_name);          return NULL;      } @@ -1424,24 +1461,13 @@ builtin_ord(PyObject *self, PyObject* obj)          }      }      else if (PyUnicode_Check(obj)) { -        size = PyUnicode_GET_SIZE(obj); +        if (PyUnicode_READY(obj) == -1) +            return NULL; +        size = PyUnicode_GET_LENGTH(obj);          if (size == 1) { -            ord = (long)*PyUnicode_AS_UNICODE(obj); +            ord = (long)PyUnicode_READ_CHAR(obj, 0);              return PyLong_FromLong(ord);          } -#ifndef Py_UNICODE_WIDE -        if (size == 2) { -            /* Decode a valid surrogate pair */ -            int c0 = PyUnicode_AS_UNICODE(obj)[0]; -            int c1 = PyUnicode_AS_UNICODE(obj)[1]; -            if (0xD800 <= c0 && c0 <= 0xDBFF && -                0xDC00 <= c1 && c1 <= 0xDFFF) { -                ord = ((((c0 & 0x03FF) << 10) | (c1 & 0x03FF)) + -                       0x00010000); -                return PyLong_FromLong(ord); -            } -        } -#endif      }      else if (PyByteArray_Check(obj)) {          /* XXX Hopefully this is temporary */ @@ -1469,13 +1495,7 @@ PyDoc_VAR(ord_doc) = PyDoc_STR(  "ord(c) -> integer\n\  \n\  Return the integer ordinal of a one-character string." -) -#ifndef Py_UNICODE_WIDE -PyDoc_STR( -"\nA valid surrogate pair is also accepted." -) -#endif -; +);  static PyObject * @@ -1499,15 +1519,15 @@ equivalent to (x**y) % z, but may be more efficient (e.g. for longs).");  static PyObject *  builtin_print(PyObject *self, PyObject *args, PyObject *kwds)  { -    static char *kwlist[] = {"sep", "end", "file", 0}; +    static char *kwlist[] = {"sep", "end", "file", "flush", 0};      static PyObject *dummy_args; -    PyObject *sep = NULL, *end = NULL, *file = NULL; +    PyObject *sep = NULL, *end = NULL, *file = NULL, *flush = NULL;      int i, err;      if (dummy_args == NULL && !(dummy_args = PyTuple_New(0))) -            return NULL; -    if (!PyArg_ParseTupleAndKeywords(dummy_args, kwds, "|OOO:print", -                                     kwlist, &sep, &end, &file)) +        return NULL; +    if (!PyArg_ParseTupleAndKeywords(dummy_args, kwds, "|OOOO:print", +                                     kwlist, &sep, &end, &file, &flush))          return NULL;      if (file == NULL || file == Py_None) {          file = PySys_GetObject("stdout"); @@ -1558,17 +1578,32 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds)      if (err)          return NULL; +    if (flush != NULL) { +        PyObject *tmp; +        int do_flush = PyObject_IsTrue(flush); +        if (do_flush == -1) +            return NULL; +        else if (do_flush) { +            tmp = PyObject_CallMethod(file, "flush", ""); +            if (tmp == NULL) +                return NULL; +            else +                Py_DECREF(tmp); +        } +    } +      Py_RETURN_NONE;  }  PyDoc_STRVAR(print_doc, -"print(value, ..., sep=' ', end='\\n', file=sys.stdout)\n\ +"print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n\  \n\  Prints the values to a stream, or to sys.stdout by default.\n\  Optional keyword arguments:\n\ -file: a file-like object (stream); defaults to the current sys.stdout.\n\ -sep:  string inserted between values, default a space.\n\ -end:  string appended after the last value, default a newline."); +file:  a file-like object (stream); defaults to the current sys.stdout.\n\ +sep:   string inserted between values, default a space.\n\ +end:   string appended after the last value, default a newline.\n\ +flush: whether to forcibly flush the stream.");  static PyObject * @@ -1604,7 +1639,7 @@ builtin_input(PyObject *self, PyObject *args)      }      /* First of all, flush stderr */ -    tmp = PyObject_CallMethod(ferr, "flush", ""); +    tmp = _PyObject_CallMethodId(ferr, &PyId_flush, "");      if (tmp == NULL)          PyErr_Clear();      else @@ -1613,7 +1648,7 @@ builtin_input(PyObject *self, PyObject *args)      /* 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_CallMethod(fin, "fileno", ""); +    tmp = _PyObject_CallMethodId(fin, &PyId_fileno, "");      if (tmp == NULL) {          PyErr_Clear();          tty = 0; @@ -1626,7 +1661,7 @@ builtin_input(PyObject *self, PyObject *args)          tty = fd == fileno(stdin) && isatty(fd);      }      if (tty) { -        tmp = PyObject_CallMethod(fout, "fileno", ""); +        tmp = _PyObject_CallMethodId(fout, &PyId_fileno, "");          if (tmp == NULL)              PyErr_Clear();          else { @@ -1648,9 +1683,11 @@ builtin_input(PyObject *self, PyObject *args)          char *stdin_encoding_str, *stdin_errors_str;          PyObject *result;          size_t len; +        _Py_IDENTIFIER(encoding); +        _Py_IDENTIFIER(errors); -        stdin_encoding = PyObject_GetAttrString(fin, "encoding"); -        stdin_errors = PyObject_GetAttrString(fin, "errors"); +        stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding); +        stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors);          if (!stdin_encoding || !stdin_errors)              /* stdin is a text stream, so it must have an                 encoding. */ @@ -1659,7 +1696,7 @@ builtin_input(PyObject *self, PyObject *args)          stdin_errors_str = _PyUnicode_AsString(stdin_errors);          if (!stdin_encoding_str || !stdin_errors_str)              goto _readline_errors; -        tmp = PyObject_CallMethod(fout, "flush", ""); +        tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");          if (tmp == NULL)              PyErr_Clear();          else @@ -1668,8 +1705,8 @@ builtin_input(PyObject *self, PyObject *args)              /* We have a prompt, encode it as stdout would */              char *stdout_encoding_str, *stdout_errors_str;              PyObject *stringpo; -            stdout_encoding = PyObject_GetAttrString(fout, "encoding"); -            stdout_errors = PyObject_GetAttrString(fout, "errors"); +            stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding); +            stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors);              if (!stdout_encoding || !stdout_errors)                  goto _readline_errors;              stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); @@ -1739,7 +1776,7 @@ builtin_input(PyObject *self, PyObject *args)          if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0)              return NULL;      } -    tmp = PyObject_CallMethod(fout, "flush", ""); +    tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");      if (tmp == NULL)          PyErr_Clear();      else @@ -1821,6 +1858,7 @@ builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds)      PyObject *callable;      static char *kwlist[] = {"iterable", "key", "reverse", 0};      int reverse; +    _Py_IDENTIFIER(sort);      /* args 1-3 should match listsort in Objects/listobject.c */      if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi:sorted", @@ -1831,7 +1869,7 @@ builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds)      if (newlist == NULL)          return NULL; -    callable = PyObject_GetAttrString(newlist, "sort"); +    callable = _PyObject_GetAttrId(newlist, &PyId_sort);      if (callable == NULL) {          Py_DECREF(newlist);          return NULL; @@ -1877,7 +1915,8 @@ builtin_vars(PyObject *self, PyObject *args)              Py_INCREF(d);      }      else { -        d = PyObject_GetAttrString(v, "__dict__"); +        _Py_IDENTIFIER(__dict__); +        d = _PyObject_GetAttrId(v, &PyId___dict__);          if (d == NULL) {              PyErr_SetString(PyExc_TypeError,                  "vars() argument must have __dict__ attribute"); @@ -1921,12 +1960,18 @@ builtin_sum(PyObject *self, PyObject *args)              Py_DECREF(iter);              return NULL;          } -        if (PyByteArray_Check(result)) { +        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);      } @@ -2229,6 +2274,18 @@ zip_next(zipobject *lz)      return result;  } +static PyObject * +zip_reduce(zipobject *lz) +{ +    /* Just recreate the zip with the internal iterator tuple */ +    return Py_BuildValue("OO", Py_TYPE(lz), lz->ittuple); +} + +static PyMethodDef zip_methods[] = { +    {"__reduce__",   (PyCFunction)zip_reduce,   METH_NOARGS, reduce_doc}, +    {NULL,           NULL}           /* sentinel */ +}; +  PyDoc_STRVAR(zip_doc,  "zip(iter1 [,iter2 [...]]) --> zip object\n\  \n\ @@ -2267,7 +2324,7 @@ PyTypeObject PyZip_Type = {      0,                                  /* tp_weaklistoffset */      PyObject_SelfIter,                  /* tp_iter */      (iternextfunc)zip_next,     /* tp_iternext */ -    0,                                  /* tp_methods */ +    zip_methods,                        /* tp_methods */      0,                                  /* tp_members */      0,                                  /* tp_getset */      0,                                  /* tp_base */ | 
