diff options
Diffstat (limited to 'Python/bltinmodule.c')
-rw-r--r-- | Python/bltinmodule.c | 279 |
1 files changed, 168 insertions, 111 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 3e44aa0566..d4bf677cb7 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -5,10 +5,13 @@ #include "node.h" #include "code.h" -#include "eval.h" #include <ctype.h> +#ifdef HAVE_LANGINFO_H +#include <langinfo.h> /* CODESET */ +#endif + /* The default encoding used by the platform file system APIs Can remain NULL for all platforms that don't have such a concept @@ -21,40 +24,21 @@ int Py_HasFileSystemDefaultEncoding = 1; #elif defined(__APPLE__) const char *Py_FileSystemDefaultEncoding = "utf-8"; int Py_HasFileSystemDefaultEncoding = 1; -#else -const char *Py_FileSystemDefaultEncoding = NULL; /* use default */ +#elif defined(HAVE_LANGINFO_H) && defined(CODESET) +const char *Py_FileSystemDefaultEncoding = NULL; /* set by initfsencoding() */ int Py_HasFileSystemDefaultEncoding = 0; +#else +const char *Py_FileSystemDefaultEncoding = "utf-8"; +int Py_HasFileSystemDefaultEncoding = 1; #endif -int -_Py_SetFileSystemEncoding(PyObject *s) -{ - PyObject *defenc, *codec; - if (!PyUnicode_Check(s)) { - PyErr_BadInternalCall(); - return -1; - } - defenc = _PyUnicode_AsDefaultEncodedString(s, NULL); - if (!defenc) - return -1; - codec = _PyCodec_Lookup(PyBytes_AsString(defenc)); - if (codec == NULL) - return -1; - Py_DECREF(codec); - if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) - /* A file system encoding was set at run-time */ - free((char*)Py_FileSystemDefaultEncoding); - Py_FileSystemDefaultEncoding = strdup(PyBytes_AsString(defenc)); - Py_HasFileSystemDefaultEncoding = 0; - return 0; -} - static PyObject * builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) { - PyObject *func, *name, *bases, *mkw, *meta, *prep, *ns, *cell; + PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *cell; PyObject *cls = NULL; - Py_ssize_t nargs, nbases; + Py_ssize_t nargs; + int isclass; assert(args != NULL); if (!PyTuple_Check(args)) { @@ -78,7 +62,6 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) bases = PyTuple_GetSlice(args, 2, nargs); if (bases == NULL) return NULL; - nbases = nargs - 2; if (kwds == NULL) { meta = NULL; @@ -99,17 +82,42 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) Py_DECREF(bases); return NULL; } + /* metaclass is explicitly given, check if it's indeed a class */ + isclass = PyType_Check(meta); } } if (meta == NULL) { - if (PyTuple_GET_SIZE(bases) == 0) + /* 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 *) (base0->ob_type); } 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) { + Py_DECREF(meta); + Py_XDECREF(mkw); + Py_DECREF(bases); + return NULL; + } + if (winner != meta) { + Py_DECREF(meta); + meta = winner; + Py_INCREF(meta); + } } + /* 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__"); if (prep == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { @@ -150,10 +158,8 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) cls = PyEval_CallObjectWithKeywords(meta, margs, mkw); Py_DECREF(margs); } - if (cls != NULL && PyCell_Check(cell)) { - Py_INCREF(cls); - PyCell_SET(cell, cls); - } + if (cls != NULL && PyCell_Check(cell)) + PyCell_Set(cell, cls); Py_DECREF(cell); } Py_DECREF(ns); @@ -189,8 +195,12 @@ builtin___import__(PyObject *self, PyObject *args, PyObject *kwds) PyDoc_STRVAR(import_doc, "__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\ \n\ -Import a module. The globals are only used to determine the context;\n\ -they are not modified. The locals are currently unused. The fromlist\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\ +importlib.import_module() to programmatically import a module.\n\ +\n\ +The globals argument is only used to determine the context;\n\ +they are not modified. The locals argument is unused. The fromlist\n\ should be a list of names to emulate ``from name import ...'', or an\n\ empty list to emulate ``import name''.\n\ When importing a module from a package, note that __import__('A.B', ...)\n\ @@ -252,7 +262,8 @@ builtin_all(PyObject *self, PyObject *v) PyDoc_STRVAR(all_doc, "all(iterable) -> bool\n\ \n\ -Return True if bool(x) is True for all values x in the iterable."); +Return True if bool(x) is True for all values x in the iterable.\n\ +If the iterable is empty, return True."); static PyObject * builtin_any(PyObject *self, PyObject *v) @@ -294,7 +305,8 @@ builtin_any(PyObject *self, PyObject *v) PyDoc_STRVAR(any_doc, "any(iterable) -> bool\n\ \n\ -Return True if bool(x) is True for any x in the iterable."); +Return True if bool(x) is True for any x in the iterable.\n\ +If the iterable is empty, return False."); static PyObject * builtin_ascii(PyObject *self, PyObject *v) @@ -320,7 +332,21 @@ builtin_bin(PyObject *self, PyObject *v) PyDoc_STRVAR(bin_doc, "bin(number) -> string\n\ \n\ -Return the binary representation of an integer or long integer."); +Return the binary representation of an integer."); + + +static PyObject * +builtin_callable(PyObject *self, PyObject *v) +{ + return PyBool_FromLong((long)PyCallable_Check(v)); +} + +PyDoc_STRVAR(callable_doc, +"callable(object) -> bool\n\ +\n\ +Return whether the object is callable (i.e., some kind of function).\n\ +Note that classes are callable, as are instances of classes with a\n\ +__call__() method."); typedef struct { @@ -404,9 +430,11 @@ filter_next(filterobject *lz) ok = PyObject_IsTrue(good); Py_DECREF(good); } - if (ok) + if (ok > 0) return item; Py_DECREF(item); + if (ok < 0) + return NULL; } } @@ -468,7 +496,7 @@ builtin_format(PyObject *self, PyObject *args) PyObject *format_spec = NULL; if (!PyArg_ParseTuple(args, "O|U:format", &value, &format_spec)) - return NULL; + return NULL; return PyObject_Format(value, format_spec); } @@ -542,19 +570,20 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) int mode = -1; int dont_inherit = 0; int supplied_flags = 0; + int optimize = -1; int is_ast; PyCompilerFlags cf; PyObject *cmd; static char *kwlist[] = {"source", "filename", "mode", "flags", - "dont_inherit", NULL}; + "dont_inherit", "optimize", NULL}; int start[] = {Py_file_input, Py_eval_input, Py_single_input}; PyObject *result; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|ii:compile", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|iii:compile", kwlist, &cmd, PyUnicode_FSConverter, &filename_obj, &startstr, &supplied_flags, - &dont_inherit)) + &dont_inherit, &optimize)) return NULL; filename = PyBytes_AS_STRING(filename_obj); @@ -569,6 +598,12 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) } /* 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 (!dont_inherit) { PyEval_MergeCompilerFlags(&cf); } @@ -598,13 +633,15 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) mod_ty mod; arena = PyArena_New(); + if (arena == NULL) + goto error; mod = PyAST_obj2mod(cmd, arena, mode); if (mod == NULL) { PyArena_Free(arena); goto error; } - result = (PyObject*)PyAST_Compile(mod, filename, - &cf, arena); + result = (PyObject*)PyAST_CompileEx(mod, filename, + &cf, optimize, arena); PyArena_Free(arena); } goto finally; @@ -614,7 +651,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) if (str == NULL) goto error; - result = Py_CompileStringFlags(str, filename, start[mode], &cf); + result = Py_CompileStringExFlags(str, filename, start[mode], &cf, optimize); goto finally; error: @@ -726,7 +763,7 @@ builtin_eval(PyObject *self, PyObject *args) "code object passed to eval() may not contain free variables"); return NULL; } - return PyEval_EvalCode((PyCodeObject *) cmd, globals, locals); + return PyEval_EvalCode(cmd, globals, locals); } cf.cf_flags = PyCF_SOURCE_IS_UTF8; @@ -758,7 +795,6 @@ builtin_exec(PyObject *self, PyObject *args) { PyObject *v; PyObject *prog, *globals = Py_None, *locals = Py_None; - int plain = 0; if (!PyArg_UnpackTuple(args, "exec", 1, 3, &prog, &globals, &locals)) return NULL; @@ -767,7 +803,6 @@ builtin_exec(PyObject *self, PyObject *args) globals = PyEval_GetGlobals(); if (locals == Py_None) { locals = PyEval_GetLocals(); - plain = 1; } if (!globals || !locals) { PyErr_SetString(PyExc_SystemError, @@ -802,7 +837,7 @@ builtin_exec(PyObject *self, PyObject *args) "contain free variables"); return NULL; } - v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals); + v = PyEval_EvalCode(prog, globals, locals); } else { char *str; @@ -897,24 +932,21 @@ builtin_hasattr(PyObject *self, PyObject *args) } v = PyObject_GetAttr(v, name); if (v == NULL) { - if (!PyErr_ExceptionMatches(PyExc_Exception)) - return NULL; - else { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); - Py_INCREF(Py_False); - return Py_False; + Py_RETURN_FALSE; } + return NULL; } Py_DECREF(v); - Py_INCREF(Py_True); - return Py_True; + Py_RETURN_TRUE; } PyDoc_STRVAR(hasattr_doc, "hasattr(object, name) -> bool\n\ \n\ Return whether the object has an attribute with the given name.\n\ -(This is done by calling getattr(object, name) and catching exceptions.)"); +(This is done by calling getattr(object, name) and catching AttributeError.)"); static PyObject * @@ -1163,12 +1195,12 @@ Delete a named attribute on an object; delattr(x, 'y') is equivalent to\n\ static PyObject * builtin_hash(PyObject *self, PyObject *v) { - long x; + Py_hash_t x; x = PyObject_Hash(v); if (x == -1) return NULL; - return PyLong_FromLong(x); + return PyLong_FromSsize_t(x); } PyDoc_STRVAR(hash_doc, @@ -1187,7 +1219,7 @@ builtin_hex(PyObject *self, PyObject *v) PyDoc_STRVAR(hex_doc, "hex(number) -> string\n\ \n\ -Return the hexadecimal representation of an integer or long integer."); +Return the hexadecimal representation of an integer."); static PyObject * @@ -1375,7 +1407,7 @@ builtin_oct(PyObject *self, PyObject *v) PyDoc_STRVAR(oct_doc, "oct(number) -> string\n\ \n\ -Return the octal representation of an integer or long integer."); +Return the octal representation of an integer."); static PyObject * @@ -1472,10 +1504,8 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds) PyObject *sep = NULL, *end = NULL, *file = NULL; int i, err; - if (dummy_args == NULL) { - if (!(dummy_args = PyTuple_New(0))) + 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; @@ -1486,13 +1516,19 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds) Py_RETURN_NONE; } - if (sep && sep != Py_None && !PyUnicode_Check(sep)) { + 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", sep->ob_type->tp_name); return NULL; } - if (end && end != Py_None && !PyUnicode_Check(end)) { + 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", end->ob_type->tp_name); @@ -1501,7 +1537,7 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds) for (i = 0; i < PyTuple_Size(args); i++) { if (i > 0) { - if (sep == NULL || sep == Py_None) + if (sep == NULL) err = PyFile_WriteString(" ", file); else err = PyFile_WriteObject(sep, file, @@ -1515,7 +1551,7 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } - if (end == NULL || end == Py_None) + if (end == NULL) err = PyFile_WriteString("\n", file); else err = PyFile_WriteObject(end, file, Py_PRINT_RAW); @@ -1604,85 +1640,98 @@ builtin_input(PyObject *self, PyObject *args) /* If we're interactive, use (GNU) readline */ if (tty) { - PyObject *po; + PyObject *po = NULL; char *prompt; - char *s; - PyObject *stdin_encoding; + char *s = NULL; + PyObject *stdin_encoding = NULL, *stdin_errors = NULL; + PyObject *stdout_encoding = NULL, *stdout_errors = NULL; + char *stdin_encoding_str, *stdin_errors_str; PyObject *result; + size_t len; stdin_encoding = PyObject_GetAttrString(fin, "encoding"); - if (!stdin_encoding) + stdin_errors = PyObject_GetAttrString(fin, "errors"); + if (!stdin_encoding || !stdin_errors) /* stdin is a text stream, so it must have an encoding. */ - return NULL; + goto _readline_errors; + stdin_encoding_str = _PyUnicode_AsString(stdin_encoding); + stdin_errors_str = _PyUnicode_AsString(stdin_errors); + if (!stdin_encoding_str || !stdin_errors_str) + goto _readline_errors; tmp = PyObject_CallMethod(fout, "flush", ""); if (tmp == NULL) PyErr_Clear(); else Py_DECREF(tmp); if (promptarg != NULL) { + /* We have a prompt, encode it as stdout would */ + char *stdout_encoding_str, *stdout_errors_str; PyObject *stringpo; - PyObject *stdout_encoding; - stdout_encoding = PyObject_GetAttrString(fout, - "encoding"); - if (stdout_encoding == NULL) { - Py_DECREF(stdin_encoding); - return NULL; - } + stdout_encoding = PyObject_GetAttrString(fout, "encoding"); + stdout_errors = PyObject_GetAttrString(fout, "errors"); + if (!stdout_encoding || !stdout_errors) + goto _readline_errors; + stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); + stdout_errors_str = _PyUnicode_AsString(stdout_errors); + if (!stdout_encoding_str || !stdout_errors_str) + goto _readline_errors; stringpo = PyObject_Str(promptarg); - if (stringpo == NULL) { - Py_DECREF(stdin_encoding); - Py_DECREF(stdout_encoding); - return NULL; - } + if (stringpo == NULL) + goto _readline_errors; po = PyUnicode_AsEncodedString(stringpo, - _PyUnicode_AsString(stdout_encoding), NULL); - Py_DECREF(stdout_encoding); - Py_DECREF(stringpo); - if (po == NULL) { - Py_DECREF(stdin_encoding); - return NULL; - } + stdout_encoding_str, stdout_errors_str); + Py_CLEAR(stdout_encoding); + Py_CLEAR(stdout_errors); + Py_CLEAR(stringpo); + if (po == NULL) + goto _readline_errors; prompt = PyBytes_AsString(po); - if (prompt == NULL) { - Py_DECREF(stdin_encoding); - Py_DECREF(po); - return NULL; - } + if (prompt == NULL) + goto _readline_errors; } else { po = NULL; prompt = ""; } s = PyOS_Readline(stdin, stdout, prompt); - Py_XDECREF(po); if (s == NULL) { if (!PyErr_Occurred()) PyErr_SetNone(PyExc_KeyboardInterrupt); - Py_DECREF(stdin_encoding); - return NULL; + goto _readline_errors; } - if (*s == '\0') { + + len = strlen(s); + if (len == 0) { PyErr_SetNone(PyExc_EOFError); result = NULL; } - else { /* strip trailing '\n' */ - size_t len = strlen(s); + else { if (len > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "input: input too long"); result = NULL; } else { - result = PyUnicode_Decode - (s, len-1, - _PyUnicode_AsString(stdin_encoding), - NULL); + 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); return result; + _readline_errors: + Py_XDECREF(stdin_encoding); + Py_XDECREF(stdout_encoding); + Py_XDECREF(stdin_errors); + Py_XDECREF(stdout_errors); + Py_XDECREF(po); + return NULL; } /* Fallback if we're not interactive */ @@ -1979,6 +2028,15 @@ builtin_sum(PyObject *self, PyObject *args) } 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. */ temp = PyNumber_Add(result, item); Py_DECREF(result); Py_DECREF(item); @@ -2233,6 +2291,7 @@ static PyMethodDef builtin_methods[] = { {"any", builtin_any, METH_O, any_doc}, {"ascii", builtin_ascii, METH_O, ascii_doc}, {"bin", builtin_bin, METH_O, bin_doc}, + {"callable", builtin_callable, METH_O, callable_doc}, {"chr", builtin_chr, METH_VARARGS, chr_doc}, {"compile", (PyCFunction)builtin_compile, METH_VARARGS | METH_KEYWORDS, compile_doc}, {"delattr", builtin_delattr, METH_VARARGS, delattr_doc}, @@ -2323,9 +2382,7 @@ _PyBuiltin_Init(void) SETBUILTIN("bytearray", &PyByteArray_Type); SETBUILTIN("bytes", &PyBytes_Type); SETBUILTIN("classmethod", &PyClassMethod_Type); -#ifndef WITHOUT_COMPLEX SETBUILTIN("complex", &PyComplex_Type); -#endif SETBUILTIN("dict", &PyDict_Type); SETBUILTIN("enumerate", &PyEnum_Type); SETBUILTIN("filter", &PyFilter_Type); |