Index: Lib/io.py =================================================================== --- Lib/io.py (révision 66888) +++ Lib/io.py (copie de travail) @@ -79,7 +79,7 @@ self.characters_written = characters_written -def open(file, mode="r", buffering=None, encoding=None, errors=None, +def open(file, mode="r", *, buffering=None, encoding=None, errors=None, newline=None, closefd=True): r"""Open file and return a stream. Raise IOError upon failure. Index: Parser/tokenizer.c =================================================================== --- Parser/tokenizer.c (révision 66888) +++ Parser/tokenizer.c (copie de travail) @@ -442,18 +442,12 @@ static int fp_setreadl(struct tok_state *tok, const char* enc) { - PyObject *readline = NULL, *stream = NULL, *io = NULL; - - io = PyImport_ImportModuleNoBlock("io"); - if (io == NULL) - goto cleanup; + PyObject *readline = NULL, *stream = NULL; if (tok->filename) - stream = PyObject_CallMethod(io, "open", "ssis", - tok->filename, "r", -1, enc); + stream = PyFile_FromFilename(tok->filename, "r", -1, enc, NULL, NULL, 1); else - stream = PyObject_CallMethod(io, "open", "isis", - fileno(tok->fp), "r", -1, enc); + stream = PyFile_FromFd(fileno(tok->fp), NULL, "r", -1, enc, NULL, NULL, 1); if (stream == NULL) goto cleanup; @@ -471,7 +465,6 @@ cleanup: Py_XDECREF(stream); - Py_XDECREF(io); return readline != NULL; } Index: Include/fileobject.h =================================================================== --- Include/fileobject.h (révision 66888) +++ Include/fileobject.h (copie de travail) @@ -10,6 +10,7 @@ PyAPI_FUNC(PyObject *) PyFile_FromFd(int, char *, char *, int, char *, char *, char *, int); +PyAPI_FUNC(PyObject *) PyFile_FromFilename(char *, char *, int, char *, char *, char *, int); PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); Index: Objects/fileobject.c =================================================================== --- Objects/fileobject.c (révision 66888) +++ Objects/fileobject.c (copie de travail) @@ -25,18 +25,103 @@ /* External C interface */ -PyObject * -PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, +static PyObject* +PyFile_FromObject(PyObject* file, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd) { - PyObject *io, *stream, *nameobj = NULL; + PyObject *io, *stream, *nameobj = NULL, *modeobj; + PyObject *func, *args, *kw, *v; + int err; io = PyImport_ImportModule("io"); if (io == NULL) return NULL; - stream = PyObject_CallMethod(io, "open", "isisssi", fd, mode, - buffering, encoding, errors, - newline, closefd); + + func = PyObject_GetAttrString(io, "open"); + if (func == NULL) { + Py_DECREF(io); + PyErr_SetString(PyExc_AttributeError, "open"); + return 0; + } + + if (!PyCallable_Check(func)) { + Py_DECREF(io); + PyErr_Format(PyExc_TypeError, + "attribute of type '%.200s' is not callable", + func->ob_type->tp_name); + Py_DECREF(func); + return NULL; + } + + modeobj = PyUnicode_FromString(mode); + if (modeobj) + args = PyTuple_Pack(2, file, modeobj); + else + args = NULL; + if (args) + kw = PyDict_New(); + else + kw = NULL; + err = (kw == NULL); + + if (!err) { + v = PyLong_FromLong(buffering); + if (v) { + err = PyDict_SetItemString(kw, "buffering", v); + Py_DECREF(v); + } else + err = 1; + } + + if (!err && encoding) { + v = PyUnicode_FromString(encoding); + if (v) { + err = PyDict_SetItemString(kw, "encoding", v); + Py_DECREF(v); + } else + err = 1; + } + + if (!err && errors) { + v = PyUnicode_FromString(errors); + if (v) { + err = PyDict_SetItemString(kw, "errors", v); + Py_DECREF(v); + } else + err = 1; + } + + if (!err && newline) { + v = PyUnicode_FromString(newline); + if (v) { + err = PyDict_SetItemString(kw, "newline", v); + Py_DECREF(v); + } else + err = 1; + } + + if (!err) { + v = PyBool_FromLong(closefd); + if (v) { + err = PyDict_SetItemString(kw, "closefd", v); + Py_DECREF(v); + } else + err = 1; + } + + if (err) { + Py_XDECREF(kw); + kw = NULL; + } + + if (kw) { + stream = PyObject_Call(func, args, kw); + Py_DECREF(args); + Py_DECREF(kw); + } else { + stream = NULL; + } + Py_DECREF(func); Py_DECREF(io); if (stream == NULL) return NULL; @@ -54,6 +139,32 @@ } PyObject * +PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, + char *errors, char *newline, int closefd) +{ + PyObject *file, *stream; + file = PyLong_FromLong(fd); + if (!file) + return NULL; + stream = PyFile_FromObject(file, name, mode, buffering, encoding, errors, newline, closefd); + Py_DECREF(file); + return stream; +} + +PyObject * +PyFile_FromFilename(char *name, char *mode, int buffering, char *encoding, + char *errors, char *newline, int closefd) +{ + PyObject *file, *stream; + file = PyUnicode_FromString(name); + if (!file) + return NULL; + stream = PyFile_FromObject(file, name, mode, buffering, encoding, errors, newline, closefd); + Py_DECREF(file); + return stream; +} + +PyObject * PyFile_GetLine(PyObject *f, int n) { PyObject *result;