summaryrefslogtreecommitdiff
path: root/Python/bltinmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/bltinmodule.c')
-rw-r--r--Python/bltinmodule.c166
1 files changed, 98 insertions, 68 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 33d2cc2dc8..ef5a34cae9 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};
+ static char *kwlist[] = {"", "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,10 @@ 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);
+ assert(PyTuple_GET_SIZE(args) >= 1);
+ 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 +2740,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