diff options
author | Ethan Furman <ethan@stoneleaf.us> | 2016-06-04 21:38:43 (GMT) |
---|---|---|
committer | Ethan Furman <ethan@stoneleaf.us> | 2016-06-04 21:38:43 (GMT) |
commit | d62548afede899e71e59a2a0b31f19fdf031c560 (patch) | |
tree | 11dc76fe4b5c89d93c63e8bdf4b9ec535fde6451 /Modules/_io | |
parent | 228c636908bda8a6b20b0f6930655fbaedc4ebad (diff) | |
download | cpython-d62548afede899e71e59a2a0b31f19fdf031c560.zip cpython-d62548afede899e71e59a2a0b31f19fdf031c560.tar.gz cpython-d62548afede899e71e59a2a0b31f19fdf031c560.tar.bz2 |
issue27186: add open/io.open; patch by Jelle Zijlstra
Diffstat (limited to 'Modules/_io')
-rw-r--r-- | Modules/_io/_iomodule.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index d8aa1df..85b1813 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -238,21 +238,33 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, int text = 0, binary = 0, universal = 0; char rawmode[6], *m; - int line_buffering; + int line_buffering, is_number; long isatty; - PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL; + PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL; _Py_IDENTIFIER(_blksize); _Py_IDENTIFIER(isatty); _Py_IDENTIFIER(mode); _Py_IDENTIFIER(close); - if (!PyUnicode_Check(file) && - !PyBytes_Check(file) && - !PyNumber_Check(file)) { + is_number = PyNumber_Check(file); + + if (is_number) { + path_or_fd = file; + Py_INCREF(path_or_fd); + } else { + path_or_fd = PyOS_FSPath(file); + if (path_or_fd == NULL) { + return NULL; + } + } + + if (!is_number && + !PyUnicode_Check(path_or_fd) && + !PyBytes_Check(path_or_fd)) { PyErr_Format(PyExc_TypeError, "invalid file: %R", file); - return NULL; + goto error; } /* Decode mode */ @@ -293,7 +305,7 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, if (strchr(mode+i+1, c)) { invalid_mode: PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode); - return NULL; + goto error; } } @@ -311,51 +323,54 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, if (creating || writing || appending || updating) { PyErr_SetString(PyExc_ValueError, "mode U cannot be combined with x', 'w', 'a', or '+'"); - return NULL; + goto error; } if (PyErr_WarnEx(PyExc_DeprecationWarning, "'U' mode is deprecated", 1) < 0) - return NULL; + goto error; reading = 1; } if (text && binary) { PyErr_SetString(PyExc_ValueError, "can't have text and binary mode at once"); - return NULL; + goto error; } if (creating + reading + writing + appending > 1) { PyErr_SetString(PyExc_ValueError, "must have exactly one of create/read/write/append mode"); - return NULL; + goto error; } if (binary && encoding != NULL) { PyErr_SetString(PyExc_ValueError, "binary mode doesn't take an encoding argument"); - return NULL; + goto error; } if (binary && errors != NULL) { PyErr_SetString(PyExc_ValueError, "binary mode doesn't take an errors argument"); - return NULL; + goto error; } if (binary && newline != NULL) { PyErr_SetString(PyExc_ValueError, "binary mode doesn't take a newline argument"); - return NULL; + goto error; } /* Create the Raw file stream */ raw = PyObject_CallFunction((PyObject *)&PyFileIO_Type, - "OsiO", file, rawmode, closefd, opener); + "OsiO", path_or_fd, rawmode, closefd, opener); if (raw == NULL) - return NULL; + goto error; result = raw; + Py_DECREF(path_or_fd); + path_or_fd = NULL; + modeobj = PyUnicode_FromString(mode); if (modeobj == NULL) goto error; @@ -461,6 +476,7 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, Py_XDECREF(close_result); Py_DECREF(result); } + Py_XDECREF(path_or_fd); Py_XDECREF(modeobj); return NULL; } |