17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    An implementation of the new I/O lib as defined by PEP 3116 - "New I/O"
37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Classes defined here: UnsupportedOperation, BlockingIOError.
57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Functions defined here: open().
67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Mostly written by Amaury Forgeot d'Arc
87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel*/
97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PY_SSIZE_T_CLEAN
117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python.h"
127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "structmember.h"
137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "_iomodule.h"
147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef HAVE_SYS_TYPES_H
167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include <sys/types.h>
177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif /* HAVE_SYS_TYPES_H */
187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef HAVE_SYS_STAT_H
207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include <sys/stat.h>
217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif /* HAVE_SYS_STAT_H */
227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Various interned strings */
257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_close;
277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_closed;
287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_decode;
297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_encode;
307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_fileno;
317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_flush;
327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_getstate;
337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_isatty;
347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_newlines;
357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_nl;
367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_read;
377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_read1;
387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_readable;
397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_readinto;
407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_readline;
417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_reset;
427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_seek;
437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_seekable;
447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_setstate;
457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_tell;
467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_truncate;
477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_writable;
487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_str_write;
497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_empty_str;
517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_empty_bytes;
527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_zero;
537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(module_doc,
567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"The io module provides the Python interfaces to stream handling. The\n"
577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"builtin open function is defined in this module.\n"
587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"At the top of the I/O hierarchy is the abstract base class IOBase. It\n"
607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"defines the basic interface to a stream. Note, however, that there is no\n"
617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"separation between reading and writing to streams; implementations are\n"
627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"allowed to raise an IOError if they do not support a given operation.\n"
637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Extending IOBase is RawIOBase which deals simply with the reading and\n"
657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide\n"
667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"an interface to OS files.\n"
677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n"
697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer\n"
707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"streams that are readable, writable, and both respectively.\n"
717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"BufferedRandom provides a buffered interface to random access\n"
727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"streams. BytesIO is a simple stream of in-memory bytes.\n"
737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n"
757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"of streams into text. TextIOWrapper, which extends it, is a buffered text\n"
767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n"
777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"is a in-memory stream for text.\n"
787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Argument names are not part of the specification, and only the arguments\n"
807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"of open() are intended to be used as keyword arguments.\n"
817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"data:\n"
837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"DEFAULT_BUFFER_SIZE\n"
857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"   An int containing the default buffer size used by the module's buffered\n"
877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"   I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n"
887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"   possible.\n"
897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    );
907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * BlockingIOError extends IOError
947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielblockingioerror_init(PyBlockingIOErrorObject *self, PyObject *args,
987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     PyObject *kwds)
997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *myerrno = NULL, *strerror = NULL;
1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *baseargs = NULL;
1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t written = 0;
1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    assert(PyTuple_Check(args));
1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->written = 0;
1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "OO|n:BlockingIOError",
1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                          &myerrno, &strerror, &written))
1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    baseargs = PyTuple_Pack(2, myerrno, strerror);
1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (baseargs == NULL)
1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* This will take care of initializing of myerrno and strerror members */
1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (((PyTypeObject *)PyExc_IOError)->tp_init(
1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                (PyObject *)self, baseargs, kwds) == -1) {
1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(baseargs);
1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(baseargs);
1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->written = written;
1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMemberDef blockingioerror_members[] = {
1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"characters_written", T_PYSSIZET, offsetof(PyBlockingIOErrorObject, written), 0},
1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL}  /* Sentinel */
1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyTypeObject _PyExc_BlockingIOError = {
1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyVarObject_HEAD_INIT(NULL, 0)
1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    "BlockingIOError", /*tp_name*/
1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sizeof(PyBlockingIOErrorObject), /*tp_basicsize*/
1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_itemsize*/
1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_dealloc*/
1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_print*/
1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_getattr*/
1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_setattr*/
1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_compare */
1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_repr*/
1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_as_number*/
1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_as_sequence*/
1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_as_mapping*/
1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_hash */
1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_call*/
1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_str*/
1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_getattro*/
1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_setattro*/
1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /*tp_as_buffer*/
1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyDoc_STR("Exception raised when I/O would block "
1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              "on a non-blocking I/O stream"), /* tp_doc */
1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_traverse */
1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_clear */
1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_richcompare */
1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_weaklistoffset */
1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_iter */
1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_iternext */
1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_methods */
1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    blockingioerror_members,    /* tp_members */
1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_getset */
1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_base */
1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_dict */
1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_descr_get */
1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_descr_set */
1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_dictoffset */
1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    (initproc)blockingioerror_init, /* tp_init */
1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_alloc */
1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    0,                          /* tp_new */
1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *PyExc_BlockingIOError = (PyObject *)&_PyExc_BlockingIOError;
1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * The main open() function
1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(open_doc,
1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Open file and return a stream.  Raise IOError upon failure.\n"
1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"file is either a text or byte string giving the name (and the path\n"
1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"if the file isn't in the current working directory) of the file to\n"
1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"be opened or an integer file descriptor of the file to be\n"
1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"wrapped. (If a file descriptor is given, it is closed when the\n"
1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"returned I/O object is closed, unless closefd is set to False.)\n"
1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"mode is an optional string that specifies the mode in which the file\n"
1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"is opened. It defaults to 'r' which means open for reading in text\n"
1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"mode.  Other common values are 'w' for writing (truncating the file if\n"
1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"it already exists), and 'a' for appending (which on some Unix systems,\n"
1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"means that all writes append to the end of the file regardless of the\n"
1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"current seek position). In text mode, if encoding is not specified the\n"
1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"encoding used is platform dependent. (For reading and writing raw\n"
1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"bytes use binary mode and leave encoding unspecified.) The available\n"
1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"modes are:\n"
1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"========= ===============================================================\n"
1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Character Meaning\n"
1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"--------- ---------------------------------------------------------------\n"
2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'r'       open for reading (default)\n"
2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'w'       open for writing, truncating the file first\n"
2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'a'       open for writing, appending to the end of the file if it exists\n"
2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'b'       binary mode\n"
2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'t'       text mode (default)\n"
2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'+'       open a disk file for updating (reading and writing)\n"
2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'U'       universal newline mode (for backwards compatibility; unneeded\n"
2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"          for new code)\n"
2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"========= ===============================================================\n"
2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"The default mode is 'rt' (open for reading text). For binary random\n"
2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"access, the mode 'w+b' opens and truncates the file to 0 bytes, while\n"
2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'r+b' opens the file without truncation.\n"
2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Python distinguishes between files opened in binary and text modes,\n"
2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"even when the underlying operating system doesn't. Files opened in\n"
2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"binary mode (appending 'b' to the mode argument) return contents as\n"
2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"bytes objects without any decoding. In text mode (the default, or when\n"
2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'t' is appended to the mode argument), the contents of the file are\n"
2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"returned as strings, the bytes having been first decoded using a\n"
2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"platform-dependent encoding or using the specified encoding if given.\n"
2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"buffering is an optional integer used to set the buffering policy.\n"
2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n"
2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"line buffering (only usable in text mode), and an integer > 1 to indicate\n"
2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"the size of a fixed-size chunk buffer.  When no buffering argument is\n"
2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"given, the default buffering policy works as follows:\n"
2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"* Binary files are buffered in fixed-size chunks; the size of the buffer\n"
2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  is chosen using a heuristic trying to determine the underlying device's\n"
2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  \"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`.\n"
2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  On many systems, the buffer will typically be 4096 or 8192 bytes long.\n"
2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"* \"Interactive\" text files (files for which isatty() returns True)\n"
2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  use line buffering.  Other text files use the policy described above\n"
2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  for binary files.\n"
2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"encoding is the name of the encoding used to decode or encode the\n"
2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"file. This should only be used in text mode. The default encoding is\n"
2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"platform dependent, but any encoding supported by Python can be\n"
2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"passed.  See the codecs module for the list of supported encodings.\n"
2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"errors is an optional string that specifies how encoding errors are to\n"
2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"be handled---this argument should not be used in binary mode. Pass\n"
2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'strict' to raise a ValueError exception if there is an encoding error\n"
2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"(the default of None has the same effect), or pass 'ignore' to ignore\n"
2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"errors. (Note that ignoring encoding errors can lead to data loss.)\n"
2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"See the documentation for codecs.register for a list of the permitted\n"
2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"encoding error strings.\n"
2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"newline controls how universal newlines works (it only applies to text\n"
2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"mode). It can be None, '', '\\n', '\\r', and '\\r\\n'.  It works as\n"
2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"follows:\n"
2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"* On input, if newline is None, universal newlines mode is\n"
2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  enabled. Lines in the input can end in '\\n', '\\r', or '\\r\\n', and\n"
2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  these are translated into '\\n' before being returned to the\n"
2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  caller. If it is '', universal newline mode is enabled, but line\n"
2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  endings are returned to the caller untranslated. If it has any of\n"
2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  the other legal values, input lines are only terminated by the given\n"
2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  string, and the line ending is returned to the caller untranslated.\n"
2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"* On output, if newline is None, any '\\n' characters written are\n"
2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  translated to the system default line separator, os.linesep. If\n"
2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  newline is '', no translation takes place. If newline is any of the\n"
2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  other legal values, any '\\n' characters written are translated to\n"
2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"  the given string.\n"
2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"If closefd is False, the underlying file descriptor will be kept open\n"
2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"when the file is closed. This does not work when a file name is given\n"
2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"and must be True in that case.\n"
2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"open() returns a file object whose type depends on the mode, and\n"
2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"through which the standard file operations such as reading and writing\n"
2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"are performed. When open() is used to open a file in a text mode ('w',\n"
2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open\n"
2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"a file in a binary mode, the returned class varies: in read binary\n"
2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"mode, it returns a BufferedReader; in write binary and append binary\n"
2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"modes, it returns a BufferedWriter, and in read/write mode, it returns\n"
2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"a BufferedRandom.\n"
2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"\n"
2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"It is also possible to use a string or bytearray as a file for both\n"
2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"reading and writing. For strings StringIO can be used like a file\n"
2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"opened in a text mode, and for bytes a BytesIO can be used like a file\n"
2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"opened in a binary mode.\n"
2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    );
2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielio_open(PyObject *self, PyObject *args, PyObject *kwds)
2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *kwlist[] = {"file", "mode", "buffering",
2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      "encoding", "errors", "newline",
2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      "closefd", NULL};
2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *file;
2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *mode = "r";
2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int buffering = -1, closefd = 1;
2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *encoding = NULL, *errors = NULL, *newline = NULL;
2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned i;
2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int reading = 0, writing = 0, appending = 0, updating = 0;
3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int text = 0, binary = 0, universal = 0;
3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char rawmode[5], *m;
3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int line_buffering;
3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    long isatty;
3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL;
3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzzi:open", kwlist,
3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     &file, &mode, &buffering,
3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     &encoding, &errors, &newline,
3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     &closefd)) {
3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyUnicode_Check(file) &&
3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel	!PyBytes_Check(file) &&
3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel	!PyNumber_Check(file)) {
3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *repr = PyObject_Repr(file);
3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (repr != NULL) {
3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_Format(PyExc_TypeError, "invalid file: %s",
3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                         PyString_AS_STRING(repr));
3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(repr);
3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Decode mode */
3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 0; i < strlen(mode); i++) {
3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        char c = mode[i];
3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        switch (c) {
3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case 'r':
3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            reading = 1;
3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case 'w':
3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            writing = 1;
3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case 'a':
3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            appending = 1;
3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case '+':
3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            updating = 1;
3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case 't':
3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            text = 1;
3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case 'b':
3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            binary = 1;
3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case 'U':
3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            universal = 1;
3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            reading = 1;
3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        default:
3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto invalid_mode;
3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* c must not be duplicated */
3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strchr(mode+i+1, c)) {
3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          invalid_mode:
3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode);
3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    m = rawmode;
3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (reading)   *(m++) = 'r';
3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (writing)   *(m++) = 'w';
3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (appending) *(m++) = 'a';
3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (updating)  *(m++) = '+';
3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    *m = '\0';
3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Parameters validation */
3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (universal) {
3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (writing || appending) {
3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_SetString(PyExc_ValueError,
3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            "can't use U and writing mode at once");
3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        reading = 1;
3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (text && binary) {
3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "can't have text and binary mode at once");
3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (reading + writing + appending > 1) {
3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "must have exactly one of read/write/append mode");
3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (binary && encoding != NULL) {
3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "binary mode doesn't take an encoding argument");
3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (binary && errors != NULL) {
4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "binary mode doesn't take an errors argument");
4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (binary && newline != NULL) {
4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "binary mode doesn't take a newline argument");
4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Create the Raw file stream */
4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    raw = PyObject_CallFunction((PyObject *)&PyFileIO_Type,
4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel				"Osi", file, rawmode, closefd);
4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (raw == NULL)
4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    result = raw;
4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    modeobj = PyUnicode_FromString(mode);
4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (modeobj == NULL)
4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto error;
4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* buffering */
4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {
4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *res = PyObject_CallMethod(raw, "isatty", NULL);
4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (res == NULL)
4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto error;
4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        isatty = PyLong_AsLong(res);
4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(res);
4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (isatty == -1 && PyErr_Occurred())
4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto error;
4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (buffering == 1 || (buffering < 0 && isatty)) {
4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        buffering = -1;
4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        line_buffering = 1;
4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        line_buffering = 0;
4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (buffering < 0) {
4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        buffering = DEFAULT_BUFFER_SIZE;
4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        {
4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            struct stat st;
4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            int fileno;
4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *res = PyObject_CallMethod(raw, "fileno", NULL);
4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (res == NULL)
4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                goto error;
4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            fileno = _PyInt_AsInt(res);
4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(res);
4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (fileno == -1 && PyErr_Occurred())
4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                goto error;
4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (fstat(fileno, &st) >= 0 && st.st_blksize > 1)
4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                buffering = st.st_blksize;
4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (buffering < 0) {
4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "invalid buffering size");
4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto error;
4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* if not buffering, returns the raw file object */
4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (buffering == 0) {
4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!binary) {
4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_SetString(PyExc_ValueError,
4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            "can't have unbuffered text I/O");
4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto error;
4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(modeobj);
4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return result;
4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* wraps into a buffered file */
4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {
4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *Buffered_class;
4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (updating)
4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Buffered_class = (PyObject *)&PyBufferedRandom_Type;
4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (writing || appending)
4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Buffered_class = (PyObject *)&PyBufferedWriter_Type;
4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (reading)
4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Buffered_class = (PyObject *)&PyBufferedReader_Type;
4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_Format(PyExc_ValueError,
4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                         "unknown mode: '%s'", mode);
4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto error;
4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering);
4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (buffer == NULL)
5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto error;
5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    result = buffer;
5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(raw);
5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* if binary, returns the buffered file */
5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (binary) {
5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(modeobj);
5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return result;
5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* wraps into a TextIOWrapper */
5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type,
5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel				    "Osssi",
5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel				    buffer,
5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel				    encoding, errors, newline,
5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel				    line_buffering);
5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (wrapper == NULL)
5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto error;
5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    result = wrapper;
5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(buffer);
5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyObject_SetAttrString(wrapper, "mode", modeobj) < 0)
5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto error;
5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(modeobj);
5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  error:
5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (result != NULL) {
5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *exc, *val, *tb, *close_result;
5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Fetch(&exc, &val, &tb);
5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        close_result = PyObject_CallMethod(result, "close", NULL);
5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        _PyErr_ReplaceException(exc, val, tb);
5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(close_result);
5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(result);
5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XDECREF(modeobj);
5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return NULL;
5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Private helpers for the io module.
5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPy_off_t
5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyNumber_AsOff_t(PyObject *item, PyObject *err)
5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_off_t result;
5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *runerr;
5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *value = PyNumber_Index(item);
5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (value == NULL)
5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyInt_Check(value)) {
5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* We assume a long always fits in a Py_off_t... */
5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = (Py_off_t) PyInt_AS_LONG(value);
5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto finish;
5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* We're done if PyLong_AsSsize_t() returns without error. */
5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    result = PyLong_AsOff_t(value);
5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (result != -1 || !(runerr = PyErr_Occurred()))
5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto finish;
5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Error handling code -- only manage OverflowError differently */
5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError))
5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto finish;
5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyErr_Clear();
5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* If no error-handling desired then the default clipping
5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       is sufficient.
5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!err) {
5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        assert(PyLong_Check(value));
5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Whether or not it is less than or equal to
5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           zero is determined by the sign of ob_size
5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        */
5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (_PyLong_Sign(value) < 0)
5787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            result = PY_OFF_T_MIN;
5797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
5807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            result = PY_OFF_T_MAX;
5817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
5837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Otherwise replace the error with caller's error object. */
5847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(err,
5857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "cannot fit '%.200s' into an offset-sized integer",
5867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     item->ob_type->tp_name);
5877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel finish:
5907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(value);
5917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
5927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Basically the "n" format code with the ability to turn None into -1. */
5967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint
5977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_PyIO_ConvertSsize_t(PyObject *obj, void *result) {
5987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_ssize_t limit;
5997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (obj == Py_None) {
6007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        limit = -1;
6017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
6027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (PyNumber_Check(obj)) {
6037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError);
6047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (limit == -1 && PyErr_Occurred())
6057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return 0;
6067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
6077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
6087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(PyExc_TypeError,
6097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "integer argument expected, got '%.200s'",
6107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     Py_TYPE(obj)->tp_name);
6117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
6127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
6137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    *((Py_ssize_t *)result) = limit;
6147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 1;
6157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
6167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
6197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Module definition
6207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
6217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_os_module = NULL;
6237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_locale_module = NULL;
6247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *_PyIO_unsupported_operation = NULL;
6257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMethodDef module_methods[] = {
6277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"open", (PyCFunction)io_open, METH_VARARGS|METH_KEYWORDS, open_doc},
6287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL, NULL}
6297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
6307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyMODINIT_FUNC
6327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinit_io(void)
6337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
6347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *m = Py_InitModule4("_io", module_methods,
6357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                 module_doc, NULL, PYTHON_API_VERSION);
6367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (m == NULL)
6377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
6387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* put os in the module state */
6407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    _PyIO_os_module = PyImport_ImportModule("os");
6417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (_PyIO_os_module == NULL)
6427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
6437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define ADD_TYPE(type, name) \
6457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyType_Ready(type) < 0) \
6467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail; \
6477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(type); \
6487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyModule_AddObject(m, name, (PyObject *)type) < 0) {  \
6497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(type); \
6507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail; \
6517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
6527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* DEFAULT_BUFFER_SIZE */
6547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0)
6557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
6567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* UnsupportedOperation inherits from ValueError and IOError */
6587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    _PyIO_unsupported_operation = PyObject_CallFunction(
6597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (PyObject *)&PyType_Type, "s(OO){}",
6607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        "UnsupportedOperation", PyExc_ValueError, PyExc_IOError);
6617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (_PyIO_unsupported_operation == NULL)
6627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
6637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(_PyIO_unsupported_operation);
6647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyModule_AddObject(m, "UnsupportedOperation",
6657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           _PyIO_unsupported_operation) < 0)
6667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
6677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* BlockingIOError */
6697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    _PyExc_BlockingIOError.tp_base = (PyTypeObject *) PyExc_IOError;
6707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&_PyExc_BlockingIOError, "BlockingIOError");
6717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Concrete base types of the IO ABCs.
6737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       (the ABCs themselves are declared through inheritance in io.py)
6747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    */
6757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyIOBase_Type, "_IOBase");
6767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyRawIOBase_Type, "_RawIOBase");
6777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyBufferedIOBase_Type, "_BufferedIOBase");
6787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyTextIOBase_Type, "_TextIOBase");
6797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Implementation of concrete IO objects. */
6817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* FileIO */
6827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyFileIO_Type.tp_base = &PyRawIOBase_Type;
6837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyFileIO_Type, "FileIO");
6847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* BytesIO */
6867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
6877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyBytesIO_Type, "BytesIO");
6887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* StringIO */
6907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyStringIO_Type.tp_base = &PyTextIOBase_Type;
6917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyStringIO_Type, "StringIO");
6927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* BufferedReader */
6947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
6957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyBufferedReader_Type, "BufferedReader");
6967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* BufferedWriter */
6987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
6997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyBufferedWriter_Type, "BufferedWriter");
7007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* BufferedRWPair */
7027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
7037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyBufferedRWPair_Type, "BufferedRWPair");
7047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* BufferedRandom */
7067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
7077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyBufferedRandom_Type, "BufferedRandom");
7087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* TextIOWrapper */
7107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
7117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyTextIOWrapper_Type, "TextIOWrapper");
7127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* IncrementalNewlineDecoder */
7147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder");
7157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Interned strings */
7177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_close = PyString_InternFromString("close")))
7187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_closed = PyString_InternFromString("closed")))
7207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_decode = PyString_InternFromString("decode")))
7227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_encode = PyString_InternFromString("encode")))
7247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_fileno = PyString_InternFromString("fileno")))
7267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_flush = PyString_InternFromString("flush")))
7287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_getstate = PyString_InternFromString("getstate")))
7307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_isatty = PyString_InternFromString("isatty")))
7327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_newlines = PyString_InternFromString("newlines")))
7347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_nl = PyString_InternFromString("\n")))
7367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_read = PyString_InternFromString("read")))
7387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_read1 = PyString_InternFromString("read1")))
7407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_readable = PyString_InternFromString("readable")))
7427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_readinto = PyString_InternFromString("readinto")))
7447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_readline = PyString_InternFromString("readline")))
7467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_reset = PyString_InternFromString("reset")))
7487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_seek = PyString_InternFromString("seek")))
7507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_seekable = PyString_InternFromString("seekable")))
7527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_setstate = PyString_InternFromString("setstate")))
7547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_tell = PyString_InternFromString("tell")))
7567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_truncate = PyString_InternFromString("truncate")))
7587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_write = PyString_InternFromString("write")))
7607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_str_writable = PyString_InternFromString("writable")))
7627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0)))
7657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0)))
7677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!(_PyIO_zero = PyLong_FromLong(0L)))
7697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto fail;
7707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return;
7727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  fail:
7747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_CLEAR(_PyIO_os_module);
7757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_CLEAR(_PyIO_unsupported_operation);
7767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(m);
7777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
778