summaryrefslogtreecommitdiff
path: root/Python/bltinmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/bltinmodule.c')
-rw-r--r--Python/bltinmodule.c279
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);