Home | History | Annotate | Download | only in _io
      1 /*
      2     An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
      3 
      4     Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
      5     BufferedRandom.
      6 
      7     Written by Amaury Forgeot d'Arc and Antoine Pitrou
      8 */
      9 
     10 #define PY_SSIZE_T_CLEAN
     11 #include "Python.h"
     12 #include "structmember.h"
     13 #include "pythread.h"
     14 #include "_iomodule.h"
     15 
     16 /*[clinic input]
     17 module _io
     18 class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
     19 class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
     20 class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
     21 class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
     22 class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
     23 class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
     24 [clinic start generated code]*/
     25 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
     26 
     27 /*[python input]
     28 class io_ssize_t_converter(CConverter):
     29     type = 'Py_ssize_t'
     30     converter = '_PyIO_ConvertSsize_t'
     31 [python start generated code]*/
     32 /*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
     33 
     34 _Py_IDENTIFIER(close);
     35 _Py_IDENTIFIER(_dealloc_warn);
     36 _Py_IDENTIFIER(flush);
     37 _Py_IDENTIFIER(isatty);
     38 _Py_IDENTIFIER(mode);
     39 _Py_IDENTIFIER(name);
     40 _Py_IDENTIFIER(peek);
     41 _Py_IDENTIFIER(read);
     42 _Py_IDENTIFIER(read1);
     43 _Py_IDENTIFIER(readable);
     44 _Py_IDENTIFIER(readinto);
     45 _Py_IDENTIFIER(readinto1);
     46 _Py_IDENTIFIER(writable);
     47 _Py_IDENTIFIER(write);
     48 
     49 /*
     50  * BufferedIOBase class, inherits from IOBase.
     51  */
     52 PyDoc_STRVAR(bufferediobase_doc,
     53     "Base class for buffered IO objects.\n"
     54     "\n"
     55     "The main difference with RawIOBase is that the read() method\n"
     56     "supports omitting the size argument, and does not have a default\n"
     57     "implementation that defers to readinto().\n"
     58     "\n"
     59     "In addition, read(), readinto() and write() may raise\n"
     60     "BlockingIOError if the underlying raw stream is in non-blocking\n"
     61     "mode and not ready; unlike their raw counterparts, they will never\n"
     62     "return None.\n"
     63     "\n"
     64     "A typical implementation should not inherit from a RawIOBase\n"
     65     "implementation, but wrap one.\n"
     66     );
     67 
     68 static PyObject *
     69 _bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
     70 {
     71     Py_ssize_t len;
     72     PyObject *data;
     73 
     74     data = _PyObject_CallMethodId(self,
     75                                   readinto1 ? &PyId_read1 : &PyId_read,
     76                                   "n", buffer->len);
     77     if (data == NULL)
     78         return NULL;
     79 
     80     if (!PyBytes_Check(data)) {
     81         Py_DECREF(data);
     82         PyErr_SetString(PyExc_TypeError, "read() should return bytes");
     83         return NULL;
     84     }
     85 
     86     len = Py_SIZE(data);
     87     if (len > buffer->len) {
     88         PyErr_Format(PyExc_ValueError,
     89                      "read() returned too much data: "
     90                      "%zd bytes requested, %zd returned",
     91                      buffer->len, len);
     92         Py_DECREF(data);
     93         return NULL;
     94     }
     95     memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
     96 
     97     Py_DECREF(data);
     98 
     99     return PyLong_FromSsize_t(len);
    100 }
    101 
    102 /*[clinic input]
    103 _io._BufferedIOBase.readinto
    104     buffer: Py_buffer(accept={rwbuffer})
    105     /
    106 [clinic start generated code]*/
    107 
    108 static PyObject *
    109 _io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
    110 /*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
    111 {
    112     return _bufferediobase_readinto_generic(self, buffer, 0);
    113 }
    114 
    115 /*[clinic input]
    116 _io._BufferedIOBase.readinto1
    117     buffer: Py_buffer(accept={rwbuffer})
    118     /
    119 [clinic start generated code]*/
    120 
    121 static PyObject *
    122 _io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
    123 /*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
    124 {
    125     return _bufferediobase_readinto_generic(self, buffer, 1);
    126 }
    127 
    128 static PyObject *
    129 bufferediobase_unsupported(const char *message)
    130 {
    131     _PyIO_State *state = IO_STATE();
    132     if (state != NULL)
    133         PyErr_SetString(state->unsupported_operation, message);
    134     return NULL;
    135 }
    136 
    137 /*[clinic input]
    138 _io._BufferedIOBase.detach
    139 
    140 Disconnect this buffer from its underlying raw stream and return it.
    141 
    142 After the raw stream has been detached, the buffer is in an unusable
    143 state.
    144 [clinic start generated code]*/
    145 
    146 static PyObject *
    147 _io__BufferedIOBase_detach_impl(PyObject *self)
    148 /*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
    149 {
    150     return bufferediobase_unsupported("detach");
    151 }
    152 
    153 PyDoc_STRVAR(bufferediobase_read_doc,
    154     "Read and return up to n bytes.\n"
    155     "\n"
    156     "If the argument is omitted, None, or negative, reads and\n"
    157     "returns all data until EOF.\n"
    158     "\n"
    159     "If the argument is positive, and the underlying raw stream is\n"
    160     "not 'interactive', multiple raw reads may be issued to satisfy\n"
    161     "the byte count (unless EOF is reached first).  But for\n"
    162     "interactive raw streams (as well as sockets and pipes), at most\n"
    163     "one raw read will be issued, and a short result does not imply\n"
    164     "that EOF is imminent.\n"
    165     "\n"
    166     "Returns an empty bytes object on EOF.\n"
    167     "\n"
    168     "Returns None if the underlying raw stream was open in non-blocking\n"
    169     "mode and no data is available at the moment.\n");
    170 
    171 static PyObject *
    172 bufferediobase_read(PyObject *self, PyObject *args)
    173 {
    174     return bufferediobase_unsupported("read");
    175 }
    176 
    177 PyDoc_STRVAR(bufferediobase_read1_doc,
    178     "Read and return up to n bytes, with at most one read() call\n"
    179     "to the underlying raw stream. A short result does not imply\n"
    180     "that EOF is imminent.\n"
    181     "\n"
    182     "Returns an empty bytes object on EOF.\n");
    183 
    184 static PyObject *
    185 bufferediobase_read1(PyObject *self, PyObject *args)
    186 {
    187     return bufferediobase_unsupported("read1");
    188 }
    189 
    190 PyDoc_STRVAR(bufferediobase_write_doc,
    191     "Write the given buffer to the IO stream.\n"
    192     "\n"
    193     "Returns the number of bytes written, which is always the length of b\n"
    194     "in bytes.\n"
    195     "\n"
    196     "Raises BlockingIOError if the buffer is full and the\n"
    197     "underlying raw stream cannot accept more data at the moment.\n");
    198 
    199 static PyObject *
    200 bufferediobase_write(PyObject *self, PyObject *args)
    201 {
    202     return bufferediobase_unsupported("write");
    203 }
    204 
    205 
    206 typedef struct {
    207     PyObject_HEAD
    208 
    209     PyObject *raw;
    210     int ok;    /* Initialized? */
    211     int detached;
    212     int readable;
    213     int writable;
    214     char finalizing;
    215 
    216     /* True if this is a vanilla Buffered object (rather than a user derived
    217        class) *and* the raw stream is a vanilla FileIO object. */
    218     int fast_closed_checks;
    219 
    220     /* Absolute position inside the raw stream (-1 if unknown). */
    221     Py_off_t abs_pos;
    222 
    223     /* A static buffer of size `buffer_size` */
    224     char *buffer;
    225     /* Current logical position in the buffer. */
    226     Py_off_t pos;
    227     /* Position of the raw stream in the buffer. */
    228     Py_off_t raw_pos;
    229 
    230     /* Just after the last buffered byte in the buffer, or -1 if the buffer
    231        isn't ready for reading. */
    232     Py_off_t read_end;
    233 
    234     /* Just after the last byte actually written */
    235     Py_off_t write_pos;
    236     /* Just after the last byte waiting to be written, or -1 if the buffer
    237        isn't ready for writing. */
    238     Py_off_t write_end;
    239 
    240 #ifdef WITH_THREAD
    241     PyThread_type_lock lock;
    242     volatile long owner;
    243 #endif
    244 
    245     Py_ssize_t buffer_size;
    246     Py_ssize_t buffer_mask;
    247 
    248     PyObject *dict;
    249     PyObject *weakreflist;
    250 } buffered;
    251 
    252 /*
    253     Implementation notes:
    254 
    255     * BufferedReader, BufferedWriter and BufferedRandom try to share most
    256       methods (this is helped by the members `readable` and `writable`, which
    257       are initialized in the respective constructors)
    258     * They also share a single buffer for reading and writing. This enables
    259       interleaved reads and writes without flushing. It also makes the logic
    260       a bit trickier to get right.
    261     * The absolute position of the raw stream is cached, if possible, in the
    262       `abs_pos` member. It must be updated every time an operation is done
    263       on the raw stream. If not sure, it can be reinitialized by calling
    264       _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
    265       also does it). To read it, use RAW_TELL().
    266     * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
    267       _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
    268 
    269     NOTE: we should try to maintain block alignment of reads and writes to the
    270     raw stream (according to the buffer size), but for now it is only done
    271     in read() and friends.
    272 
    273 */
    274 
    275 /* These macros protect the buffered object against concurrent operations. */
    276 
    277 #ifdef WITH_THREAD
    278 
    279 static int
    280 _enter_buffered_busy(buffered *self)
    281 {
    282     int relax_locking;
    283     PyLockStatus st;
    284     if (self->owner == PyThread_get_thread_ident()) {
    285         PyErr_Format(PyExc_RuntimeError,
    286                      "reentrant call inside %R", self);
    287         return 0;
    288     }
    289     relax_locking = (_Py_Finalizing != NULL);
    290     Py_BEGIN_ALLOW_THREADS
    291     if (!relax_locking)
    292         st = PyThread_acquire_lock(self->lock, 1);
    293     else {
    294         /* When finalizing, we don't want a deadlock to happen with daemon
    295          * threads abruptly shut down while they owned the lock.
    296          * Therefore, only wait for a grace period (1 s.).
    297          * Note that non-daemon threads have already exited here, so this
    298          * shouldn't affect carefully written threaded I/O code.
    299          */
    300         st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
    301     }
    302     Py_END_ALLOW_THREADS
    303     if (relax_locking && st != PY_LOCK_ACQUIRED) {
    304         PyObject *msgobj = PyUnicode_FromFormat(
    305             "could not acquire lock for %A at interpreter "
    306             "shutdown, possibly due to daemon threads",
    307             (PyObject *) self);
    308         char *msg = PyUnicode_AsUTF8(msgobj);
    309         Py_FatalError(msg);
    310     }
    311     return 1;
    312 }
    313 
    314 #define ENTER_BUFFERED(self) \
    315     ( (PyThread_acquire_lock(self->lock, 0) ? \
    316        1 : _enter_buffered_busy(self)) \
    317      && (self->owner = PyThread_get_thread_ident(), 1) )
    318 
    319 #define LEAVE_BUFFERED(self) \
    320     do { \
    321         self->owner = 0; \
    322         PyThread_release_lock(self->lock); \
    323     } while(0);
    324 
    325 #else
    326 #define ENTER_BUFFERED(self) 1
    327 #define LEAVE_BUFFERED(self)
    328 #endif
    329 
    330 #define CHECK_INITIALIZED(self) \
    331     if (self->ok <= 0) { \
    332         if (self->detached) { \
    333             PyErr_SetString(PyExc_ValueError, \
    334                  "raw stream has been detached"); \
    335         } else { \
    336             PyErr_SetString(PyExc_ValueError, \
    337                 "I/O operation on uninitialized object"); \
    338         } \
    339         return NULL; \
    340     }
    341 
    342 #define CHECK_INITIALIZED_INT(self) \
    343     if (self->ok <= 0) { \
    344         if (self->detached) { \
    345             PyErr_SetString(PyExc_ValueError, \
    346                  "raw stream has been detached"); \
    347         } else { \
    348             PyErr_SetString(PyExc_ValueError, \
    349                 "I/O operation on uninitialized object"); \
    350         } \
    351         return -1; \
    352     }
    353 
    354 #define IS_CLOSED(self) \
    355     (self->fast_closed_checks \
    356      ? _PyFileIO_closed(self->raw) \
    357      : buffered_closed(self))
    358 
    359 #define CHECK_CLOSED(self, error_msg) \
    360     if (IS_CLOSED(self)) { \
    361         PyErr_SetString(PyExc_ValueError, error_msg); \
    362         return NULL; \
    363     }
    364 
    365 
    366 #define VALID_READ_BUFFER(self) \
    367     (self->readable && self->read_end != -1)
    368 
    369 #define VALID_WRITE_BUFFER(self) \
    370     (self->writable && self->write_end != -1)
    371 
    372 #define ADJUST_POSITION(self, _new_pos) \
    373     do { \
    374         self->pos = _new_pos; \
    375         if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
    376             self->read_end = self->pos; \
    377     } while(0)
    378 
    379 #define READAHEAD(self) \
    380     ((self->readable && VALID_READ_BUFFER(self)) \
    381         ? (self->read_end - self->pos) : 0)
    382 
    383 #define RAW_OFFSET(self) \
    384     (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
    385         && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
    386 
    387 #define RAW_TELL(self) \
    388     (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
    389 
    390 #define MINUS_LAST_BLOCK(self, size) \
    391     (self->buffer_mask ? \
    392         (size & ~self->buffer_mask) : \
    393         (self->buffer_size * (size / self->buffer_size)))
    394 
    395 
    396 static void
    397 buffered_dealloc(buffered *self)
    398 {
    399     self->finalizing = 1;
    400     if (_PyIOBase_finalize((PyObject *) self) < 0)
    401         return;
    402     _PyObject_GC_UNTRACK(self);
    403     self->ok = 0;
    404     if (self->weakreflist != NULL)
    405         PyObject_ClearWeakRefs((PyObject *)self);
    406     Py_CLEAR(self->raw);
    407     if (self->buffer) {
    408         PyMem_Free(self->buffer);
    409         self->buffer = NULL;
    410     }
    411 #ifdef WITH_THREAD
    412     if (self->lock) {
    413         PyThread_free_lock(self->lock);
    414         self->lock = NULL;
    415     }
    416 #endif
    417     Py_CLEAR(self->dict);
    418     Py_TYPE(self)->tp_free((PyObject *)self);
    419 }
    420 
    421 static PyObject *
    422 buffered_sizeof(buffered *self, void *unused)
    423 {
    424     Py_ssize_t res;
    425 
    426     res = _PyObject_SIZE(Py_TYPE(self));
    427     if (self->buffer)
    428         res += self->buffer_size;
    429     return PyLong_FromSsize_t(res);
    430 }
    431 
    432 static int
    433 buffered_traverse(buffered *self, visitproc visit, void *arg)
    434 {
    435     Py_VISIT(self->raw);
    436     Py_VISIT(self->dict);
    437     return 0;
    438 }
    439 
    440 static int
    441 buffered_clear(buffered *self)
    442 {
    443     self->ok = 0;
    444     Py_CLEAR(self->raw);
    445     Py_CLEAR(self->dict);
    446     return 0;
    447 }
    448 
    449 /* Because this can call arbitrary code, it shouldn't be called when
    450    the refcount is 0 (that is, not directly from tp_dealloc unless
    451    the refcount has been temporarily re-incremented). */
    452 static PyObject *
    453 buffered_dealloc_warn(buffered *self, PyObject *source)
    454 {
    455     if (self->ok && self->raw) {
    456         PyObject *r;
    457         r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
    458         if (r)
    459             Py_DECREF(r);
    460         else
    461             PyErr_Clear();
    462     }
    463     Py_RETURN_NONE;
    464 }
    465 
    466 /*
    467  * _BufferedIOMixin methods
    468  * This is not a class, just a collection of methods that will be reused
    469  * by BufferedReader and BufferedWriter
    470  */
    471 
    472 /* Flush and close */
    473 
    474 static PyObject *
    475 buffered_simple_flush(buffered *self, PyObject *args)
    476 {
    477     CHECK_INITIALIZED(self)
    478     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
    479 }
    480 
    481 static int
    482 buffered_closed(buffered *self)
    483 {
    484     int closed;
    485     PyObject *res;
    486     CHECK_INITIALIZED_INT(self)
    487     res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
    488     if (res == NULL)
    489         return -1;
    490     closed = PyObject_IsTrue(res);
    491     Py_DECREF(res);
    492     return closed;
    493 }
    494 
    495 static PyObject *
    496 buffered_closed_get(buffered *self, void *context)
    497 {
    498     CHECK_INITIALIZED(self)
    499     return PyObject_GetAttr(self->raw, _PyIO_str_closed);
    500 }
    501 
    502 static PyObject *
    503 buffered_close(buffered *self, PyObject *args)
    504 {
    505     PyObject *res = NULL, *exc = NULL, *val, *tb;
    506     int r;
    507 
    508     CHECK_INITIALIZED(self)
    509     if (!ENTER_BUFFERED(self))
    510         return NULL;
    511 
    512     r = buffered_closed(self);
    513     if (r < 0)
    514         goto end;
    515     if (r > 0) {
    516         res = Py_None;
    517         Py_INCREF(res);
    518         goto end;
    519     }
    520 
    521     if (self->finalizing) {
    522         PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
    523         if (r)
    524             Py_DECREF(r);
    525         else
    526             PyErr_Clear();
    527     }
    528     /* flush() will most probably re-take the lock, so drop it first */
    529     LEAVE_BUFFERED(self)
    530     res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
    531     if (!ENTER_BUFFERED(self))
    532         return NULL;
    533     if (res == NULL)
    534         PyErr_Fetch(&exc, &val, &tb);
    535     else
    536         Py_DECREF(res);
    537 
    538     res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
    539 
    540     if (self->buffer) {
    541         PyMem_Free(self->buffer);
    542         self->buffer = NULL;
    543     }
    544 
    545     if (exc != NULL) {
    546         _PyErr_ChainExceptions(exc, val, tb);
    547         Py_CLEAR(res);
    548     }
    549 
    550 end:
    551     LEAVE_BUFFERED(self)
    552     return res;
    553 }
    554 
    555 /* detach */
    556 
    557 static PyObject *
    558 buffered_detach(buffered *self, PyObject *args)
    559 {
    560     PyObject *raw, *res;
    561     CHECK_INITIALIZED(self)
    562     res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
    563     if (res == NULL)
    564         return NULL;
    565     Py_DECREF(res);
    566     raw = self->raw;
    567     self->raw = NULL;
    568     self->detached = 1;
    569     self->ok = 0;
    570     return raw;
    571 }
    572 
    573 /* Inquiries */
    574 
    575 static PyObject *
    576 buffered_seekable(buffered *self, PyObject *args)
    577 {
    578     CHECK_INITIALIZED(self)
    579     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
    580 }
    581 
    582 static PyObject *
    583 buffered_readable(buffered *self, PyObject *args)
    584 {
    585     CHECK_INITIALIZED(self)
    586     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
    587 }
    588 
    589 static PyObject *
    590 buffered_writable(buffered *self, PyObject *args)
    591 {
    592     CHECK_INITIALIZED(self)
    593     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
    594 }
    595 
    596 static PyObject *
    597 buffered_name_get(buffered *self, void *context)
    598 {
    599     CHECK_INITIALIZED(self)
    600     return _PyObject_GetAttrId(self->raw, &PyId_name);
    601 }
    602 
    603 static PyObject *
    604 buffered_mode_get(buffered *self, void *context)
    605 {
    606     CHECK_INITIALIZED(self)
    607     return _PyObject_GetAttrId(self->raw, &PyId_mode);
    608 }
    609 
    610 /* Lower-level APIs */
    611 
    612 static PyObject *
    613 buffered_fileno(buffered *self, PyObject *args)
    614 {
    615     CHECK_INITIALIZED(self)
    616     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
    617 }
    618 
    619 static PyObject *
    620 buffered_isatty(buffered *self, PyObject *args)
    621 {
    622     CHECK_INITIALIZED(self)
    623     return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
    624 }
    625 
    626 /* Serialization */
    627 
    628 static PyObject *
    629 buffered_getstate(buffered *self, PyObject *args)
    630 {
    631     PyErr_Format(PyExc_TypeError,
    632                  "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
    633     return NULL;
    634 }
    635 
    636 /* Forward decls */
    637 static PyObject *
    638 _bufferedwriter_flush_unlocked(buffered *);
    639 static Py_ssize_t
    640 _bufferedreader_fill_buffer(buffered *self);
    641 static void
    642 _bufferedreader_reset_buf(buffered *self);
    643 static void
    644 _bufferedwriter_reset_buf(buffered *self);
    645 static PyObject *
    646 _bufferedreader_peek_unlocked(buffered *self);
    647 static PyObject *
    648 _bufferedreader_read_all(buffered *self);
    649 static PyObject *
    650 _bufferedreader_read_fast(buffered *self, Py_ssize_t);
    651 static PyObject *
    652 _bufferedreader_read_generic(buffered *self, Py_ssize_t);
    653 static Py_ssize_t
    654 _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
    655 
    656 /*
    657  * Helpers
    658  */
    659 
    660 /* Sets the current error to BlockingIOError */
    661 static void
    662 _set_BlockingIOError(const char *msg, Py_ssize_t written)
    663 {
    664     PyObject *err;
    665     PyErr_Clear();
    666     err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
    667                                 errno, msg, written);
    668     if (err)
    669         PyErr_SetObject(PyExc_BlockingIOError, err);
    670     Py_XDECREF(err);
    671 }
    672 
    673 /* Returns the address of the `written` member if a BlockingIOError was
    674    raised, NULL otherwise. The error is always re-raised. */
    675 static Py_ssize_t *
    676 _buffered_check_blocking_error(void)
    677 {
    678     PyObject *t, *v, *tb;
    679     PyOSErrorObject *err;
    680 
    681     PyErr_Fetch(&t, &v, &tb);
    682     if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
    683         PyErr_Restore(t, v, tb);
    684         return NULL;
    685     }
    686     err = (PyOSErrorObject *) v;
    687     /* TODO: sanity check (err->written >= 0) */
    688     PyErr_Restore(t, v, tb);
    689     return &err->written;
    690 }
    691 
    692 static Py_off_t
    693 _buffered_raw_tell(buffered *self)
    694 {
    695     Py_off_t n;
    696     PyObject *res;
    697     res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
    698     if (res == NULL)
    699         return -1;
    700     n = PyNumber_AsOff_t(res, PyExc_ValueError);
    701     Py_DECREF(res);
    702     if (n < 0) {
    703         if (!PyErr_Occurred())
    704             PyErr_Format(PyExc_IOError,
    705                          "Raw stream returned invalid position %" PY_PRIdOFF,
    706                          (PY_OFF_T_COMPAT)n);
    707         return -1;
    708     }
    709     self->abs_pos = n;
    710     return n;
    711 }
    712 
    713 static Py_off_t
    714 _buffered_raw_seek(buffered *self, Py_off_t target, int whence)
    715 {
    716     PyObject *res, *posobj, *whenceobj;
    717     Py_off_t n;
    718 
    719     posobj = PyLong_FromOff_t(target);
    720     if (posobj == NULL)
    721         return -1;
    722     whenceobj = PyLong_FromLong(whence);
    723     if (whenceobj == NULL) {
    724         Py_DECREF(posobj);
    725         return -1;
    726     }
    727     res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
    728                                      posobj, whenceobj, NULL);
    729     Py_DECREF(posobj);
    730     Py_DECREF(whenceobj);
    731     if (res == NULL)
    732         return -1;
    733     n = PyNumber_AsOff_t(res, PyExc_ValueError);
    734     Py_DECREF(res);
    735     if (n < 0) {
    736         if (!PyErr_Occurred())
    737             PyErr_Format(PyExc_IOError,
    738                          "Raw stream returned invalid position %" PY_PRIdOFF,
    739                          (PY_OFF_T_COMPAT)n);
    740         return -1;
    741     }
    742     self->abs_pos = n;
    743     return n;
    744 }
    745 
    746 static int
    747 _buffered_init(buffered *self)
    748 {
    749     Py_ssize_t n;
    750     if (self->buffer_size <= 0) {
    751         PyErr_SetString(PyExc_ValueError,
    752             "buffer size must be strictly positive");
    753         return -1;
    754     }
    755     if (self->buffer)
    756         PyMem_Free(self->buffer);
    757     self->buffer = PyMem_Malloc(self->buffer_size);
    758     if (self->buffer == NULL) {
    759         PyErr_NoMemory();
    760         return -1;
    761     }
    762 #ifdef WITH_THREAD
    763     if (self->lock)
    764         PyThread_free_lock(self->lock);
    765     self->lock = PyThread_allocate_lock();
    766     if (self->lock == NULL) {
    767         PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
    768         return -1;
    769     }
    770     self->owner = 0;
    771 #endif
    772     /* Find out whether buffer_size is a power of 2 */
    773     /* XXX is this optimization useful? */
    774     for (n = self->buffer_size - 1; n & 1; n >>= 1)
    775         ;
    776     if (n == 0)
    777         self->buffer_mask = self->buffer_size - 1;
    778     else
    779         self->buffer_mask = 0;
    780     if (_buffered_raw_tell(self) == -1)
    781         PyErr_Clear();
    782     return 0;
    783 }
    784 
    785 /* Return 1 if an EnvironmentError with errno == EINTR is set (and then
    786    clears the error indicator), 0 otherwise.
    787    Should only be called when PyErr_Occurred() is true.
    788 */
    789 int
    790 _PyIO_trap_eintr(void)
    791 {
    792     static PyObject *eintr_int = NULL;
    793     PyObject *typ, *val, *tb;
    794     PyEnvironmentErrorObject *env_err;
    795 
    796     if (eintr_int == NULL) {
    797         eintr_int = PyLong_FromLong(EINTR);
    798         assert(eintr_int != NULL);
    799     }
    800     if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
    801         return 0;
    802     PyErr_Fetch(&typ, &val, &tb);
    803     PyErr_NormalizeException(&typ, &val, &tb);
    804     env_err = (PyEnvironmentErrorObject *) val;
    805     assert(env_err != NULL);
    806     if (env_err->myerrno != NULL &&
    807         PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
    808         Py_DECREF(typ);
    809         Py_DECREF(val);
    810         Py_XDECREF(tb);
    811         return 1;
    812     }
    813     /* This silences any error set by PyObject_RichCompareBool() */
    814     PyErr_Restore(typ, val, tb);
    815     return 0;
    816 }
    817 
    818 /*
    819  * Shared methods and wrappers
    820  */
    821 
    822 static PyObject *
    823 buffered_flush_and_rewind_unlocked(buffered *self)
    824 {
    825     PyObject *res;
    826 
    827     res = _bufferedwriter_flush_unlocked(self);
    828     if (res == NULL)
    829         return NULL;
    830     Py_DECREF(res);
    831 
    832     if (self->readable) {
    833         /* Rewind the raw stream so that its position corresponds to
    834            the current logical position. */
    835         Py_off_t n;
    836         n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
    837         _bufferedreader_reset_buf(self);
    838         if (n == -1)
    839             return NULL;
    840     }
    841     Py_RETURN_NONE;
    842 }
    843 
    844 static PyObject *
    845 buffered_flush(buffered *self, PyObject *args)
    846 {
    847     PyObject *res;
    848 
    849     CHECK_INITIALIZED(self)
    850     CHECK_CLOSED(self, "flush of closed file")
    851 
    852     if (!ENTER_BUFFERED(self))
    853         return NULL;
    854     res = buffered_flush_and_rewind_unlocked(self);
    855     LEAVE_BUFFERED(self)
    856 
    857     return res;
    858 }
    859 
    860 /*[clinic input]
    861 _io._Buffered.peek
    862     size: Py_ssize_t = 0
    863     /
    864 
    865 [clinic start generated code]*/
    866 
    867 static PyObject *
    868 _io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
    869 /*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
    870 {
    871     PyObject *res = NULL;
    872 
    873     CHECK_INITIALIZED(self)
    874     CHECK_CLOSED(self, "peek of closed file")
    875 
    876     if (!ENTER_BUFFERED(self))
    877         return NULL;
    878 
    879     if (self->writable) {
    880         res = buffered_flush_and_rewind_unlocked(self);
    881         if (res == NULL)
    882             goto end;
    883         Py_CLEAR(res);
    884     }
    885     res = _bufferedreader_peek_unlocked(self);
    886 
    887 end:
    888     LEAVE_BUFFERED(self)
    889     return res;
    890 }
    891 
    892 /*[clinic input]
    893 _io._Buffered.read
    894     size as n: io_ssize_t = -1
    895     /
    896 [clinic start generated code]*/
    897 
    898 static PyObject *
    899 _io__Buffered_read_impl(buffered *self, Py_ssize_t n)
    900 /*[clinic end generated code: output=f41c78bb15b9bbe9 input=c0939ec7f9e9354f]*/
    901 {
    902     PyObject *res;
    903 
    904     CHECK_INITIALIZED(self)
    905     if (n < -1) {
    906         PyErr_SetString(PyExc_ValueError,
    907                         "read length must be positive or -1");
    908         return NULL;
    909     }
    910 
    911     CHECK_CLOSED(self, "read of closed file")
    912 
    913     if (n == -1) {
    914         /* The number of bytes is unspecified, read until the end of stream */
    915         if (!ENTER_BUFFERED(self))
    916             return NULL;
    917         res = _bufferedreader_read_all(self);
    918     }
    919     else {
    920         res = _bufferedreader_read_fast(self, n);
    921         if (res != Py_None)
    922             return res;
    923         Py_DECREF(res);
    924         if (!ENTER_BUFFERED(self))
    925             return NULL;
    926         res = _bufferedreader_read_generic(self, n);
    927     }
    928 
    929     LEAVE_BUFFERED(self)
    930     return res;
    931 }
    932 
    933 /*[clinic input]
    934 _io._Buffered.read1
    935     size as n: Py_ssize_t
    936     /
    937 [clinic start generated code]*/
    938 
    939 static PyObject *
    940 _io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
    941 /*[clinic end generated code: output=bcc4fb4e54d103a3 input=8d2869c18b983184]*/
    942 {
    943     Py_ssize_t have, r;
    944     PyObject *res = NULL;
    945 
    946     CHECK_INITIALIZED(self)
    947     if (n < 0) {
    948         PyErr_SetString(PyExc_ValueError,
    949                         "read length must be positive");
    950         return NULL;
    951     }
    952 
    953     CHECK_CLOSED(self, "read of closed file")
    954 
    955     if (n == 0)
    956         return PyBytes_FromStringAndSize(NULL, 0);
    957 
    958     /* Return up to n bytes.  If at least one byte is buffered, we
    959        only return buffered bytes.  Otherwise, we do one raw read. */
    960 
    961     have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
    962     if (have > 0) {
    963         n = Py_MIN(have, n);
    964         res = _bufferedreader_read_fast(self, n);
    965         assert(res != Py_None);
    966         return res;
    967     }
    968     res = PyBytes_FromStringAndSize(NULL, n);
    969     if (res == NULL)
    970         return NULL;
    971     if (!ENTER_BUFFERED(self)) {
    972         Py_DECREF(res);
    973         return NULL;
    974     }
    975     _bufferedreader_reset_buf(self);
    976     r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
    977     LEAVE_BUFFERED(self)
    978     if (r == -1) {
    979         Py_DECREF(res);
    980         return NULL;
    981     }
    982     if (r == -2)
    983         r = 0;
    984     if (n > r)
    985         _PyBytes_Resize(&res, r);
    986     return res;
    987 }
    988 
    989 static PyObject *
    990 _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
    991 {
    992     Py_ssize_t n, written = 0, remaining;
    993     PyObject *res = NULL;
    994 
    995     CHECK_INITIALIZED(self)
    996 
    997     n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
    998     if (n > 0) {
    999         if (n >= buffer->len) {
   1000             memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
   1001             self->pos += buffer->len;
   1002             return PyLong_FromSsize_t(buffer->len);
   1003         }
   1004         memcpy(buffer->buf, self->buffer + self->pos, n);
   1005         self->pos += n;
   1006         written = n;
   1007     }
   1008 
   1009     if (!ENTER_BUFFERED(self))
   1010         return NULL;
   1011 
   1012     if (self->writable) {
   1013         res = buffered_flush_and_rewind_unlocked(self);
   1014         if (res == NULL)
   1015             goto end;
   1016         Py_CLEAR(res);
   1017     }
   1018 
   1019     _bufferedreader_reset_buf(self);
   1020     self->pos = 0;
   1021 
   1022     for (remaining = buffer->len - written;
   1023          remaining > 0;
   1024          written += n, remaining -= n) {
   1025         /* If remaining bytes is larger than internal buffer size, copy
   1026          * directly into caller's buffer. */
   1027         if (remaining > self->buffer_size) {
   1028             n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
   1029                                          remaining);
   1030         }
   1031 
   1032         /* In readinto1 mode, we do not want to fill the internal
   1033            buffer if we already have some data to return */
   1034         else if (!(readinto1 && written)) {
   1035             n = _bufferedreader_fill_buffer(self);
   1036             if (n > 0) {
   1037                 if (n > remaining)
   1038                     n = remaining;
   1039                 memcpy((char *) buffer->buf + written,
   1040                        self->buffer + self->pos, n);
   1041                 self->pos += n;
   1042                 continue; /* short circuit */
   1043             }
   1044         }
   1045         else
   1046             n = 0;
   1047 
   1048         if (n == 0 || (n == -2 && written > 0))
   1049             break;
   1050         if (n < 0) {
   1051             if (n == -2) {
   1052                 Py_INCREF(Py_None);
   1053                 res = Py_None;
   1054             }
   1055             goto end;
   1056         }
   1057 
   1058         /* At most one read in readinto1 mode */
   1059         if (readinto1) {
   1060             written += n;
   1061             break;
   1062         }
   1063     }
   1064     res = PyLong_FromSsize_t(written);
   1065 
   1066 end:
   1067     LEAVE_BUFFERED(self);
   1068     return res;
   1069 }
   1070 
   1071 /*[clinic input]
   1072 _io._Buffered.readinto
   1073     buffer: Py_buffer(accept={rwbuffer})
   1074     /
   1075 [clinic start generated code]*/
   1076 
   1077 static PyObject *
   1078 _io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
   1079 /*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
   1080 {
   1081     return _buffered_readinto_generic(self, buffer, 0);
   1082 }
   1083 
   1084 /*[clinic input]
   1085 _io._Buffered.readinto1
   1086     buffer: Py_buffer(accept={rwbuffer})
   1087     /
   1088 [clinic start generated code]*/
   1089 
   1090 static PyObject *
   1091 _io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
   1092 /*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
   1093 {
   1094     return _buffered_readinto_generic(self, buffer, 1);
   1095 }
   1096 
   1097 
   1098 static PyObject *
   1099 _buffered_readline(buffered *self, Py_ssize_t limit)
   1100 {
   1101     PyObject *res = NULL;
   1102     PyObject *chunks = NULL;
   1103     Py_ssize_t n, written = 0;
   1104     const char *start, *s, *end;
   1105 
   1106     CHECK_CLOSED(self, "readline of closed file")
   1107 
   1108     /* First, try to find a line in the buffer. This can run unlocked because
   1109        the calls to the C API are simple enough that they can't trigger
   1110        any thread switch. */
   1111     n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
   1112     if (limit >= 0 && n > limit)
   1113         n = limit;
   1114     start = self->buffer + self->pos;
   1115     s = memchr(start, '\n', n);
   1116     if (s != NULL) {
   1117         res = PyBytes_FromStringAndSize(start, s - start + 1);
   1118         if (res != NULL)
   1119             self->pos += s - start + 1;
   1120         goto end_unlocked;
   1121     }
   1122     if (n == limit) {
   1123         res = PyBytes_FromStringAndSize(start, n);
   1124         if (res != NULL)
   1125             self->pos += n;
   1126         goto end_unlocked;
   1127     }
   1128 
   1129     if (!ENTER_BUFFERED(self))
   1130         goto end_unlocked;
   1131 
   1132     /* Now we try to get some more from the raw stream */
   1133     chunks = PyList_New(0);
   1134     if (chunks == NULL)
   1135         goto end;
   1136     if (n > 0) {
   1137         res = PyBytes_FromStringAndSize(start, n);
   1138         if (res == NULL)
   1139             goto end;
   1140         if (PyList_Append(chunks, res) < 0) {
   1141             Py_CLEAR(res);
   1142             goto end;
   1143         }
   1144         Py_CLEAR(res);
   1145         written += n;
   1146         self->pos += n;
   1147         if (limit >= 0)
   1148             limit -= n;
   1149     }
   1150     if (self->writable) {
   1151         PyObject *r = buffered_flush_and_rewind_unlocked(self);
   1152         if (r == NULL)
   1153             goto end;
   1154         Py_DECREF(r);
   1155     }
   1156 
   1157     for (;;) {
   1158         _bufferedreader_reset_buf(self);
   1159         n = _bufferedreader_fill_buffer(self);
   1160         if (n == -1)
   1161             goto end;
   1162         if (n <= 0)
   1163             break;
   1164         if (limit >= 0 && n > limit)
   1165             n = limit;
   1166         start = self->buffer;
   1167         end = start + n;
   1168         s = start;
   1169         while (s < end) {
   1170             if (*s++ == '\n') {
   1171                 res = PyBytes_FromStringAndSize(start, s - start);
   1172                 if (res == NULL)
   1173                     goto end;
   1174                 self->pos = s - start;
   1175                 goto found;
   1176             }
   1177         }
   1178         res = PyBytes_FromStringAndSize(start, n);
   1179         if (res == NULL)
   1180             goto end;
   1181         if (n == limit) {
   1182             self->pos = n;
   1183             break;
   1184         }
   1185         if (PyList_Append(chunks, res) < 0) {
   1186             Py_CLEAR(res);
   1187             goto end;
   1188         }
   1189         Py_CLEAR(res);
   1190         written += n;
   1191         if (limit >= 0)
   1192             limit -= n;
   1193     }
   1194 found:
   1195     if (res != NULL && PyList_Append(chunks, res) < 0) {
   1196         Py_CLEAR(res);
   1197         goto end;
   1198     }
   1199     Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
   1200 
   1201 end:
   1202     LEAVE_BUFFERED(self)
   1203 end_unlocked:
   1204     Py_XDECREF(chunks);
   1205     return res;
   1206 }
   1207 
   1208 /*[clinic input]
   1209 _io._Buffered.readline
   1210     size: io_ssize_t = -1
   1211     /
   1212 [clinic start generated code]*/
   1213 
   1214 static PyObject *
   1215 _io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
   1216 /*[clinic end generated code: output=24dd2aa6e33be83c input=ff1e0df821cb4e5c]*/
   1217 {
   1218     CHECK_INITIALIZED(self)
   1219     return _buffered_readline(self, size);
   1220 }
   1221 
   1222 
   1223 static PyObject *
   1224 buffered_tell(buffered *self, PyObject *args)
   1225 {
   1226     Py_off_t pos;
   1227 
   1228     CHECK_INITIALIZED(self)
   1229     pos = _buffered_raw_tell(self);
   1230     if (pos == -1)
   1231         return NULL;
   1232     pos -= RAW_OFFSET(self);
   1233     /* TODO: sanity check (pos >= 0) */
   1234     return PyLong_FromOff_t(pos);
   1235 }
   1236 
   1237 /*[clinic input]
   1238 _io._Buffered.seek
   1239     target as targetobj: object
   1240     whence: int = 0
   1241     /
   1242 [clinic start generated code]*/
   1243 
   1244 static PyObject *
   1245 _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
   1246 /*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
   1247 {
   1248     Py_off_t target, n;
   1249     PyObject *res = NULL;
   1250 
   1251     CHECK_INITIALIZED(self)
   1252 
   1253     /* Do some error checking instead of trusting OS 'seek()'
   1254     ** error detection, just in case.
   1255     */
   1256     if ((whence < 0 || whence >2)
   1257 #ifdef SEEK_HOLE
   1258         && (whence != SEEK_HOLE)
   1259 #endif
   1260 #ifdef SEEK_DATA
   1261         && (whence != SEEK_DATA)
   1262 #endif
   1263         ) {
   1264         PyErr_Format(PyExc_ValueError,
   1265                      "whence value %d unsupported", whence);
   1266         return NULL;
   1267     }
   1268 
   1269     CHECK_CLOSED(self, "seek of closed file")
   1270 
   1271     if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
   1272         return NULL;
   1273 
   1274     target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
   1275     if (target == -1 && PyErr_Occurred())
   1276         return NULL;
   1277 
   1278     /* SEEK_SET and SEEK_CUR are special because we could seek inside the
   1279        buffer. Other whence values must be managed without this optimization.
   1280        Some Operating Systems can provide additional values, like
   1281        SEEK_HOLE/SEEK_DATA. */
   1282     if (((whence == 0) || (whence == 1)) && self->readable) {
   1283         Py_off_t current, avail;
   1284         /* Check if seeking leaves us inside the current buffer,
   1285            so as to return quickly if possible. Also, we needn't take the
   1286            lock in this fast path.
   1287            Don't know how to do that when whence == 2, though. */
   1288         /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
   1289            state at this point. */
   1290         current = RAW_TELL(self);
   1291         avail = READAHEAD(self);
   1292         if (avail > 0) {
   1293             Py_off_t offset;
   1294             if (whence == 0)
   1295                 offset = target - (current - RAW_OFFSET(self));
   1296             else
   1297                 offset = target;
   1298             if (offset >= -self->pos && offset <= avail) {
   1299                 self->pos += offset;
   1300                 return PyLong_FromOff_t(current - avail + offset);
   1301             }
   1302         }
   1303     }
   1304 
   1305     if (!ENTER_BUFFERED(self))
   1306         return NULL;
   1307 
   1308     /* Fallback: invoke raw seek() method and clear buffer */
   1309     if (self->writable) {
   1310         res = _bufferedwriter_flush_unlocked(self);
   1311         if (res == NULL)
   1312             goto end;
   1313         Py_CLEAR(res);
   1314         _bufferedwriter_reset_buf(self);
   1315     }
   1316 
   1317     /* TODO: align on block boundary and read buffer if needed? */
   1318     if (whence == 1)
   1319         target -= RAW_OFFSET(self);
   1320     n = _buffered_raw_seek(self, target, whence);
   1321     if (n == -1)
   1322         goto end;
   1323     self->raw_pos = -1;
   1324     res = PyLong_FromOff_t(n);
   1325     if (res != NULL && self->readable)
   1326         _bufferedreader_reset_buf(self);
   1327 
   1328 end:
   1329     LEAVE_BUFFERED(self)
   1330     return res;
   1331 }
   1332 
   1333 /*[clinic input]
   1334 _io._Buffered.truncate
   1335     pos: object = None
   1336     /
   1337 [clinic start generated code]*/
   1338 
   1339 static PyObject *
   1340 _io__Buffered_truncate_impl(buffered *self, PyObject *pos)
   1341 /*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
   1342 {
   1343     PyObject *res = NULL;
   1344 
   1345     CHECK_INITIALIZED(self)
   1346     if (!ENTER_BUFFERED(self))
   1347         return NULL;
   1348 
   1349     if (self->writable) {
   1350         res = buffered_flush_and_rewind_unlocked(self);
   1351         if (res == NULL)
   1352             goto end;
   1353         Py_CLEAR(res);
   1354     }
   1355     res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
   1356     if (res == NULL)
   1357         goto end;
   1358     /* Reset cached position */
   1359     if (_buffered_raw_tell(self) == -1)
   1360         PyErr_Clear();
   1361 
   1362 end:
   1363     LEAVE_BUFFERED(self)
   1364     return res;
   1365 }
   1366 
   1367 static PyObject *
   1368 buffered_iternext(buffered *self)
   1369 {
   1370     PyObject *line;
   1371     PyTypeObject *tp;
   1372 
   1373     CHECK_INITIALIZED(self);
   1374 
   1375     tp = Py_TYPE(self);
   1376     if (tp == &PyBufferedReader_Type ||
   1377         tp == &PyBufferedRandom_Type) {
   1378         /* Skip method call overhead for speed */
   1379         line = _buffered_readline(self, -1);
   1380     }
   1381     else {
   1382         line = PyObject_CallMethodObjArgs((PyObject *)self,
   1383                                            _PyIO_str_readline, NULL);
   1384         if (line && !PyBytes_Check(line)) {
   1385             PyErr_Format(PyExc_IOError,
   1386                          "readline() should have returned a bytes object, "
   1387                          "not '%.200s'", Py_TYPE(line)->tp_name);
   1388             Py_DECREF(line);
   1389             return NULL;
   1390         }
   1391     }
   1392 
   1393     if (line == NULL)
   1394         return NULL;
   1395 
   1396     if (PyBytes_GET_SIZE(line) == 0) {
   1397         /* Reached EOF or would have blocked */
   1398         Py_DECREF(line);
   1399         return NULL;
   1400     }
   1401 
   1402     return line;
   1403 }
   1404 
   1405 static PyObject *
   1406 buffered_repr(buffered *self)
   1407 {
   1408     PyObject *nameobj, *res;
   1409 
   1410     nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
   1411     if (nameobj == NULL) {
   1412         if (PyErr_ExceptionMatches(PyExc_Exception))
   1413             PyErr_Clear();
   1414         else
   1415             return NULL;
   1416         res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
   1417     }
   1418     else {
   1419         res = PyUnicode_FromFormat("<%s name=%R>",
   1420                                    Py_TYPE(self)->tp_name, nameobj);
   1421         Py_DECREF(nameobj);
   1422     }
   1423     return res;
   1424 }
   1425 
   1426 /*
   1427  * class BufferedReader
   1428  */
   1429 
   1430 static void _bufferedreader_reset_buf(buffered *self)
   1431 {
   1432     self->read_end = -1;
   1433 }
   1434 
   1435 /*[clinic input]
   1436 _io.BufferedReader.__init__
   1437     raw: object
   1438     buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
   1439 
   1440 Create a new buffered reader using the given readable raw IO object.
   1441 [clinic start generated code]*/
   1442 
   1443 static int
   1444 _io_BufferedReader___init___impl(buffered *self, PyObject *raw,
   1445                                  Py_ssize_t buffer_size)
   1446 /*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
   1447 {
   1448     self->ok = 0;
   1449     self->detached = 0;
   1450 
   1451     if (_PyIOBase_check_readable(raw, Py_True) == NULL)
   1452         return -1;
   1453 
   1454     Py_INCREF(raw);
   1455     Py_XSETREF(self->raw, raw);
   1456     self->buffer_size = buffer_size;
   1457     self->readable = 1;
   1458     self->writable = 0;
   1459 
   1460     if (_buffered_init(self) < 0)
   1461         return -1;
   1462     _bufferedreader_reset_buf(self);
   1463 
   1464     self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
   1465                                 Py_TYPE(raw) == &PyFileIO_Type);
   1466 
   1467     self->ok = 1;
   1468     return 0;
   1469 }
   1470 
   1471 static Py_ssize_t
   1472 _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
   1473 {
   1474     Py_buffer buf;
   1475     PyObject *memobj, *res;
   1476     Py_ssize_t n;
   1477     /* NOTE: the buffer needn't be released as its object is NULL. */
   1478     if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
   1479         return -1;
   1480     memobj = PyMemoryView_FromBuffer(&buf);
   1481     if (memobj == NULL)
   1482         return -1;
   1483     /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
   1484        occurs so we needn't do it ourselves.
   1485        We then retry reading, ignoring the signal if no handler has
   1486        raised (see issue #10956).
   1487     */
   1488     do {
   1489         res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
   1490     } while (res == NULL && _PyIO_trap_eintr());
   1491     Py_DECREF(memobj);
   1492     if (res == NULL)
   1493         return -1;
   1494     if (res == Py_None) {
   1495         /* Non-blocking stream would have blocked. Special return code! */
   1496         Py_DECREF(res);
   1497         return -2;
   1498     }
   1499     n = PyNumber_AsSsize_t(res, PyExc_ValueError);
   1500     Py_DECREF(res);
   1501     if (n < 0 || n > len) {
   1502         PyErr_Format(PyExc_IOError,
   1503                      "raw readinto() returned invalid length %zd "
   1504                      "(should have been between 0 and %zd)", n, len);
   1505         return -1;
   1506     }
   1507     if (n > 0 && self->abs_pos != -1)
   1508         self->abs_pos += n;
   1509     return n;
   1510 }
   1511 
   1512 static Py_ssize_t
   1513 _bufferedreader_fill_buffer(buffered *self)
   1514 {
   1515     Py_ssize_t start, len, n;
   1516     if (VALID_READ_BUFFER(self))
   1517         start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
   1518     else
   1519         start = 0;
   1520     len = self->buffer_size - start;
   1521     n = _bufferedreader_raw_read(self, self->buffer + start, len);
   1522     if (n <= 0)
   1523         return n;
   1524     self->read_end = start + n;
   1525     self->raw_pos = start + n;
   1526     return n;
   1527 }
   1528 
   1529 static PyObject *
   1530 _bufferedreader_read_all(buffered *self)
   1531 {
   1532     Py_ssize_t current_size;
   1533     PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
   1534 
   1535     /* First copy what we have in the current buffer. */
   1536     current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
   1537     if (current_size) {
   1538         data = PyBytes_FromStringAndSize(
   1539             self->buffer + self->pos, current_size);
   1540         if (data == NULL)
   1541             return NULL;
   1542         self->pos += current_size;
   1543     }
   1544     /* We're going past the buffer's bounds, flush it */
   1545     if (self->writable) {
   1546         tmp = buffered_flush_and_rewind_unlocked(self);
   1547         if (tmp == NULL)
   1548             goto cleanup;
   1549         Py_CLEAR(tmp);
   1550     }
   1551     _bufferedreader_reset_buf(self);
   1552 
   1553     if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
   1554         tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
   1555         if (tmp == NULL)
   1556             goto cleanup;
   1557         if (tmp != Py_None && !PyBytes_Check(tmp)) {
   1558             PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
   1559             goto cleanup;
   1560         }
   1561         if (tmp == Py_None) {
   1562             if (current_size == 0) {
   1563                 res = Py_None;
   1564                 goto cleanup;
   1565             } else {
   1566                 res = data;
   1567                 goto cleanup;
   1568             }
   1569         }
   1570         else if (current_size) {
   1571             PyBytes_Concat(&data, tmp);
   1572             res = data;
   1573             goto cleanup;
   1574         }
   1575         else {
   1576             res = tmp;
   1577             goto cleanup;
   1578         }
   1579     }
   1580 
   1581     chunks = PyList_New(0);
   1582     if (chunks == NULL)
   1583         goto cleanup;
   1584 
   1585     while (1) {
   1586         if (data) {
   1587             if (PyList_Append(chunks, data) < 0)
   1588                 goto cleanup;
   1589             Py_CLEAR(data);
   1590         }
   1591 
   1592         /* Read until EOF or until read() would block. */
   1593         data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
   1594         if (data == NULL)
   1595             goto cleanup;
   1596         if (data != Py_None && !PyBytes_Check(data)) {
   1597             PyErr_SetString(PyExc_TypeError, "read() should return bytes");
   1598             goto cleanup;
   1599         }
   1600         if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
   1601             if (current_size == 0) {
   1602                 res = data;
   1603                 goto cleanup;
   1604             }
   1605             else {
   1606                 tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
   1607                 res = tmp;
   1608                 goto cleanup;
   1609             }
   1610         }
   1611         current_size += PyBytes_GET_SIZE(data);
   1612         if (self->abs_pos != -1)
   1613             self->abs_pos += PyBytes_GET_SIZE(data);
   1614     }
   1615 cleanup:
   1616     /* res is either NULL or a borrowed ref */
   1617     Py_XINCREF(res);
   1618     Py_XDECREF(data);
   1619     Py_XDECREF(tmp);
   1620     Py_XDECREF(chunks);
   1621     return res;
   1622 }
   1623 
   1624 /* Read n bytes from the buffer if it can, otherwise return None.
   1625    This function is simple enough that it can run unlocked. */
   1626 static PyObject *
   1627 _bufferedreader_read_fast(buffered *self, Py_ssize_t n)
   1628 {
   1629     Py_ssize_t current_size;
   1630 
   1631     current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
   1632     if (n <= current_size) {
   1633         /* Fast path: the data to read is fully buffered. */
   1634         PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
   1635         if (res != NULL)
   1636             self->pos += n;
   1637         return res;
   1638     }
   1639     Py_RETURN_NONE;
   1640 }
   1641 
   1642 /* Generic read function: read from the stream until enough bytes are read,
   1643  * or until an EOF occurs or until read() would block.
   1644  */
   1645 static PyObject *
   1646 _bufferedreader_read_generic(buffered *self, Py_ssize_t n)
   1647 {
   1648     PyObject *res = NULL;
   1649     Py_ssize_t current_size, remaining, written;
   1650     char *out;
   1651 
   1652     current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
   1653     if (n <= current_size)
   1654         return _bufferedreader_read_fast(self, n);
   1655 
   1656     res = PyBytes_FromStringAndSize(NULL, n);
   1657     if (res == NULL)
   1658         goto error;
   1659     out = PyBytes_AS_STRING(res);
   1660     remaining = n;
   1661     written = 0;
   1662     if (current_size > 0) {
   1663         memcpy(out, self->buffer + self->pos, current_size);
   1664         remaining -= current_size;
   1665         written += current_size;
   1666         self->pos += current_size;
   1667     }
   1668     /* Flush the write buffer if necessary */
   1669     if (self->writable) {
   1670         PyObject *r = buffered_flush_and_rewind_unlocked(self);
   1671         if (r == NULL)
   1672             goto error;
   1673         Py_DECREF(r);
   1674     }
   1675     _bufferedreader_reset_buf(self);
   1676     while (remaining > 0) {
   1677         /* We want to read a whole block at the end into buffer.
   1678            If we had readv() we could do this in one pass. */
   1679         Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
   1680         if (r == 0)
   1681             break;
   1682         r = _bufferedreader_raw_read(self, out + written, r);
   1683         if (r == -1)
   1684             goto error;
   1685         if (r == 0 || r == -2) {
   1686             /* EOF occurred or read() would block. */
   1687             if (r == 0 || written > 0) {
   1688                 if (_PyBytes_Resize(&res, written))
   1689                     goto error;
   1690                 return res;
   1691             }
   1692             Py_DECREF(res);
   1693             Py_INCREF(Py_None);
   1694             return Py_None;
   1695         }
   1696         remaining -= r;
   1697         written += r;
   1698     }
   1699     assert(remaining <= self->buffer_size);
   1700     self->pos = 0;
   1701     self->raw_pos = 0;
   1702     self->read_end = 0;
   1703     /* NOTE: when the read is satisfied, we avoid issuing any additional
   1704        reads, which could block indefinitely (e.g. on a socket).
   1705        See issue #9550. */
   1706     while (remaining > 0 && self->read_end < self->buffer_size) {
   1707         Py_ssize_t r = _bufferedreader_fill_buffer(self);
   1708         if (r == -1)
   1709             goto error;
   1710         if (r == 0 || r == -2) {
   1711             /* EOF occurred or read() would block. */
   1712             if (r == 0 || written > 0) {
   1713                 if (_PyBytes_Resize(&res, written))
   1714                     goto error;
   1715                 return res;
   1716             }
   1717             Py_DECREF(res);
   1718             Py_INCREF(Py_None);
   1719             return Py_None;
   1720         }
   1721         if (remaining > r) {
   1722             memcpy(out + written, self->buffer + self->pos, r);
   1723             written += r;
   1724             self->pos += r;
   1725             remaining -= r;
   1726         }
   1727         else if (remaining > 0) {
   1728             memcpy(out + written, self->buffer + self->pos, remaining);
   1729             written += remaining;
   1730             self->pos += remaining;
   1731             remaining = 0;
   1732         }
   1733         if (remaining == 0)
   1734             break;
   1735     }
   1736 
   1737     return res;
   1738 
   1739 error:
   1740     Py_XDECREF(res);
   1741     return NULL;
   1742 }
   1743 
   1744 static PyObject *
   1745 _bufferedreader_peek_unlocked(buffered *self)
   1746 {
   1747     Py_ssize_t have, r;
   1748 
   1749     have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
   1750     /* Constraints:
   1751        1. we don't want to advance the file position.
   1752        2. we don't want to lose block alignment, so we can't shift the buffer
   1753           to make some place.
   1754        Therefore, we either return `have` bytes (if > 0), or a full buffer.
   1755     */
   1756     if (have > 0) {
   1757         return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
   1758     }
   1759 
   1760     /* Fill the buffer from the raw stream, and copy it to the result. */
   1761     _bufferedreader_reset_buf(self);
   1762     r = _bufferedreader_fill_buffer(self);
   1763     if (r == -1)
   1764         return NULL;
   1765     if (r == -2)
   1766         r = 0;
   1767     self->pos = 0;
   1768     return PyBytes_FromStringAndSize(self->buffer, r);
   1769 }
   1770 
   1771 
   1773 
   1774 /*
   1775  * class BufferedWriter
   1776  */
   1777 static void
   1778 _bufferedwriter_reset_buf(buffered *self)
   1779 {
   1780     self->write_pos = 0;
   1781     self->write_end = -1;
   1782 }
   1783 
   1784 /*[clinic input]
   1785 _io.BufferedWriter.__init__
   1786     raw: object
   1787     buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
   1788 
   1789 A buffer for a writeable sequential RawIO object.
   1790 
   1791 The constructor creates a BufferedWriter for the given writeable raw
   1792 stream. If the buffer_size is not given, it defaults to
   1793 DEFAULT_BUFFER_SIZE.
   1794 [clinic start generated code]*/
   1795 
   1796 static int
   1797 _io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
   1798                                  Py_ssize_t buffer_size)
   1799 /*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
   1800 {
   1801     self->ok = 0;
   1802     self->detached = 0;
   1803 
   1804     if (_PyIOBase_check_writable(raw, Py_True) == NULL)
   1805         return -1;
   1806 
   1807     Py_INCREF(raw);
   1808     Py_XSETREF(self->raw, raw);
   1809     self->readable = 0;
   1810     self->writable = 1;
   1811 
   1812     self->buffer_size = buffer_size;
   1813     if (_buffered_init(self) < 0)
   1814         return -1;
   1815     _bufferedwriter_reset_buf(self);
   1816     self->pos = 0;
   1817 
   1818     self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
   1819                                 Py_TYPE(raw) == &PyFileIO_Type);
   1820 
   1821     self->ok = 1;
   1822     return 0;
   1823 }
   1824 
   1825 static Py_ssize_t
   1826 _bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
   1827 {
   1828     Py_buffer buf;
   1829     PyObject *memobj, *res;
   1830     Py_ssize_t n;
   1831     int errnum;
   1832     /* NOTE: the buffer needn't be released as its object is NULL. */
   1833     if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
   1834         return -1;
   1835     memobj = PyMemoryView_FromBuffer(&buf);
   1836     if (memobj == NULL)
   1837         return -1;
   1838     /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
   1839        occurs so we needn't do it ourselves.
   1840        We then retry writing, ignoring the signal if no handler has
   1841        raised (see issue #10956).
   1842     */
   1843     do {
   1844         errno = 0;
   1845         res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
   1846         errnum = errno;
   1847     } while (res == NULL && _PyIO_trap_eintr());
   1848     Py_DECREF(memobj);
   1849     if (res == NULL)
   1850         return -1;
   1851     if (res == Py_None) {
   1852         /* Non-blocking stream would have blocked. Special return code!
   1853            Being paranoid we reset errno in case it is changed by code
   1854            triggered by a decref.  errno is used by _set_BlockingIOError(). */
   1855         Py_DECREF(res);
   1856         errno = errnum;
   1857         return -2;
   1858     }
   1859     n = PyNumber_AsSsize_t(res, PyExc_ValueError);
   1860     Py_DECREF(res);
   1861     if (n < 0 || n > len) {
   1862         PyErr_Format(PyExc_IOError,
   1863                      "raw write() returned invalid length %zd "
   1864                      "(should have been between 0 and %zd)", n, len);
   1865         return -1;
   1866     }
   1867     if (n > 0 && self->abs_pos != -1)
   1868         self->abs_pos += n;
   1869     return n;
   1870 }
   1871 
   1872 /* `restore_pos` is 1 if we need to restore the raw stream position at
   1873    the end, 0 otherwise. */
   1874 static PyObject *
   1875 _bufferedwriter_flush_unlocked(buffered *self)
   1876 {
   1877     Py_ssize_t written = 0;
   1878     Py_off_t n, rewind;
   1879 
   1880     if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
   1881         goto end;
   1882     /* First, rewind */
   1883     rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
   1884     if (rewind != 0) {
   1885         n = _buffered_raw_seek(self, -rewind, 1);
   1886         if (n < 0) {
   1887             goto error;
   1888         }
   1889         self->raw_pos -= rewind;
   1890     }
   1891     while (self->write_pos < self->write_end) {
   1892         n = _bufferedwriter_raw_write(self,
   1893             self->buffer + self->write_pos,
   1894             Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
   1895                              Py_off_t, Py_ssize_t));
   1896         if (n == -1) {
   1897             goto error;
   1898         }
   1899         else if (n == -2) {
   1900             _set_BlockingIOError("write could not complete without blocking",
   1901                                  0);
   1902             goto error;
   1903         }
   1904         self->write_pos += n;
   1905         self->raw_pos = self->write_pos;
   1906         written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
   1907         /* Partial writes can return successfully when interrupted by a
   1908            signal (see write(2)).  We must run signal handlers before
   1909            blocking another time, possibly indefinitely. */
   1910         if (PyErr_CheckSignals() < 0)
   1911             goto error;
   1912     }
   1913 
   1914     _bufferedwriter_reset_buf(self);
   1915 
   1916 end:
   1917     Py_RETURN_NONE;
   1918 
   1919 error:
   1920     return NULL;
   1921 }
   1922 
   1923 /*[clinic input]
   1924 _io.BufferedWriter.write
   1925     buffer: Py_buffer
   1926     /
   1927 [clinic start generated code]*/
   1928 
   1929 static PyObject *
   1930 _io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
   1931 /*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
   1932 {
   1933     PyObject *res = NULL;
   1934     Py_ssize_t written, avail, remaining;
   1935     Py_off_t offset;
   1936 
   1937     CHECK_INITIALIZED(self)
   1938     if (IS_CLOSED(self)) {
   1939         PyErr_SetString(PyExc_ValueError, "write to closed file");
   1940         return NULL;
   1941     }
   1942 
   1943     if (!ENTER_BUFFERED(self))
   1944         return NULL;
   1945 
   1946     /* Fast path: the data to write can be fully buffered. */
   1947     if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
   1948         self->pos = 0;
   1949         self->raw_pos = 0;
   1950     }
   1951     avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
   1952     if (buffer->len <= avail) {
   1953         memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
   1954         if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
   1955             self->write_pos = self->pos;
   1956         }
   1957         ADJUST_POSITION(self, self->pos + buffer->len);
   1958         if (self->pos > self->write_end)
   1959             self->write_end = self->pos;
   1960         written = buffer->len;
   1961         goto end;
   1962     }
   1963 
   1964     /* First write the current buffer */
   1965     res = _bufferedwriter_flush_unlocked(self);
   1966     if (res == NULL) {
   1967         Py_ssize_t *w = _buffered_check_blocking_error();
   1968         if (w == NULL)
   1969             goto error;
   1970         if (self->readable)
   1971             _bufferedreader_reset_buf(self);
   1972         /* Make some place by shifting the buffer. */
   1973         assert(VALID_WRITE_BUFFER(self));
   1974         memmove(self->buffer, self->buffer + self->write_pos,
   1975                 Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
   1976                                  Py_off_t, Py_ssize_t));
   1977         self->write_end -= self->write_pos;
   1978         self->raw_pos -= self->write_pos;
   1979         self->pos -= self->write_pos;
   1980         self->write_pos = 0;
   1981         avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
   1982                                  Py_off_t, Py_ssize_t);
   1983         if (buffer->len <= avail) {
   1984             /* Everything can be buffered */
   1985             PyErr_Clear();
   1986             memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
   1987             self->write_end += buffer->len;
   1988             self->pos += buffer->len;
   1989             written = buffer->len;
   1990             goto end;
   1991         }
   1992         /* Buffer as much as possible. */
   1993         memcpy(self->buffer + self->write_end, buffer->buf, avail);
   1994         self->write_end += avail;
   1995         self->pos += avail;
   1996         /* XXX Modifying the existing exception e using the pointer w
   1997            will change e.characters_written but not e.args[2].
   1998            Therefore we just replace with a new error. */
   1999         _set_BlockingIOError("write could not complete without blocking",
   2000                              avail);
   2001         goto error;
   2002     }
   2003     Py_CLEAR(res);
   2004 
   2005     /* Adjust the raw stream position if it is away from the logical stream
   2006        position. This happens if the read buffer has been filled but not
   2007        modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
   2008        the raw stream by itself).
   2009        Fixes issue #6629.
   2010     */
   2011     offset = RAW_OFFSET(self);
   2012     if (offset != 0) {
   2013         if (_buffered_raw_seek(self, -offset, 1) < 0)
   2014             goto error;
   2015         self->raw_pos -= offset;
   2016     }
   2017 
   2018     /* Then write buf itself. At this point the buffer has been emptied. */
   2019     remaining = buffer->len;
   2020     written = 0;
   2021     while (remaining > self->buffer_size) {
   2022         Py_ssize_t n = _bufferedwriter_raw_write(
   2023             self, (char *) buffer->buf + written, buffer->len - written);
   2024         if (n == -1) {
   2025             goto error;
   2026         } else if (n == -2) {
   2027             /* Write failed because raw file is non-blocking */
   2028             if (remaining > self->buffer_size) {
   2029                 /* Can't buffer everything, still buffer as much as possible */
   2030                 memcpy(self->buffer,
   2031                        (char *) buffer->buf + written, self->buffer_size);
   2032                 self->raw_pos = 0;
   2033                 ADJUST_POSITION(self, self->buffer_size);
   2034                 self->write_end = self->buffer_size;
   2035                 written += self->buffer_size;
   2036                 _set_BlockingIOError("write could not complete without "
   2037                                      "blocking", written);
   2038                 goto error;
   2039             }
   2040             PyErr_Clear();
   2041             break;
   2042         }
   2043         written += n;
   2044         remaining -= n;
   2045         /* Partial writes can return successfully when interrupted by a
   2046            signal (see write(2)).  We must run signal handlers before
   2047            blocking another time, possibly indefinitely. */
   2048         if (PyErr_CheckSignals() < 0)
   2049             goto error;
   2050     }
   2051     if (self->readable)
   2052         _bufferedreader_reset_buf(self);
   2053     if (remaining > 0) {
   2054         memcpy(self->buffer, (char *) buffer->buf + written, remaining);
   2055         written += remaining;
   2056     }
   2057     self->write_pos = 0;
   2058     /* TODO: sanity check (remaining >= 0) */
   2059     self->write_end = remaining;
   2060     ADJUST_POSITION(self, remaining);
   2061     self->raw_pos = 0;
   2062 
   2063 end:
   2064     res = PyLong_FromSsize_t(written);
   2065 
   2066 error:
   2067     LEAVE_BUFFERED(self)
   2068     return res;
   2069 }
   2070 
   2071 
   2073 
   2074 /*
   2075  * BufferedRWPair
   2076  */
   2077 
   2078 /* XXX The usefulness of this (compared to having two separate IO objects) is
   2079  * questionable.
   2080  */
   2081 
   2082 typedef struct {
   2083     PyObject_HEAD
   2084     buffered *reader;
   2085     buffered *writer;
   2086     PyObject *dict;
   2087     PyObject *weakreflist;
   2088 } rwpair;
   2089 
   2090 /*[clinic input]
   2091 _io.BufferedRWPair.__init__
   2092     reader: object
   2093     writer: object
   2094     buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
   2095     /
   2096 
   2097 A buffered reader and writer object together.
   2098 
   2099 A buffered reader object and buffered writer object put together to
   2100 form a sequential IO object that can read and write. This is typically
   2101 used with a socket or two-way pipe.
   2102 
   2103 reader and writer are RawIOBase objects that are readable and
   2104 writeable respectively. If the buffer_size is omitted it defaults to
   2105 DEFAULT_BUFFER_SIZE.
   2106 [clinic start generated code]*/
   2107 
   2108 static int
   2109 _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
   2110                                  PyObject *writer, Py_ssize_t buffer_size)
   2111 /*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
   2112 {
   2113     if (_PyIOBase_check_readable(reader, Py_True) == NULL)
   2114         return -1;
   2115     if (_PyIOBase_check_writable(writer, Py_True) == NULL)
   2116         return -1;
   2117 
   2118     self->reader = (buffered *) PyObject_CallFunction(
   2119             (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
   2120     if (self->reader == NULL)
   2121         return -1;
   2122 
   2123     self->writer = (buffered *) PyObject_CallFunction(
   2124             (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
   2125     if (self->writer == NULL) {
   2126         Py_CLEAR(self->reader);
   2127         return -1;
   2128     }
   2129 
   2130     return 0;
   2131 }
   2132 
   2133 static int
   2134 bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
   2135 {
   2136     Py_VISIT(self->dict);
   2137     return 0;
   2138 }
   2139 
   2140 static int
   2141 bufferedrwpair_clear(rwpair *self)
   2142 {
   2143     Py_CLEAR(self->reader);
   2144     Py_CLEAR(self->writer);
   2145     Py_CLEAR(self->dict);
   2146     return 0;
   2147 }
   2148 
   2149 static void
   2150 bufferedrwpair_dealloc(rwpair *self)
   2151 {
   2152     _PyObject_GC_UNTRACK(self);
   2153     if (self->weakreflist != NULL)
   2154         PyObject_ClearWeakRefs((PyObject *)self);
   2155     Py_CLEAR(self->reader);
   2156     Py_CLEAR(self->writer);
   2157     Py_CLEAR(self->dict);
   2158     Py_TYPE(self)->tp_free((PyObject *) self);
   2159 }
   2160 
   2161 static PyObject *
   2162 _forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
   2163 {
   2164     PyObject *func, *ret;
   2165     if (self == NULL) {
   2166         PyErr_SetString(PyExc_ValueError,
   2167                         "I/O operation on uninitialized object");
   2168         return NULL;
   2169     }
   2170 
   2171     func = _PyObject_GetAttrId((PyObject *)self, name);
   2172     if (func == NULL) {
   2173         PyErr_SetString(PyExc_AttributeError, name->string);
   2174         return NULL;
   2175     }
   2176 
   2177     ret = PyObject_CallObject(func, args);
   2178     Py_DECREF(func);
   2179     return ret;
   2180 }
   2181 
   2182 static PyObject *
   2183 bufferedrwpair_read(rwpair *self, PyObject *args)
   2184 {
   2185     return _forward_call(self->reader, &PyId_read, args);
   2186 }
   2187 
   2188 static PyObject *
   2189 bufferedrwpair_peek(rwpair *self, PyObject *args)
   2190 {
   2191     return _forward_call(self->reader, &PyId_peek, args);
   2192 }
   2193 
   2194 static PyObject *
   2195 bufferedrwpair_read1(rwpair *self, PyObject *args)
   2196 {
   2197     return _forward_call(self->reader, &PyId_read1, args);
   2198 }
   2199 
   2200 static PyObject *
   2201 bufferedrwpair_readinto(rwpair *self, PyObject *args)
   2202 {
   2203     return _forward_call(self->reader, &PyId_readinto, args);
   2204 }
   2205 
   2206 static PyObject *
   2207 bufferedrwpair_readinto1(rwpair *self, PyObject *args)
   2208 {
   2209     return _forward_call(self->reader, &PyId_readinto1, args);
   2210 }
   2211 
   2212 static PyObject *
   2213 bufferedrwpair_write(rwpair *self, PyObject *args)
   2214 {
   2215     return _forward_call(self->writer, &PyId_write, args);
   2216 }
   2217 
   2218 static PyObject *
   2219 bufferedrwpair_flush(rwpair *self, PyObject *args)
   2220 {
   2221     return _forward_call(self->writer, &PyId_flush, args);
   2222 }
   2223 
   2224 static PyObject *
   2225 bufferedrwpair_readable(rwpair *self, PyObject *args)
   2226 {
   2227     return _forward_call(self->reader, &PyId_readable, args);
   2228 }
   2229 
   2230 static PyObject *
   2231 bufferedrwpair_writable(rwpair *self, PyObject *args)
   2232 {
   2233     return _forward_call(self->writer, &PyId_writable, args);
   2234 }
   2235 
   2236 static PyObject *
   2237 bufferedrwpair_close(rwpair *self, PyObject *args)
   2238 {
   2239     PyObject *exc = NULL, *val, *tb;
   2240     PyObject *ret = _forward_call(self->writer, &PyId_close, args);
   2241     if (ret == NULL)
   2242         PyErr_Fetch(&exc, &val, &tb);
   2243     else
   2244         Py_DECREF(ret);
   2245     ret = _forward_call(self->reader, &PyId_close, args);
   2246     if (exc != NULL) {
   2247         _PyErr_ChainExceptions(exc, val, tb);
   2248         Py_CLEAR(ret);
   2249     }
   2250     return ret;
   2251 }
   2252 
   2253 static PyObject *
   2254 bufferedrwpair_isatty(rwpair *self, PyObject *args)
   2255 {
   2256     PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
   2257 
   2258     if (ret != Py_False) {
   2259         /* either True or exception */
   2260         return ret;
   2261     }
   2262     Py_DECREF(ret);
   2263 
   2264     return _forward_call(self->reader, &PyId_isatty, args);
   2265 }
   2266 
   2267 static PyObject *
   2268 bufferedrwpair_closed_get(rwpair *self, void *context)
   2269 {
   2270     if (self->writer == NULL) {
   2271         PyErr_SetString(PyExc_RuntimeError,
   2272                 "the BufferedRWPair object is being garbage-collected");
   2273         return NULL;
   2274     }
   2275     return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
   2276 }
   2277 
   2278 
   2280 
   2281 /*
   2282  * BufferedRandom
   2283  */
   2284 
   2285 /*[clinic input]
   2286 _io.BufferedRandom.__init__
   2287     raw: object
   2288     buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
   2289 
   2290 A buffered interface to random access streams.
   2291 
   2292 The constructor creates a reader and writer for a seekable stream,
   2293 raw, given in the first argument. If the buffer_size is omitted it
   2294 defaults to DEFAULT_BUFFER_SIZE.
   2295 [clinic start generated code]*/
   2296 
   2297 static int
   2298 _io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
   2299                                  Py_ssize_t buffer_size)
   2300 /*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
   2301 {
   2302     self->ok = 0;
   2303     self->detached = 0;
   2304 
   2305     if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
   2306         return -1;
   2307     if (_PyIOBase_check_readable(raw, Py_True) == NULL)
   2308         return -1;
   2309     if (_PyIOBase_check_writable(raw, Py_True) == NULL)
   2310         return -1;
   2311 
   2312     Py_INCREF(raw);
   2313     Py_XSETREF(self->raw, raw);
   2314     self->buffer_size = buffer_size;
   2315     self->readable = 1;
   2316     self->writable = 1;
   2317 
   2318     if (_buffered_init(self) < 0)
   2319         return -1;
   2320     _bufferedreader_reset_buf(self);
   2321     _bufferedwriter_reset_buf(self);
   2322     self->pos = 0;
   2323 
   2324     self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
   2325                                 Py_TYPE(raw) == &PyFileIO_Type);
   2326 
   2327     self->ok = 1;
   2328     return 0;
   2329 }
   2330 
   2331 #include "clinic/bufferedio.c.h"
   2332 
   2333 
   2334 static PyMethodDef bufferediobase_methods[] = {
   2335     _IO__BUFFEREDIOBASE_DETACH_METHODDEF
   2336     {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
   2337     {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
   2338     _IO__BUFFEREDIOBASE_READINTO_METHODDEF
   2339     _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
   2340     {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
   2341     {NULL, NULL}
   2342 };
   2343 
   2344 PyTypeObject PyBufferedIOBase_Type = {
   2345     PyVarObject_HEAD_INIT(NULL, 0)
   2346     "_io._BufferedIOBase",      /*tp_name*/
   2347     0,                          /*tp_basicsize*/
   2348     0,                          /*tp_itemsize*/
   2349     0,                          /*tp_dealloc*/
   2350     0,                          /*tp_print*/
   2351     0,                          /*tp_getattr*/
   2352     0,                          /*tp_setattr*/
   2353     0,                          /*tp_compare */
   2354     0,                          /*tp_repr*/
   2355     0,                          /*tp_as_number*/
   2356     0,                          /*tp_as_sequence*/
   2357     0,                          /*tp_as_mapping*/
   2358     0,                          /*tp_hash */
   2359     0,                          /*tp_call*/
   2360     0,                          /*tp_str*/
   2361     0,                          /*tp_getattro*/
   2362     0,                          /*tp_setattro*/
   2363     0,                          /*tp_as_buffer*/
   2364     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
   2365         | Py_TPFLAGS_HAVE_FINALIZE,  /*tp_flags*/
   2366     bufferediobase_doc,         /* tp_doc */
   2367     0,                          /* tp_traverse */
   2368     0,                          /* tp_clear */
   2369     0,                          /* tp_richcompare */
   2370     0,                          /* tp_weaklistoffset */
   2371     0,                          /* tp_iter */
   2372     0,                          /* tp_iternext */
   2373     bufferediobase_methods,     /* tp_methods */
   2374     0,                          /* tp_members */
   2375     0,                          /* tp_getset */
   2376     &PyIOBase_Type,             /* tp_base */
   2377     0,                          /* tp_dict */
   2378     0,                          /* tp_descr_get */
   2379     0,                          /* tp_descr_set */
   2380     0,                          /* tp_dictoffset */
   2381     0,                          /* tp_init */
   2382     0,                          /* tp_alloc */
   2383     0,                          /* tp_new */
   2384     0,                          /* tp_free */
   2385     0,                          /* tp_is_gc */
   2386     0,                          /* tp_bases */
   2387     0,                          /* tp_mro */
   2388     0,                          /* tp_cache */
   2389     0,                          /* tp_subclasses */
   2390     0,                          /* tp_weaklist */
   2391     0,                          /* tp_del */
   2392     0,                          /* tp_version_tag */
   2393     0,                          /* tp_finalize */
   2394 };
   2395 
   2396 
   2397 static PyMethodDef bufferedreader_methods[] = {
   2398     /* BufferedIOMixin methods */
   2399     {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
   2400     {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
   2401     {"close", (PyCFunction)buffered_close, METH_NOARGS},
   2402     {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
   2403     {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
   2404     {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
   2405     {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
   2406     {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
   2407     {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
   2408 
   2409     _IO__BUFFERED_READ_METHODDEF
   2410     _IO__BUFFERED_PEEK_METHODDEF
   2411     _IO__BUFFERED_READ1_METHODDEF
   2412     _IO__BUFFERED_READINTO_METHODDEF
   2413     _IO__BUFFERED_READINTO1_METHODDEF
   2414     _IO__BUFFERED_READLINE_METHODDEF
   2415     _IO__BUFFERED_SEEK_METHODDEF
   2416     {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
   2417     _IO__BUFFERED_TRUNCATE_METHODDEF
   2418     {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
   2419     {NULL, NULL}
   2420 };
   2421 
   2422 static PyMemberDef bufferedreader_members[] = {
   2423     {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
   2424     {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
   2425     {NULL}
   2426 };
   2427 
   2428 static PyGetSetDef bufferedreader_getset[] = {
   2429     {"closed", (getter)buffered_closed_get, NULL, NULL},
   2430     {"name", (getter)buffered_name_get, NULL, NULL},
   2431     {"mode", (getter)buffered_mode_get, NULL, NULL},
   2432     {NULL}
   2433 };
   2434 
   2435 
   2436 PyTypeObject PyBufferedReader_Type = {
   2437     PyVarObject_HEAD_INIT(NULL, 0)
   2438     "_io.BufferedReader",       /*tp_name*/
   2439     sizeof(buffered),           /*tp_basicsize*/
   2440     0,                          /*tp_itemsize*/
   2441     (destructor)buffered_dealloc,     /*tp_dealloc*/
   2442     0,                          /*tp_print*/
   2443     0,                          /*tp_getattr*/
   2444     0,                          /*tp_setattr*/
   2445     0,                          /*tp_compare */
   2446     (reprfunc)buffered_repr,    /*tp_repr*/
   2447     0,                          /*tp_as_number*/
   2448     0,                          /*tp_as_sequence*/
   2449     0,                          /*tp_as_mapping*/
   2450     0,                          /*tp_hash */
   2451     0,                          /*tp_call*/
   2452     0,                          /*tp_str*/
   2453     0,                          /*tp_getattro*/
   2454     0,                          /*tp_setattro*/
   2455     0,                          /*tp_as_buffer*/
   2456     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
   2457         | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
   2458     _io_BufferedReader___init____doc__, /* tp_doc */
   2459     (traverseproc)buffered_traverse, /* tp_traverse */
   2460     (inquiry)buffered_clear,    /* tp_clear */
   2461     0,                          /* tp_richcompare */
   2462     offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
   2463     0,                          /* tp_iter */
   2464     (iternextfunc)buffered_iternext, /* tp_iternext */
   2465     bufferedreader_methods,     /* tp_methods */
   2466     bufferedreader_members,     /* tp_members */
   2467     bufferedreader_getset,      /* tp_getset */
   2468     0,                          /* tp_base */
   2469     0,                          /* tp_dict */
   2470     0,                          /* tp_descr_get */
   2471     0,                          /* tp_descr_set */
   2472     offsetof(buffered, dict), /* tp_dictoffset */
   2473     _io_BufferedReader___init__, /* tp_init */
   2474     0,                          /* tp_alloc */
   2475     PyType_GenericNew,          /* tp_new */
   2476     0,                          /* tp_free */
   2477     0,                          /* tp_is_gc */
   2478     0,                          /* tp_bases */
   2479     0,                          /* tp_mro */
   2480     0,                          /* tp_cache */
   2481     0,                          /* tp_subclasses */
   2482     0,                          /* tp_weaklist */
   2483     0,                          /* tp_del */
   2484     0,                          /* tp_version_tag */
   2485     0,                          /* tp_finalize */
   2486 };
   2487 
   2488 
   2489 static PyMethodDef bufferedwriter_methods[] = {
   2490     /* BufferedIOMixin methods */
   2491     {"close", (PyCFunction)buffered_close, METH_NOARGS},
   2492     {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
   2493     {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
   2494     {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
   2495     {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
   2496     {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
   2497     {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
   2498     {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
   2499 
   2500     _IO_BUFFEREDWRITER_WRITE_METHODDEF
   2501     _IO__BUFFERED_TRUNCATE_METHODDEF
   2502     {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
   2503     _IO__BUFFERED_SEEK_METHODDEF
   2504     {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
   2505     {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
   2506     {NULL, NULL}
   2507 };
   2508 
   2509 static PyMemberDef bufferedwriter_members[] = {
   2510     {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
   2511     {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
   2512     {NULL}
   2513 };
   2514 
   2515 static PyGetSetDef bufferedwriter_getset[] = {
   2516     {"closed", (getter)buffered_closed_get, NULL, NULL},
   2517     {"name", (getter)buffered_name_get, NULL, NULL},
   2518     {"mode", (getter)buffered_mode_get, NULL, NULL},
   2519     {NULL}
   2520 };
   2521 
   2522 
   2523 PyTypeObject PyBufferedWriter_Type = {
   2524     PyVarObject_HEAD_INIT(NULL, 0)
   2525     "_io.BufferedWriter",       /*tp_name*/
   2526     sizeof(buffered),           /*tp_basicsize*/
   2527     0,                          /*tp_itemsize*/
   2528     (destructor)buffered_dealloc,     /*tp_dealloc*/
   2529     0,                          /*tp_print*/
   2530     0,                          /*tp_getattr*/
   2531     0,                          /*tp_setattr*/
   2532     0,                          /*tp_compare */
   2533     (reprfunc)buffered_repr,    /*tp_repr*/
   2534     0,                          /*tp_as_number*/
   2535     0,                          /*tp_as_sequence*/
   2536     0,                          /*tp_as_mapping*/
   2537     0,                          /*tp_hash */
   2538     0,                          /*tp_call*/
   2539     0,                          /*tp_str*/
   2540     0,                          /*tp_getattro*/
   2541     0,                          /*tp_setattro*/
   2542     0,                          /*tp_as_buffer*/
   2543     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
   2544         | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,   /*tp_flags*/
   2545     _io_BufferedWriter___init____doc__, /* tp_doc */
   2546     (traverseproc)buffered_traverse, /* tp_traverse */
   2547     (inquiry)buffered_clear,    /* tp_clear */
   2548     0,                          /* tp_richcompare */
   2549     offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
   2550     0,                          /* tp_iter */
   2551     0,                          /* tp_iternext */
   2552     bufferedwriter_methods,     /* tp_methods */
   2553     bufferedwriter_members,     /* tp_members */
   2554     bufferedwriter_getset,      /* tp_getset */
   2555     0,                          /* tp_base */
   2556     0,                          /* tp_dict */
   2557     0,                          /* tp_descr_get */
   2558     0,                          /* tp_descr_set */
   2559     offsetof(buffered, dict),   /* tp_dictoffset */
   2560     _io_BufferedWriter___init__, /* tp_init */
   2561     0,                          /* tp_alloc */
   2562     PyType_GenericNew,          /* tp_new */
   2563     0,                          /* tp_free */
   2564     0,                          /* tp_is_gc */
   2565     0,                          /* tp_bases */
   2566     0,                          /* tp_mro */
   2567     0,                          /* tp_cache */
   2568     0,                          /* tp_subclasses */
   2569     0,                          /* tp_weaklist */
   2570     0,                          /* tp_del */
   2571     0,                          /* tp_version_tag */
   2572     0,                          /* tp_finalize */
   2573 };
   2574 
   2575 
   2576 static PyMethodDef bufferedrwpair_methods[] = {
   2577     {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
   2578     {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
   2579     {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
   2580     {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
   2581     {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
   2582 
   2583     {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
   2584     {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
   2585 
   2586     {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
   2587     {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
   2588 
   2589     {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
   2590     {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
   2591 
   2592     {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
   2593 
   2594     {NULL, NULL}
   2595 };
   2596 
   2597 static PyGetSetDef bufferedrwpair_getset[] = {
   2598     {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
   2599     {NULL}
   2600 };
   2601 
   2602 PyTypeObject PyBufferedRWPair_Type = {
   2603     PyVarObject_HEAD_INIT(NULL, 0)
   2604     "_io.BufferedRWPair",       /*tp_name*/
   2605     sizeof(rwpair),            /*tp_basicsize*/
   2606     0,                          /*tp_itemsize*/
   2607     (destructor)bufferedrwpair_dealloc,     /*tp_dealloc*/
   2608     0,                          /*tp_print*/
   2609     0,                          /*tp_getattr*/
   2610     0,                          /*tp_setattr*/
   2611     0,                          /*tp_compare */
   2612     0,                          /*tp_repr*/
   2613     0,                          /*tp_as_number*/
   2614     0,                          /*tp_as_sequence*/
   2615     0,                          /*tp_as_mapping*/
   2616     0,                          /*tp_hash */
   2617     0,                          /*tp_call*/
   2618     0,                          /*tp_str*/
   2619     0,                          /*tp_getattro*/
   2620     0,                          /*tp_setattro*/
   2621     0,                          /*tp_as_buffer*/
   2622     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
   2623         | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,   /* tp_flags */
   2624     _io_BufferedRWPair___init____doc__, /* tp_doc */
   2625     (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
   2626     (inquiry)bufferedrwpair_clear, /* tp_clear */
   2627     0,                          /* tp_richcompare */
   2628     offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
   2629     0,                          /* tp_iter */
   2630     0,                          /* tp_iternext */
   2631     bufferedrwpair_methods,     /* tp_methods */
   2632     0,                          /* tp_members */
   2633     bufferedrwpair_getset,      /* tp_getset */
   2634     0,                          /* tp_base */
   2635     0,                          /* tp_dict */
   2636     0,                          /* tp_descr_get */
   2637     0,                          /* tp_descr_set */
   2638     offsetof(rwpair, dict),     /* tp_dictoffset */
   2639     _io_BufferedRWPair___init__, /* tp_init */
   2640     0,                          /* tp_alloc */
   2641     PyType_GenericNew,          /* tp_new */
   2642     0,                          /* tp_free */
   2643     0,                          /* tp_is_gc */
   2644     0,                          /* tp_bases */
   2645     0,                          /* tp_mro */
   2646     0,                          /* tp_cache */
   2647     0,                          /* tp_subclasses */
   2648     0,                          /* tp_weaklist */
   2649     0,                          /* tp_del */
   2650     0,                          /* tp_version_tag */
   2651     0,                          /* tp_finalize */
   2652 };
   2653 
   2654 
   2655 static PyMethodDef bufferedrandom_methods[] = {
   2656     /* BufferedIOMixin methods */
   2657     {"close", (PyCFunction)buffered_close, METH_NOARGS},
   2658     {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
   2659     {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
   2660     {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
   2661     {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
   2662     {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
   2663     {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
   2664     {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
   2665     {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
   2666 
   2667     {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
   2668 
   2669     _IO__BUFFERED_SEEK_METHODDEF
   2670     {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
   2671     _IO__BUFFERED_TRUNCATE_METHODDEF
   2672     _IO__BUFFERED_READ_METHODDEF
   2673     _IO__BUFFERED_READ1_METHODDEF
   2674     _IO__BUFFERED_READINTO_METHODDEF
   2675     _IO__BUFFERED_READINTO1_METHODDEF
   2676     _IO__BUFFERED_READLINE_METHODDEF
   2677     _IO__BUFFERED_PEEK_METHODDEF
   2678     _IO_BUFFEREDWRITER_WRITE_METHODDEF
   2679     {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
   2680     {NULL, NULL}
   2681 };
   2682 
   2683 static PyMemberDef bufferedrandom_members[] = {
   2684     {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
   2685     {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
   2686     {NULL}
   2687 };
   2688 
   2689 static PyGetSetDef bufferedrandom_getset[] = {
   2690     {"closed", (getter)buffered_closed_get, NULL, NULL},
   2691     {"name", (getter)buffered_name_get, NULL, NULL},
   2692     {"mode", (getter)buffered_mode_get, NULL, NULL},
   2693     {NULL}
   2694 };
   2695 
   2696 
   2697 PyTypeObject PyBufferedRandom_Type = {
   2698     PyVarObject_HEAD_INIT(NULL, 0)
   2699     "_io.BufferedRandom",       /*tp_name*/
   2700     sizeof(buffered),           /*tp_basicsize*/
   2701     0,                          /*tp_itemsize*/
   2702     (destructor)buffered_dealloc,     /*tp_dealloc*/
   2703     0,                          /*tp_print*/
   2704     0,                          /*tp_getattr*/
   2705     0,                          /*tp_setattr*/
   2706     0,                          /*tp_compare */
   2707     (reprfunc)buffered_repr,    /*tp_repr*/
   2708     0,                          /*tp_as_number*/
   2709     0,                          /*tp_as_sequence*/
   2710     0,                          /*tp_as_mapping*/
   2711     0,                          /*tp_hash */
   2712     0,                          /*tp_call*/
   2713     0,                          /*tp_str*/
   2714     0,                          /*tp_getattro*/
   2715     0,                          /*tp_setattro*/
   2716     0,                          /*tp_as_buffer*/
   2717     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
   2718         | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,   /*tp_flags*/
   2719     _io_BufferedRandom___init____doc__, /* tp_doc */
   2720     (traverseproc)buffered_traverse, /* tp_traverse */
   2721     (inquiry)buffered_clear,    /* tp_clear */
   2722     0,                          /* tp_richcompare */
   2723     offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
   2724     0,                          /* tp_iter */
   2725     (iternextfunc)buffered_iternext, /* tp_iternext */
   2726     bufferedrandom_methods,     /* tp_methods */
   2727     bufferedrandom_members,     /* tp_members */
   2728     bufferedrandom_getset,      /* tp_getset */
   2729     0,                          /* tp_base */
   2730     0,                          /*tp_dict*/
   2731     0,                          /* tp_descr_get */
   2732     0,                          /* tp_descr_set */
   2733     offsetof(buffered, dict), /*tp_dictoffset*/
   2734     _io_BufferedRandom___init__, /* tp_init */
   2735     0,                          /* tp_alloc */
   2736     PyType_GenericNew,          /* tp_new */
   2737     0,                          /* tp_free */
   2738     0,                          /* tp_is_gc */
   2739     0,                          /* tp_bases */
   2740     0,                          /* tp_mro */
   2741     0,                          /* tp_cache */
   2742     0,                          /* tp_subclasses */
   2743     0,                          /* tp_weaklist */
   2744     0,                          /* tp_del */
   2745     0,                          /* tp_version_tag */
   2746     0,                          /* tp_finalize */
   2747 };
   2748