/* An implementation of the I/O abstract base classes hierarchy as defined by PEP 3116 - "New I/O" Classes defined here: IOBase, RawIOBase. Written by Amaury Forgeot d'Arc and Antoine Pitrou */ #include "Python.h" #include "pycore_call.h" // _PyObject_CallMethod() #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_object.h" // _PyType_HasFeature() #include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include <stddef.h> // offsetof() #include "_iomodule.h" /*[clinic input] module _io class _io._IOBase "PyObject *" "clinic_state()->PyIOBase_Type" class _io._RawIOBase "PyObject *" "clinic_state()->PyRawIOBase_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=9006b7802ab8ea85]*/ /* * IOBase class, an abstract class */ iobase; PyDoc_STRVAR(iobase_doc, "The abstract base class for all I/O classes.\n" "\n" "This class provides dummy implementations for many methods that\n" "derived classes can override selectively; the default implementations\n" "represent a file that cannot be read, written or seeked.\n" "\n" "Even though IOBase does not declare read, readinto, or write because\n" "their signatures will vary, implementations and clients should\n" "consider those methods part of the interface. Also, implementations\n" "may raise UnsupportedOperation when operations they do not support are\n" "called.\n" "\n" "The basic type used for binary data read from or written to a file is\n" "bytes. Other bytes-like objects are accepted as method arguments too.\n" "In some cases (such as readinto), a writable object is required. Text\n" "I/O classes work with str data.\n" "\n" "Note that calling any method (except additional calls to close(),\n" "which are ignored) on a closed stream should raise a ValueError.\n" "\n" "IOBase (and its subclasses) support the iterator protocol, meaning\n" "that an IOBase object can be iterated over yielding the lines in a\n" "stream.\n" "\n" "IOBase also supports the :keyword:`with` statement. In this example,\n" "fp is closed after the suite of the with statement is complete:\n" "\n" "with open('spam.txt', 'r') as fp:\n" " fp.write('Spam and eggs!')\n"); /* Internal methods */ /* Use this function whenever you want to check the internal `closed` status of the IOBase object rather than the virtual `closed` attribute as returned by whatever subclass. */ static int iobase_is_closed(PyObject *self) { … } static PyObject * iobase_unsupported(_PyIO_State *state, const char *message) { … } /* Positioning */ /*[clinic input] _io._IOBase.seek cls: defining_class offset: int(unused=True) The stream position, relative to 'whence'. whence: int(unused=True, c_default='0') = os.SEEK_SET The relative position to seek from. / Change the stream position to the given byte offset. The offset is interpreted relative to the position indicated by whence. Values for whence are: * os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive * os.SEEK_CUR or 1 -- current stream position; offset may be negative * os.SEEK_END or 2 -- end of stream; offset is usually negative Return the new absolute position. [clinic start generated code]*/ static PyObject * _io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, int Py_UNUSED(offset), int Py_UNUSED(whence)) /*[clinic end generated code: output=8bd74ea6538ded53 input=74211232b363363e]*/ { … } /*[clinic input] _io._IOBase.tell Return current stream position. [clinic start generated code]*/ static PyObject * _io__IOBase_tell_impl(PyObject *self) /*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/ { … } /*[clinic input] _io._IOBase.truncate cls: defining_class size: object(unused=True) = None / Truncate file to size bytes. File pointer is left unchanged. Size defaults to the current IO position as reported by tell(). Return the new size. [clinic start generated code]*/ static PyObject * _io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, PyObject *Py_UNUSED(size)) /*[clinic end generated code: output=2013179bff1fe8ef input=660ac20936612c27]*/ { … } /* Flush and close methods */ /*[clinic input] _io._IOBase.flush Flush write buffers, if applicable. This is not implemented for read-only and non-blocking streams. [clinic start generated code]*/ static PyObject * _io__IOBase_flush_impl(PyObject *self) /*[clinic end generated code: output=7cef4b4d54656a3b input=773be121abe270aa]*/ { … } static PyObject * iobase_closed_get(PyObject *self, void *context) { … } static int iobase_check_closed(PyObject *self) { … } PyObject * _PyIOBase_check_closed(PyObject *self, PyObject *args) { … } static PyObject * iobase_check_seekable(PyObject *self, PyObject *args) { … } static PyObject * iobase_check_readable(PyObject *self, PyObject *args) { … } static PyObject * iobase_check_writable(PyObject *self, PyObject *args) { … } PyObject * _PyIOBase_cannot_pickle(PyObject *self, PyObject *args) { … } /* XXX: IOBase thinks it has to maintain its own internal state in `__IOBase_closed` and call flush() by itself, but it is redundant with whatever behaviour a non-trivial derived class will implement. */ /*[clinic input] _io._IOBase.close Flush and close the IO object. This method has no effect if the file is already closed. [clinic start generated code]*/ static PyObject * _io__IOBase_close_impl(PyObject *self) /*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/ { … } /* Finalization and garbage collection support */ static void iobase_finalize(PyObject *self) { … } int _PyIOBase_finalize(PyObject *self) { … } static int iobase_traverse(iobase *self, visitproc visit, void *arg) { … } static int iobase_clear(iobase *self) { … } /* Destructor */ static void iobase_dealloc(iobase *self) { … } /* Inquiry methods */ /*[clinic input] _io._IOBase.seekable Return whether object supports random access. If False, seek(), tell() and truncate() will raise OSError. This method may need to do a test seek(). [clinic start generated code]*/ static PyObject * _io__IOBase_seekable_impl(PyObject *self) /*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/ { … } PyObject * _PyIOBase_check_seekable(_PyIO_State *state, PyObject *self, PyObject *args) { … } /*[clinic input] _io._IOBase.readable Return whether object was opened for reading. If False, read() will raise OSError. [clinic start generated code]*/ static PyObject * _io__IOBase_readable_impl(PyObject *self) /*[clinic end generated code: output=e48089250686388b input=285b3b866a0ec35f]*/ { … } /* May be called with any object */ PyObject * _PyIOBase_check_readable(_PyIO_State *state, PyObject *self, PyObject *args) { … } /*[clinic input] _io._IOBase.writable Return whether object was opened for writing. If False, write() will raise OSError. [clinic start generated code]*/ static PyObject * _io__IOBase_writable_impl(PyObject *self) /*[clinic end generated code: output=406001d0985be14f input=9dcac18a013a05b5]*/ { … } /* May be called with any object */ PyObject * _PyIOBase_check_writable(_PyIO_State *state, PyObject *self, PyObject *args) { … } /* Context manager */ static PyObject * iobase_enter(PyObject *self, PyObject *args) { … } static PyObject * iobase_exit(PyObject *self, PyObject *args) { … } /* Lower-level APIs */ /* XXX Should these be present even if unimplemented? */ /*[clinic input] _io._IOBase.fileno cls: defining_class / Return underlying file descriptor if one exists. Raise OSError if the IO object does not use a file descriptor. [clinic start generated code]*/ static PyObject * _io__IOBase_fileno_impl(PyObject *self, PyTypeObject *cls) /*[clinic end generated code: output=7caaa32a6f4ada3d input=1927c8bea5c85099]*/ { … } /*[clinic input] _io._IOBase.isatty Return whether this is an 'interactive' stream. Return False if it can't be determined. [clinic start generated code]*/ static PyObject * _io__IOBase_isatty_impl(PyObject *self) /*[clinic end generated code: output=60cab77cede41cdd input=9ef76530d368458b]*/ { … } /* Readline(s) and writelines */ /*[clinic input] _io._IOBase.readline size as limit: Py_ssize_t(accept={int, NoneType}) = -1 / Read and return a line from the stream. If size is specified, at most size bytes will be read. The line terminator is always b'\n' for binary files; for text files, the newlines argument to open can be used to select the line terminator(s) recognized. [clinic start generated code]*/ static PyObject * _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) /*[clinic end generated code: output=4479f79b58187840 input=d0c596794e877bff]*/ { … } static PyObject * iobase_iter(PyObject *self) { … } static PyObject * iobase_iternext(PyObject *self) { … } /*[clinic input] _io._IOBase.readlines hint: Py_ssize_t(accept={int, NoneType}) = -1 / Return a list of lines from the stream. hint can be specified to control the number of lines read: no more lines will be read if the total size (in bytes/characters) of all lines so far exceeds hint. [clinic start generated code]*/ static PyObject * _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) /*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/ { … } /*[clinic input] _io._IOBase.writelines lines: object / Write a list of lines to stream. Line separators are not added, so it is usual for each of the lines provided to have a line separator at the end. [clinic start generated code]*/ static PyObject * _io__IOBase_writelines(PyObject *self, PyObject *lines) /*[clinic end generated code: output=976eb0a9b60a6628 input=cac3fc8864183359]*/ { … } #define clinic_state … #include "clinic/iobase.c.h" #undef clinic_state static PyMethodDef iobase_methods[] = …; static PyGetSetDef iobase_getset[] = …; static struct PyMemberDef iobase_members[] = …; static PyType_Slot iobase_slots[] = …; PyType_Spec iobase_spec = …; /* * RawIOBase class, Inherits from IOBase. */ PyDoc_STRVAR(rawiobase_doc, "Base class for raw binary I/O."); /* * The read() method is implemented by calling readinto(); derived classes * that want to support read() only need to implement readinto() as a * primitive operation. In general, readinto() can be more efficient than * read(). * * (It would be tempting to also provide an implementation of readinto() in * terms of read(), in case the latter is a more suitable primitive operation, * but that would lead to nasty recursion in case a subclass doesn't implement * either.) */ /*[clinic input] _io._RawIOBase.read size as n: Py_ssize_t = -1 / [clinic start generated code]*/ static PyObject * _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n) /*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/ { … } /*[clinic input] _io._RawIOBase.readall Read until EOF, using multiple read() call. [clinic start generated code]*/ static PyObject * _io__RawIOBase_readall_impl(PyObject *self) /*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/ { … } static PyObject * rawiobase_readinto(PyObject *self, PyObject *args) { … } static PyObject * rawiobase_write(PyObject *self, PyObject *args) { … } static PyMethodDef rawiobase_methods[] = …; static PyType_Slot rawiobase_slots[] = …; /* Do not set Py_TPFLAGS_HAVE_GC so that tp_traverse and tp_clear are inherited */ PyType_Spec rawiobase_spec = …;