diff options
Diffstat (limited to 'Modules/_io/_iomodule.c')
-rw-r--r-- | Modules/_io/_iomodule.c | 189 |
1 files changed, 108 insertions, 81 deletions
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index d73dff2746f..cec06710c4e 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -176,6 +176,9 @@ PyObject *PyExc_BlockingIOError = (PyObject *)&_PyExc_BlockingIOError; * The main open() function */ PyDoc_STRVAR(open_doc, +"open(file, mode='r', buffering=-1, encoding=None,\n" +" errors=None, newline=None, closefd=True) -> file object\n" +"\n" "Open file and return a stream. Raise IOError upon failure.\n" "\n" "file is either a text or byte string giving the name (and the path\n" @@ -261,9 +264,9 @@ PyDoc_STRVAR(open_doc, "\n" "* On output, if newline is None, any '\\n' characters written are\n" " translated to the system default line separator, os.linesep. If\n" -" newline is '', no translation takes place. If newline is any of the\n" -" other legal values, any '\\n' characters written are translated to\n" -" the given string.\n" +" newline is '' or '\\n', no translation takes place. If newline is any\n" +" of the other legal values, any '\\n' characters written are translated\n" +" to the given string.\n" "\n" "If closefd is False, the underlying file descriptor will be kept open\n" "when the file is closed. This does not work when a file name is given\n" @@ -314,12 +317,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) if (!PyUnicode_Check(file) && !PyBytes_Check(file) && !PyNumber_Check(file)) { - PyObject *repr = PyObject_Repr(file); - if (repr != NULL) { - PyErr_Format(PyExc_TypeError, "invalid file: %s", - PyString_AS_STRING(repr)); - Py_DECREF(repr); - } + PyErr_Format(PyExc_TypeError, "invalid file: %R", file); return NULL; } @@ -448,7 +446,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) if (res == NULL) goto error; - fileno = PyInt_AsLong(res); + fileno = PyLong_AsLong(res); Py_DECREF(res); if (fileno == -1 && PyErr_Occurred()) goto error; @@ -541,12 +539,6 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err) if (value == NULL) return -1; - if (PyInt_Check(value)) { - /* We assume a long always fits in a Py_off_t... */ - result = (Py_off_t) PyInt_AS_LONG(value); - goto finish; - } - /* We're done if PyLong_AsSsize_t() returns without error. */ result = PyLong_AsOff_t(value); if (result != -1 || !(runerr = PyErr_Occurred())) @@ -606,30 +598,72 @@ _PyIO_ConvertSsize_t(PyObject *obj, void *result) { } +static int +iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { + _PyIO_State *state = IO_MOD_STATE(mod); + if (!state->initialized) + return 0; + Py_VISIT(state->os_module); + if (state->locale_module != NULL) { + Py_VISIT(state->locale_module); + } + Py_VISIT(state->unsupported_operation); + return 0; +} + + +static int +iomodule_clear(PyObject *mod) { + _PyIO_State *state = IO_MOD_STATE(mod); + if (!state->initialized) + return 0; + Py_CLEAR(state->os_module); + if (state->locale_module != NULL) + Py_CLEAR(state->locale_module); + Py_CLEAR(state->unsupported_operation); + return 0; +} + +static void +iomodule_free(PyObject *mod) { + iomodule_clear(mod); +} + + /* * Module definition */ -PyObject *_PyIO_os_module = NULL; -PyObject *_PyIO_locale_module = NULL; -PyObject *_PyIO_unsupported_operation = NULL; - static PyMethodDef module_methods[] = { {"open", (PyCFunction)io_open, METH_VARARGS|METH_KEYWORDS, open_doc}, {NULL, NULL} }; +struct PyModuleDef _PyIO_Module = { + PyModuleDef_HEAD_INIT, + "io", + module_doc, + sizeof(_PyIO_State), + module_methods, + NULL, + iomodule_traverse, + iomodule_clear, + (freefunc)iomodule_free, +}; + PyMODINIT_FUNC -init_io(void) +PyInit__io(void) { - PyObject *m = Py_InitModule4("_io", module_methods, - module_doc, NULL, PYTHON_API_VERSION); + PyObject *m = PyModule_Create(&_PyIO_Module); + _PyIO_State *state = NULL; if (m == NULL) - return; + return NULL; + state = IO_MOD_STATE(m); + state->initialized = 0; /* put os in the module state */ - _PyIO_os_module = PyImport_ImportModule("os"); - if (_PyIO_os_module == NULL) + state->os_module = PyImport_ImportModule("os"); + if (state->os_module == NULL) goto fail; #define ADD_TYPE(type, name) \ @@ -646,14 +680,14 @@ init_io(void) goto fail; /* UnsupportedOperation inherits from ValueError and IOError */ - _PyIO_unsupported_operation = PyObject_CallFunction( + state->unsupported_operation = PyObject_CallFunction( (PyObject *)&PyType_Type, "s(OO){}", "UnsupportedOperation", PyExc_ValueError, PyExc_IOError); - if (_PyIO_unsupported_operation == NULL) + if (state->unsupported_operation == NULL) goto fail; - Py_INCREF(_PyIO_unsupported_operation); + Py_INCREF(state->unsupported_operation); if (PyModule_AddObject(m, "UnsupportedOperation", - _PyIO_unsupported_operation) < 0) + state->unsupported_operation) < 0) goto fail; /* BlockingIOError */ @@ -676,6 +710,8 @@ init_io(void) /* BytesIO */ PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type; ADD_TYPE(&PyBytesIO_Type, "BytesIO"); + if (PyType_Ready(&_PyBytesIOBuffer_Type) < 0) + goto fail; /* StringIO */ PyStringIO_Type.tp_base = &PyTextIOBase_Type; @@ -705,64 +741,55 @@ init_io(void) ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder"); /* Interned strings */ - if (!(_PyIO_str_close = PyString_InternFromString("close"))) - goto fail; - if (!(_PyIO_str_closed = PyString_InternFromString("closed"))) +#define ADD_INTERNED(name) \ + if (!_PyIO_str_ ## name && \ + !(_PyIO_str_ ## name = PyUnicode_InternFromString(# name))) \ goto fail; - if (!(_PyIO_str_decode = PyString_InternFromString("decode"))) - goto fail; - if (!(_PyIO_str_encode = PyString_InternFromString("encode"))) - goto fail; - if (!(_PyIO_str_fileno = PyString_InternFromString("fileno"))) - goto fail; - if (!(_PyIO_str_flush = PyString_InternFromString("flush"))) - goto fail; - if (!(_PyIO_str_getstate = PyString_InternFromString("getstate"))) - goto fail; - if (!(_PyIO_str_isatty = PyString_InternFromString("isatty"))) - goto fail; - if (!(_PyIO_str_newlines = PyString_InternFromString("newlines"))) - goto fail; - if (!(_PyIO_str_nl = PyString_InternFromString("\n"))) - goto fail; - if (!(_PyIO_str_read = PyString_InternFromString("read"))) - goto fail; - if (!(_PyIO_str_read1 = PyString_InternFromString("read1"))) - goto fail; - if (!(_PyIO_str_readable = PyString_InternFromString("readable"))) - goto fail; - if (!(_PyIO_str_readinto = PyString_InternFromString("readinto"))) - goto fail; - if (!(_PyIO_str_readline = PyString_InternFromString("readline"))) - goto fail; - if (!(_PyIO_str_reset = PyString_InternFromString("reset"))) - goto fail; - if (!(_PyIO_str_seek = PyString_InternFromString("seek"))) - goto fail; - if (!(_PyIO_str_seekable = PyString_InternFromString("seekable"))) - goto fail; - if (!(_PyIO_str_setstate = PyString_InternFromString("setstate"))) - goto fail; - if (!(_PyIO_str_tell = PyString_InternFromString("tell"))) - goto fail; - if (!(_PyIO_str_truncate = PyString_InternFromString("truncate"))) - goto fail; - if (!(_PyIO_str_write = PyString_InternFromString("write"))) - goto fail; - if (!(_PyIO_str_writable = PyString_InternFromString("writable"))) + + ADD_INTERNED(close) + ADD_INTERNED(closed) + ADD_INTERNED(decode) + ADD_INTERNED(encode) + ADD_INTERNED(fileno) + ADD_INTERNED(flush) + ADD_INTERNED(getstate) + ADD_INTERNED(isatty) + ADD_INTERNED(newlines) + ADD_INTERNED(read) + ADD_INTERNED(read1) + ADD_INTERNED(readable) + ADD_INTERNED(readinto) + ADD_INTERNED(readline) + ADD_INTERNED(reset) + ADD_INTERNED(seek) + ADD_INTERNED(seekable) + ADD_INTERNED(setstate) + ADD_INTERNED(tell) + ADD_INTERNED(truncate) + ADD_INTERNED(write) + ADD_INTERNED(writable) + + if (!_PyIO_str_nl && + !(_PyIO_str_nl = PyUnicode_InternFromString("\n"))) goto fail; - - if (!(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) + + if (!_PyIO_empty_str && + !(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) goto fail; - if (!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) + if (!_PyIO_empty_bytes && + !(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) goto fail; - if (!(_PyIO_zero = PyLong_FromLong(0L))) + if (!_PyIO_zero && + !(_PyIO_zero = PyLong_FromLong(0L))) goto fail; - return; + state->initialized = 1; + + return m; fail: - Py_CLEAR(_PyIO_os_module); - Py_CLEAR(_PyIO_unsupported_operation); + Py_XDECREF(state->os_module); + Py_XDECREF(state->unsupported_operation); Py_DECREF(m); + return NULL; } |