14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    An implementation of the new I/O lib as defined by PEP 3116 - "New I/O"
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Classes defined here: UnsupportedOperation, BlockingIOError.
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Functions defined here: open().
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Mostly written by Amaury Forgeot d'Arc
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define PY_SSIZE_T_CLEAN
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "Python.h"
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "structmember.h"
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "_iomodule.h"
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_SYS_TYPES_H
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <sys/types.h>
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* HAVE_SYS_TYPES_H */
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_SYS_STAT_H
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <sys/stat.h>
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* HAVE_SYS_STAT_H */
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Various interned strings */
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_close;
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_closed;
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_decode;
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_encode;
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_fileno;
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_flush;
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_getstate;
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_isatty;
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_newlines;
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_nl;
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_read;
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_read1;
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_readable;
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_readinto;
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_readline;
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_reset;
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_seek;
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_seekable;
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_setstate;
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_tell;
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_truncate;
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_writable;
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_str_write;
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_empty_str;
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_empty_bytes;
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_zero;
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(module_doc,
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"The io module provides the Python interfaces to stream handling. The\n"
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"builtin open function is defined in this module.\n"
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"At the top of the I/O hierarchy is the abstract base class IOBase. It\n"
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"defines the basic interface to a stream. Note, however, that there is no\n"
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"seperation between reading and writing to streams; implementations are\n"
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"allowed to throw an IOError if they do not support a given operation.\n"
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"Extending IOBase is RawIOBase which deals simply with the reading and\n"
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide\n"
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"an interface to OS files.\n"
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n"
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer\n"
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"streams that are readable, writable, and both respectively.\n"
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"BufferedRandom provides a buffered interface to random access\n"
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"streams. BytesIO is a simple stream of in-memory bytes.\n"
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n"
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"of streams into text. TextIOWrapper, which extends it, is a buffered text\n"
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n"
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"is a in-memory stream for text.\n"
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"Argument names are not part of the specification, and only the arguments\n"
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"of open() are intended to be used as keyword arguments.\n"
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"data:\n"
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"DEFAULT_BUFFER_SIZE\n"
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"   An int containing the default buffer size used by the module's buffered\n"
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"   I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n"
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"   possible.\n"
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    );
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * BlockingIOError extends IOError
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmblockingioerror_init(PyBlockingIOErrorObject *self, PyObject *args,
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     PyObject *kwds)
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *myerrno = NULL, *strerror = NULL;
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *baseargs = NULL;
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t written = 0;
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(PyTuple_Check(args));
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    self->written = 0;
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "OO|n:BlockingIOError",
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          &myerrno, &strerror, &written))
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    baseargs = PyTuple_Pack(2, myerrno, strerror);
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (baseargs == NULL)
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* This will take care of initializing of myerrno and strerror members */
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (((PyTypeObject *)PyExc_IOError)->tp_init(
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (PyObject *)self, baseargs, kwds) == -1) {
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(baseargs);
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(baseargs);
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    self->written = written;
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMemberDef blockingioerror_members[] = {
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"characters_written", T_PYSSIZET, offsetof(PyBlockingIOErrorObject, written), 0},
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {NULL}  /* Sentinel */
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyTypeObject _PyExc_BlockingIOError = {
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyVarObject_HEAD_INIT(NULL, 0)
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "BlockingIOError", /*tp_name*/
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    sizeof(PyBlockingIOErrorObject), /*tp_basicsize*/
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_itemsize*/
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_dealloc*/
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_print*/
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_getattr*/
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_setattr*/
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_compare */
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_repr*/
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_as_number*/
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_as_sequence*/
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_as_mapping*/
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_hash */
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_call*/
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_str*/
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_getattro*/
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_setattro*/
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /*tp_as_buffer*/
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyDoc_STR("Exception raised when I/O would block "
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm              "on a non-blocking I/O stream"), /* tp_doc */
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_traverse */
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_clear */
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_richcompare */
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_weaklistoffset */
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_iter */
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_iternext */
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_methods */
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    blockingioerror_members,    /* tp_members */
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_getset */
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_base */
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_dict */
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_descr_get */
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_descr_set */
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_dictoffset */
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    (initproc)blockingioerror_init, /* tp_init */
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_alloc */
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                          /* tp_new */
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *PyExc_BlockingIOError = (PyObject *)&_PyExc_BlockingIOError;
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * The main open() function
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(open_doc,
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"Open file and return a stream.  Raise IOError upon failure.\n"
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"file is either a text or byte string giving the name (and the path\n"
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"if the file isn't in the current working directory) of the file to\n"
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"be opened or an integer file descriptor of the file to be\n"
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"wrapped. (If a file descriptor is given, it is closed when the\n"
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"returned I/O object is closed, unless closefd is set to False.)\n"
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"mode is an optional string that specifies the mode in which the file\n"
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"is opened. It defaults to 'r' which means open for reading in text\n"
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"mode.  Other common values are 'w' for writing (truncating the file if\n"
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"it already exists), and 'a' for appending (which on some Unix systems,\n"
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"means that all writes append to the end of the file regardless of the\n"
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"current seek position). In text mode, if encoding is not specified the\n"
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"encoding used is platform dependent. (For reading and writing raw\n"
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"bytes use binary mode and leave encoding unspecified.) The available\n"
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"modes are:\n"
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"========= ===============================================================\n"
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"Character Meaning\n"
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"--------- ---------------------------------------------------------------\n"
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'r'       open for reading (default)\n"
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'w'       open for writing, truncating the file first\n"
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'a'       open for writing, appending to the end of the file if it exists\n"
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'b'       binary mode\n"
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'t'       text mode (default)\n"
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'+'       open a disk file for updating (reading and writing)\n"
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'U'       universal newline mode (for backwards compatibility; unneeded\n"
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"          for new code)\n"
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"========= ===============================================================\n"
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"The default mode is 'rt' (open for reading text). For binary random\n"
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"access, the mode 'w+b' opens and truncates the file to 0 bytes, while\n"
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'r+b' opens the file without truncation.\n"
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"Python distinguishes between files opened in binary and text modes,\n"
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"even when the underlying operating system doesn't. Files opened in\n"
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"binary mode (appending 'b' to the mode argument) return contents as\n"
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"bytes objects without any decoding. In text mode (the default, or when\n"
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'t' is appended to the mode argument), the contents of the file are\n"
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"returned as strings, the bytes having been first decoded using a\n"
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"platform-dependent encoding or using the specified encoding if given.\n"
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"buffering is an optional integer used to set the buffering policy.\n"
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n"
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"line buffering (only usable in text mode), and an integer > 1 to indicate\n"
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"the size of a fixed-size chunk buffer.  When no buffering argument is\n"
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"given, the default buffering policy works as follows:\n"
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"* Binary files are buffered in fixed-size chunks; the size of the buffer\n"
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  is chosen using a heuristic trying to determine the underlying device's\n"
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  \"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`.\n"
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  On many systems, the buffer will typically be 4096 or 8192 bytes long.\n"
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"* \"Interactive\" text files (files for which isatty() returns True)\n"
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  use line buffering.  Other text files use the policy described above\n"
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  for binary files.\n"
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"encoding is the name of the encoding used to decode or encode the\n"
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"file. This should only be used in text mode. The default encoding is\n"
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"platform dependent, but any encoding supported by Python can be\n"
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"passed.  See the codecs module for the list of supported encodings.\n"
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"errors is an optional string that specifies how encoding errors are to\n"
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"be handled---this argument should not be used in binary mode. Pass\n"
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'strict' to raise a ValueError exception if there is an encoding error\n"
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"(the default of None has the same effect), or pass 'ignore' to ignore\n"
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"errors. (Note that ignoring encoding errors can lead to data loss.)\n"
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"See the documentation for codecs.register for a list of the permitted\n"
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"encoding error strings.\n"
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"newline controls how universal newlines works (it only applies to text\n"
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"mode). It can be None, '', '\\n', '\\r', and '\\r\\n'.  It works as\n"
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"follows:\n"
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"* On input, if newline is None, universal newlines mode is\n"
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  enabled. Lines in the input can end in '\\n', '\\r', or '\\r\\n', and\n"
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  these are translated into '\\n' before being returned to the\n"
2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  caller. If it is '', universal newline mode is enabled, but line\n"
2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  endings are returned to the caller untranslated. If it has any of\n"
2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  the other legal values, input lines are only terminated by the given\n"
2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  string, and the line ending is returned to the caller untranslated.\n"
2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"* On output, if newline is None, any '\\n' characters written are\n"
2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  translated to the system default line separator, os.linesep. If\n"
2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  newline is '', no translation takes place. If newline is any of the\n"
2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  other legal values, any '\\n' characters written are translated to\n"
2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"  the given string.\n"
2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"If closefd is False, the underlying file descriptor will be kept open\n"
2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"when the file is closed. This does not work when a file name is given\n"
2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"and must be True in that case.\n"
2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"open() returns a file object whose type depends on the mode, and\n"
2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"through which the standard file operations such as reading and writing\n"
2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"are performed. When open() is used to open a file in a text mode ('w',\n"
2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open\n"
2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"a file in a binary mode, the returned class varies: in read binary\n"
2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"mode, it returns a BufferedReader; in write binary and append binary\n"
2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"modes, it returns a BufferedWriter, and in read/write mode, it returns\n"
2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"a BufferedRandom.\n"
2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"\n"
2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"It is also possible to use a string or bytearray as a file for both\n"
2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"reading and writing. For strings StringIO can be used like a file\n"
2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"opened in a text mode, and for bytes a BytesIO can be used like a file\n"
2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"opened in a binary mode.\n"
2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    );
2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmio_open(PyObject *self, PyObject *args, PyObject *kwds)
2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *kwlist[] = {"file", "mode", "buffering",
2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      "encoding", "errors", "newline",
2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      "closefd", NULL};
2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *file;
2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *mode = "r";
2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int buffering = -1, closefd = 1;
2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *encoding = NULL, *errors = NULL, *newline = NULL;
2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    unsigned i;
2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int reading = 0, writing = 0, appending = 0, updating = 0;
3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int text = 0, binary = 0, universal = 0;
3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char rawmode[5], *m;
3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int line_buffering, isatty;
3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL;
3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzzi:open", kwlist,
3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                     &file, &mode, &buffering,
3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                     &encoding, &errors, &newline,
3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                     &closefd)) {
3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyUnicode_Check(file) &&
3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm	!PyBytes_Check(file) &&
3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm	!PyNumber_Check(file)) {
3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *repr = PyObject_Repr(file);
3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (repr != NULL) {
3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_TypeError, "invalid file: %s",
3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         PyString_AS_STRING(repr));
3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(repr);
3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Decode mode */
3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; i < strlen(mode); i++) {
3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char c = mode[i];
3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        switch (c) {
3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case 'r':
3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            reading = 1;
3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case 'w':
3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            writing = 1;
3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case 'a':
3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            appending = 1;
3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case '+':
3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            updating = 1;
3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case 't':
3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            text = 1;
3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case 'b':
3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            binary = 1;
3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        case 'U':
3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            universal = 1;
3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            reading = 1;
3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        default:
3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto invalid_mode;
3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* c must not be duplicated */
3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (strchr(mode+i+1, c)) {
3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm          invalid_mode:
3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode);
3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = rawmode;
3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (reading)   *(m++) = 'r';
3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (writing)   *(m++) = 'w';
3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (appending) *(m++) = 'a';
3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (updating)  *(m++) = '+';
3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *m = '\0';
3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Parameters validation */
3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (universal) {
3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (writing || appending) {
3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ValueError,
3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "can't use U and writing mode at once");
3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        reading = 1;
3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (text && binary) {
3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError,
3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "can't have text and binary mode at once");
3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (reading + writing + appending > 1) {
3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError,
3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "must have exactly one of read/write/append mode");
3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (binary && encoding != NULL) {
3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError,
3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "binary mode doesn't take an encoding argument");
3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (binary && errors != NULL) {
4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError,
4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "binary mode doesn't take an errors argument");
4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (binary && newline != NULL) {
4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError,
4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "binary mode doesn't take a newline argument");
4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Create the Raw file stream */
4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    raw = PyObject_CallFunction((PyObject *)&PyFileIO_Type,
4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm				"Osi", file, rawmode, closefd);
4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (raw == NULL)
4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    modeobj = PyUnicode_FromString(mode);
4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (modeobj == NULL)
4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* buffering */
4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {
4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *res = PyObject_CallMethod(raw, "isatty", NULL);
4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (res == NULL)
4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto error;
4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        isatty = PyLong_AsLong(res);
4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(res);
4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (isatty == -1 && PyErr_Occurred())
4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto error;
4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (buffering == 1 || (buffering < 0 && isatty)) {
4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        buffering = -1;
4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        line_buffering = 1;
4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else
4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        line_buffering = 0;
4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (buffering < 0) {
4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        buffering = DEFAULT_BUFFER_SIZE;
4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            struct stat st;
4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            long fileno;
4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyObject *res = PyObject_CallMethod(raw, "fileno", NULL);
4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (res == NULL)
4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                goto error;
4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            fileno = PyInt_AsLong(res);
4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(res);
4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (fileno == -1 && PyErr_Occurred())
4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                goto error;
4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (fstat(fileno, &st) >= 0 && st.st_blksize > 1)
4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                buffering = st.st_blksize;
4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (buffering < 0) {
4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError,
4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "invalid buffering size");
4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* if not buffering, returns the raw file object */
4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (buffering == 0) {
4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!binary) {
4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ValueError,
4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "can't have unbuffered text I/O");
4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto error;
4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(modeobj);
4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return raw;
4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* wraps into a buffered file */
4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {
4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *Buffered_class;
4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (updating)
4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Buffered_class = (PyObject *)&PyBufferedRandom_Type;
4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (writing || appending)
4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Buffered_class = (PyObject *)&PyBufferedWriter_Type;
4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else if (reading)
4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Buffered_class = (PyObject *)&PyBufferedReader_Type;
4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else {
4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_ValueError,
4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "unknown mode: '%s'", mode);
4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto error;
4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering);
4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_CLEAR(raw);
4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (buffer == NULL)
4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* if binary, returns the buffered file */
5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (binary) {
5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(modeobj);
5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return buffer;
5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* wraps into a TextIOWrapper */
5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type,
5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm				    "Osssi",
5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm				    buffer,
5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm				    encoding, errors, newline,
5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm				    line_buffering);
5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_CLEAR(buffer);
5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (wrapper == NULL)
5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyObject_SetAttrString(wrapper, "mode", modeobj) < 0)
5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(modeobj);
5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return wrapper;
5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  error:
5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(raw);
5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(modeobj);
5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(buffer);
5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(wrapper);
5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return NULL;
5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*
5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Private helpers for the io module.
5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPy_off_t
5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyNumber_AsOff_t(PyObject *item, PyObject *err)
5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_off_t result;
5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *runerr;
5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *value = PyNumber_Index(item);
5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (value == NULL)
5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyInt_Check(value)) {
5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* We assume a long always fits in a Py_off_t... */
5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = (Py_off_t) PyInt_AS_LONG(value);
5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto finish;
5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* We're done if PyLong_AsSsize_t() returns without error. */
5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    result = PyLong_AsOff_t(value);
5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (result != -1 || !(runerr = PyErr_Occurred()))
5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto finish;
5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Error handling code -- only manage OverflowError differently */
5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError))
5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto finish;
5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyErr_Clear();
5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* If no error-handling desired then the default clipping
5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       is sufficient.
5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     */
5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!err) {
5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        assert(PyLong_Check(value));
5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Whether or not it is less than or equal to
5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           zero is determined by the sign of ob_size
5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        */
5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (_PyLong_Sign(value) < 0)
5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            result = PY_OFF_T_MIN;
5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            result = PY_OFF_T_MAX;
5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Otherwise replace the error with caller's error object. */
5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(err,
5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "cannot fit '%.200s' into an offset-sized integer",
5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     item->ob_type->tp_name);
5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finish:
5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(value);
5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return result;
5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Basically the "n" format code with the ability to turn None into -1. */
5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyIO_ConvertSsize_t(PyObject *obj, void *result) {
5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t limit;
5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (obj == Py_None) {
5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        limit = -1;
5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else if (PyNumber_Check(obj)) {
5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError);
5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (limit == -1 && PyErr_Occurred())
5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 0;
5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
5994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_TypeError,
6004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "integer argument expected, got '%.200s'",
6014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     Py_TYPE(obj)->tp_name);
6024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
6034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *((Py_ssize_t *)result) = limit;
6054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 1;
6064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
6074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*
6104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Module definition
6114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
6124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_os_module = NULL;
6144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_locale_module = NULL;
6154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *_PyIO_unsupported_operation = NULL;
6164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMethodDef module_methods[] = {
6184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"open", (PyCFunction)io_open, METH_VARARGS|METH_KEYWORDS, open_doc},
6194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {NULL, NULL}
6204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
6214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyMODINIT_FUNC
6234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylminit_io(void)
6244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
6254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m = Py_InitModule4("_io", module_methods,
6264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 module_doc, NULL, PYTHON_API_VERSION);
6274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (m == NULL)
6284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return;
6294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* put os in the module state */
6314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _PyIO_os_module = PyImport_ImportModule("os");
6324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (_PyIO_os_module == NULL)
6334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
6344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define ADD_TYPE(type, name) \
6364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyType_Ready(type) < 0) \
6374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail; \
6384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(type); \
6394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyModule_AddObject(m, name, (PyObject *)type) < 0) {  \
6404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(type); \
6414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail; \
6424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* DEFAULT_BUFFER_SIZE */
6454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0)
6464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
6474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* UnsupportedOperation inherits from ValueError and IOError */
6494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _PyIO_unsupported_operation = PyObject_CallFunction(
6504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (PyObject *)&PyType_Type, "s(OO){}",
6514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        "UnsupportedOperation", PyExc_ValueError, PyExc_IOError);
6524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (_PyIO_unsupported_operation == NULL)
6534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
6544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(_PyIO_unsupported_operation);
6554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyModule_AddObject(m, "UnsupportedOperation",
6564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           _PyIO_unsupported_operation) < 0)
6574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
6584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* BlockingIOError */
6604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _PyExc_BlockingIOError.tp_base = (PyTypeObject *) PyExc_IOError;
6614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&_PyExc_BlockingIOError, "BlockingIOError");
6624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Concrete base types of the IO ABCs.
6644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       (the ABCs themselves are declared through inheritance in io.py)
6654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    */
6664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyIOBase_Type, "_IOBase");
6674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyRawIOBase_Type, "_RawIOBase");
6684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyBufferedIOBase_Type, "_BufferedIOBase");
6694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyTextIOBase_Type, "_TextIOBase");
6704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Implementation of concrete IO objects. */
6724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* FileIO */
6734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyFileIO_Type.tp_base = &PyRawIOBase_Type;
6744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyFileIO_Type, "FileIO");
6754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* BytesIO */
6774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
6784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyBytesIO_Type, "BytesIO");
6794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* StringIO */
6814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyStringIO_Type.tp_base = &PyTextIOBase_Type;
6824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyStringIO_Type, "StringIO");
6834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* BufferedReader */
6854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
6864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyBufferedReader_Type, "BufferedReader");
6874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* BufferedWriter */
6894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
6904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyBufferedWriter_Type, "BufferedWriter");
6914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* BufferedRWPair */
6934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
6944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyBufferedRWPair_Type, "BufferedRWPair");
6954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* BufferedRandom */
6974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
6984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyBufferedRandom_Type, "BufferedRandom");
6994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* TextIOWrapper */
7014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
7024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyTextIOWrapper_Type, "TextIOWrapper");
7034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* IncrementalNewlineDecoder */
7054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder");
7064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Interned strings */
7084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_close = PyString_InternFromString("close")))
7094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_closed = PyString_InternFromString("closed")))
7114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_decode = PyString_InternFromString("decode")))
7134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_encode = PyString_InternFromString("encode")))
7154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_fileno = PyString_InternFromString("fileno")))
7174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_flush = PyString_InternFromString("flush")))
7194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_getstate = PyString_InternFromString("getstate")))
7214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_isatty = PyString_InternFromString("isatty")))
7234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_newlines = PyString_InternFromString("newlines")))
7254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_nl = PyString_InternFromString("\n")))
7274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_read = PyString_InternFromString("read")))
7294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_read1 = PyString_InternFromString("read1")))
7314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_readable = PyString_InternFromString("readable")))
7334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_readinto = PyString_InternFromString("readinto")))
7354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_readline = PyString_InternFromString("readline")))
7374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_reset = PyString_InternFromString("reset")))
7394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_seek = PyString_InternFromString("seek")))
7414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_seekable = PyString_InternFromString("seekable")))
7434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_setstate = PyString_InternFromString("setstate")))
7454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_tell = PyString_InternFromString("tell")))
7474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_truncate = PyString_InternFromString("truncate")))
7494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_write = PyString_InternFromString("write")))
7514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_str_writable = PyString_InternFromString("writable")))
7534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0)))
7564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0)))
7584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!(_PyIO_zero = PyLong_FromLong(0L)))
7604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto fail;
7614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return;
7634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  fail:
7654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_CLEAR(_PyIO_os_module);
7664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_CLEAR(_PyIO_unsupported_operation);
7674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(m);
7684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
769