summaryrefslogtreecommitdiffstats
path: root/Python/bltinmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/bltinmodule.c')
-rw-r--r--Python/bltinmodule.c199
1 files changed, 123 insertions, 76 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index c94daea..d905ba2 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -32,8 +32,19 @@ const char *Py_FileSystemDefaultEncoding = NULL; /* set by initfsencoding() */
int Py_HasFileSystemDefaultEncoding = 0;
#endif
+_Py_IDENTIFIER(__builtins__);
+_Py_IDENTIFIER(__dict__);
+_Py_IDENTIFIER(__prepare__);
+_Py_IDENTIFIER(__round__);
+_Py_IDENTIFIER(encoding);
+_Py_IDENTIFIER(errors);
_Py_IDENTIFIER(fileno);
_Py_IDENTIFIER(flush);
+_Py_IDENTIFIER(metaclass);
+_Py_IDENTIFIER(sort);
+_Py_IDENTIFIER(stdin);
+_Py_IDENTIFIER(stdout);
+_Py_IDENTIFIER(stderr);
static PyObject *
builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
@@ -42,7 +53,6 @@ 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)) {
@@ -57,6 +67,11 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
return NULL;
}
func = PyTuple_GET_ITEM(args, 0); /* Better be callable */
+ if (!PyFunction_Check(func)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__build_class__: func must be a function");
+ return NULL;
+ }
name = PyTuple_GET_ITEM(args, 1);
if (!PyUnicode_Check(name)) {
PyErr_SetString(PyExc_TypeError,
@@ -77,10 +92,10 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
Py_DECREF(bases);
return NULL;
}
- meta = PyDict_GetItemString(mkw, "metaclass");
+ meta = _PyDict_GetItemId(mkw, &PyId_metaclass);
if (meta != NULL) {
Py_INCREF(meta);
- if (PyDict_DelItemString(mkw, "metaclass") < 0) {
+ if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) {
Py_DECREF(meta);
Py_DECREF(mkw);
Py_DECREF(bases);
@@ -155,7 +170,9 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
Py_DECREF(bases);
return NULL;
}
- cell = PyObject_CallFunctionObjArgs(func, ns, NULL);
+ cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns,
+ NULL, 0, NULL, 0, NULL, 0, NULL,
+ PyFunction_GET_CLOSURE(func));
if (cell != NULL) {
PyObject *margs;
margs = PyTuple_Pack(3, name, bases, ns);
@@ -333,7 +350,11 @@ builtin_bin(PyObject *self, PyObject *v)
PyDoc_STRVAR(bin_doc,
"bin(number) -> string\n\
\n\
-Return the binary representation of an integer.");
+Return the binary representation of an integer.\n\
+\n\
+ >>> bin(2796202)\n\
+ '0b1010101010101010101010'\n\
+");
static PyObject *
@@ -572,8 +593,7 @@ static PyObject *
builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
{
char *str;
- PyObject *filename_obj;
- char *filename;
+ PyObject *filename;
char *startstr;
int mode = -1;
int dont_inherit = 0;
@@ -589,12 +609,11 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|iii:compile", kwlist,
&cmd,
- PyUnicode_FSConverter, &filename_obj,
+ PyUnicode_FSDecoder, &filename,
&startstr, &supplied_flags,
&dont_inherit, &optimize))
return NULL;
- filename = PyBytes_AS_STRING(filename_obj);
cf.cf_flags = supplied_flags | PyCF_SOURCE_IS_UTF8;
if (supplied_flags &
@@ -652,24 +671,24 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
PyArena_Free(arena);
goto error;
}
- result = (PyObject*)PyAST_CompileEx(mod, filename,
- &cf, optimize, arena);
+ result = (PyObject*)PyAST_CompileObject(mod, filename,
+ &cf, optimize, arena);
PyArena_Free(arena);
}
goto finally;
}
- str = source_as_string(cmd, "compile", "string, bytes, AST or code", &cf);
+ str = source_as_string(cmd, "compile", "string, bytes or AST", &cf);
if (str == NULL)
goto error;
- result = Py_CompileStringExFlags(str, filename, start[mode], &cf, optimize);
+ result = Py_CompileStringObject(str, filename, start[mode], &cf, optimize);
goto finally;
error:
result = NULL;
finally:
- Py_DECREF(filename_obj);
+ Py_DECREF(filename);
return result;
}
@@ -750,8 +769,11 @@ builtin_eval(PyObject *self, PyObject *args)
}
if (globals == Py_None) {
globals = PyEval_GetGlobals();
- if (locals == Py_None)
+ if (locals == Py_None) {
locals = PyEval_GetLocals();
+ if (locals == NULL)
+ return NULL;
+ }
}
else if (locals == Py_None)
locals = globals;
@@ -763,9 +785,9 @@ builtin_eval(PyObject *self, PyObject *args)
return NULL;
}
- if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
- if (PyDict_SetItemString(globals, "__builtins__",
- PyEval_GetBuiltins()) != 0)
+ if (_PyDict_GetItemId(globals, &PyId___builtins__) == NULL) {
+ if (_PyDict_SetItemId(globals, &PyId___builtins__,
+ PyEval_GetBuiltins()) != 0)
return NULL;
}
@@ -815,6 +837,8 @@ builtin_exec(PyObject *self, PyObject *args)
globals = PyEval_GetGlobals();
if (locals == Py_None) {
locals = PyEval_GetLocals();
+ if (locals == NULL)
+ return NULL;
}
if (!globals || !locals) {
PyErr_SetString(PyExc_SystemError,
@@ -836,9 +860,9 @@ builtin_exec(PyObject *self, PyObject *args)
locals->ob_type->tp_name);
return NULL;
}
- if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
- if (PyDict_SetItemString(globals, "__builtins__",
- PyEval_GetBuiltins()) != 0)
+ if (_PyDict_GetItemId(globals, &PyId___builtins__) == NULL) {
+ if (_PyDict_SetItemId(globals, &PyId___builtins__,
+ PyEval_GetBuiltins()) != 0)
return NULL;
}
@@ -1256,7 +1280,11 @@ builtin_hex(PyObject *self, PyObject *v)
PyDoc_STRVAR(hex_doc,
"hex(number) -> string\n\
\n\
-Return the hexadecimal representation of an integer.");
+Return the hexadecimal representation of an integer.\n\
+\n\
+ >>> hex(3735928559)\n\
+ '0xdeadbeef'\n\
+");
static PyObject *
@@ -1297,9 +1325,9 @@ builtin_len(PyObject *self, PyObject *v)
}
PyDoc_STRVAR(len_doc,
-"len(object) -> integer\n\
+"len(object)\n\
\n\
-Return the number of items of a sequence or mapping.");
+Return the number of items of a sequence or collection.");
static PyObject *
@@ -1322,26 +1350,35 @@ static PyObject *
min_max(PyObject *args, PyObject *kwds, int op)
{
PyObject *v, *it, *item, *val, *maxitem, *maxval, *keyfunc=NULL;
+ PyObject *emptytuple, *defaultval = NULL;
+ static char *kwlist[] = {"key", "default", NULL};
const char *name = op == Py_LT ? "min" : "max";
+ const int positional = PyTuple_Size(args) > 1;
+ int ret;
- if (PyTuple_Size(args) > 1)
+ if (positional)
v = args;
- else if (!PyArg_UnpackTuple(args, (char *)name, 1, 1, &v))
+ else if (!PyArg_UnpackTuple(args, name, 1, 1, &v))
return NULL;
- if (kwds != NULL && PyDict_Check(kwds) && PyDict_Size(kwds)) {
- keyfunc = PyDict_GetItemString(kwds, "key");
- if (PyDict_Size(kwds)!=1 || keyfunc == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%s() got an unexpected keyword argument", name);
- return NULL;
- }
- Py_INCREF(keyfunc);
+ emptytuple = PyTuple_New(0);
+ if (emptytuple == NULL)
+ return NULL;
+ ret = PyArg_ParseTupleAndKeywords(emptytuple, kwds, "|$OO", kwlist,
+ &keyfunc, &defaultval);
+ Py_DECREF(emptytuple);
+ if (!ret)
+ return NULL;
+
+ if (positional && defaultval != NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "Cannot specify a default for %s() with multiple "
+ "positional arguments", name);
+ return NULL;
}
it = PyObject_GetIter(v);
if (it == NULL) {
- Py_XDECREF(keyfunc);
return NULL;
}
@@ -1385,14 +1422,18 @@ min_max(PyObject *args, PyObject *kwds, int op)
if (PyErr_Occurred())
goto Fail_it;
if (maxval == NULL) {
- PyErr_Format(PyExc_ValueError,
- "%s() arg is an empty sequence", name);
assert(maxitem == NULL);
+ if (defaultval != NULL) {
+ Py_INCREF(defaultval);
+ maxitem = defaultval;
+ } else {
+ PyErr_Format(PyExc_ValueError,
+ "%s() arg is an empty sequence", name);
+ }
}
else
Py_DECREF(maxval);
Py_DECREF(it);
- Py_XDECREF(keyfunc);
return maxitem;
Fail_it_item_and_val:
@@ -1403,7 +1444,6 @@ Fail_it:
Py_XDECREF(maxval);
Py_XDECREF(maxitem);
Py_DECREF(it);
- Py_XDECREF(keyfunc);
return NULL;
}
@@ -1414,10 +1454,12 @@ builtin_min(PyObject *self, PyObject *args, PyObject *kwds)
}
PyDoc_STRVAR(min_doc,
-"min(iterable[, key=func]) -> value\n\
-min(a, b, c, ...[, key=func]) -> value\n\
+"min(iterable, *[, default=obj, key=func]) -> value\n\
+min(arg1, arg2, *args, *[, key=func]) -> value\n\
\n\
-With a single iterable argument, return its smallest item.\n\
+With a single iterable argument, return its smallest item. The\n\
+default keyword-only argument specifies an object to return if\n\
+the provided iterable is empty.\n\
With two or more arguments, return the smallest argument.");
@@ -1428,10 +1470,12 @@ builtin_max(PyObject *self, PyObject *args, PyObject *kwds)
}
PyDoc_STRVAR(max_doc,
-"max(iterable[, key=func]) -> value\n\
-max(a, b, c, ...[, key=func]) -> value\n\
+"max(iterable, *[, default=obj, key=func]) -> value\n\
+max(arg1, arg2, *args, *[, key=func]) -> value\n\
\n\
-With a single iterable argument, return its largest item.\n\
+With a single iterable argument, return its biggest item. The\n\
+default keyword-only argument specifies an object to return if\n\
+the provided iterable is empty.\n\
With two or more arguments, return the largest argument.");
@@ -1444,7 +1488,11 @@ builtin_oct(PyObject *self, PyObject *v)
PyDoc_STRVAR(oct_doc,
"oct(number) -> string\n\
\n\
-Return the octal representation of an integer.");
+Return the octal representation of an integer.\n\
+\n\
+ >>> oct(342391)\n\
+ '0o1234567'\n\
+");
static PyObject *
@@ -1530,7 +1578,12 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
kwlist, &sep, &end, &file, &flush))
return NULL;
if (file == NULL || file == Py_None) {
- file = PySys_GetObject("stdout");
+ file = _PySys_GetObjectId(&PyId_stdout);
+ if (file == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
+ return NULL;
+ }
+
/* sys.stdout may be None when FILE* stdout isn't connected */
if (file == Py_None)
Py_RETURN_NONE;
@@ -1584,7 +1637,7 @@ builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
if (do_flush == -1)
return NULL;
else if (do_flush) {
- tmp = PyObject_CallMethod(file, "flush", "");
+ tmp = _PyObject_CallMethodId(file, &PyId_flush, "");
if (tmp == NULL)
return NULL;
else
@@ -1610,9 +1663,9 @@ static PyObject *
builtin_input(PyObject *self, PyObject *args)
{
PyObject *promptarg = NULL;
- PyObject *fin = PySys_GetObject("stdin");
- PyObject *fout = PySys_GetObject("stdout");
- PyObject *ferr = PySys_GetObject("stderr");
+ PyObject *fin = _PySys_GetObjectId(&PyId_stdin);
+ PyObject *fout = _PySys_GetObjectId(&PyId_stdout);
+ PyObject *ferr = _PySys_GetObjectId(&PyId_stderr);
PyObject *tmp;
long fd;
int tty;
@@ -1683,8 +1736,6 @@ 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_GetAttrId(fin, &PyId_encoding);
stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors);
@@ -1810,10 +1861,9 @@ For most object types, eval(repr(object)) == object.");
static PyObject *
builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
{
- static PyObject *round_str = NULL;
PyObject *ndigits = NULL;
static char *kwlist[] = {"number", "ndigits", 0};
- PyObject *number, *round;
+ PyObject *number, *round, *result;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:round",
kwlist, &number, &ndigits))
@@ -1824,24 +1874,21 @@ builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
return NULL;
}
- if (round_str == NULL) {
- round_str = PyUnicode_InternFromString("__round__");
- if (round_str == NULL)
- return NULL;
- }
-
- round = _PyType_Lookup(Py_TYPE(number), round_str);
+ round = _PyObject_LookupSpecial(number, &PyId___round__);
if (round == NULL) {
- PyErr_Format(PyExc_TypeError,
- "type %.100s doesn't define __round__ method",
- Py_TYPE(number)->tp_name);
+ if (!PyErr_Occurred())
+ PyErr_Format(PyExc_TypeError,
+ "type %.100s doesn't define __round__ method",
+ Py_TYPE(number)->tp_name);
return NULL;
}
if (ndigits == NULL)
- return PyObject_CallFunction(round, "O", number);
+ result = PyObject_CallFunctionObjArgs(round, NULL);
else
- return PyObject_CallFunction(round, "OO", number, ndigits);
+ result = PyObject_CallFunctionObjArgs(round, ndigits, NULL);
+ Py_DECREF(round);
+ return result;
}
PyDoc_STRVAR(round_doc,
@@ -1859,7 +1906,6 @@ 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",
@@ -1907,16 +1953,11 @@ builtin_vars(PyObject *self, PyObject *args)
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);
+ if (d == NULL)
+ return NULL;
+ Py_INCREF(d);
}
else {
- _Py_IDENTIFIER(__dict__);
d = _PyObject_GetAttrId(v, &PyId___dict__);
if (d == NULL) {
PyErr_SetString(PyExc_TypeError,
@@ -2413,6 +2454,12 @@ PyObject *
_PyBuiltin_Init(void)
{
PyObject *mod, *dict, *debug;
+
+ if (PyType_Ready(&PyFilter_Type) < 0 ||
+ PyType_Ready(&PyMap_Type) < 0 ||
+ PyType_Ready(&PyZip_Type) < 0)
+ return NULL;
+
mod = PyModule_Create(&builtinsmodule);
if (mod == NULL)
return NULL;