aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules/_io/_iomodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_io/_iomodule.c')
-rw-r--r--Modules/_io/_iomodule.c189
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;
}