(root)/
Python-3.12.0/
Modules/
_io/
bytesio.c
       1  #include "Python.h"
       2  #include "pycore_object.h"
       3  #include <stddef.h>               // offsetof()
       4  #include "_iomodule.h"
       5  
       6  /*[clinic input]
       7  module _io
       8  class _io.BytesIO "bytesio *" "clinic_state()->PyBytesIO_Type"
       9  [clinic start generated code]*/
      10  /*[clinic end generated code: output=da39a3ee5e6b4b0d input=48ede2f330f847c3]*/
      11  
      12  typedef struct {
      13      PyObject_HEAD
      14      PyObject *buf;
      15      Py_ssize_t pos;
      16      Py_ssize_t string_size;
      17      PyObject *dict;
      18      PyObject *weakreflist;
      19      Py_ssize_t exports;
      20  } bytesio;
      21  
      22  typedef struct {
      23      PyObject_HEAD
      24      bytesio *source;
      25  } bytesiobuf;
      26  
      27  /* The bytesio object can be in three states:
      28    * Py_REFCNT(buf) == 1, exports == 0.
      29    * Py_REFCNT(buf) > 1.  exports == 0,
      30      first modification or export causes the internal buffer copying.
      31    * exports > 0.  Py_REFCNT(buf) == 1, any modifications are forbidden.
      32  */
      33  
      34  static int
      35  check_closed(bytesio *self)
      36  {
      37      if (self->buf == NULL) {
      38          PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
      39          return 1;
      40      }
      41      return 0;
      42  }
      43  
      44  static int
      45  check_exports(bytesio *self)
      46  {
      47      if (self->exports > 0) {
      48          PyErr_SetString(PyExc_BufferError,
      49                          "Existing exports of data: object cannot be re-sized");
      50          return 1;
      51      }
      52      return 0;
      53  }
      54  
      55  #define CHECK_CLOSED(self)                                  \
      56      if (check_closed(self)) {                               \
      57          return NULL;                                        \
      58      }
      59  
      60  #define CHECK_EXPORTS(self) \
      61      if (check_exports(self)) { \
      62          return NULL; \
      63      }
      64  
      65  #define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1)
      66  
      67  
      68  /* Internal routine to get a line from the buffer of a BytesIO
      69     object. Returns the length between the current position to the
      70     next newline character. */
      71  static Py_ssize_t
      72  scan_eol(bytesio *self, Py_ssize_t len)
      73  {
      74      const char *start, *n;
      75      Py_ssize_t maxlen;
      76  
      77      assert(self->buf != NULL);
      78      assert(self->pos >= 0);
      79  
      80      if (self->pos >= self->string_size)
      81          return 0;
      82  
      83      /* Move to the end of the line, up to the end of the string, s. */
      84      maxlen = self->string_size - self->pos;
      85      if (len < 0 || len > maxlen)
      86          len = maxlen;
      87  
      88      if (len) {
      89          start = PyBytes_AS_STRING(self->buf) + self->pos;
      90          n = memchr(start, '\n', len);
      91          if (n)
      92              /* Get the length from the current position to the end of
      93                 the line. */
      94              len = n - start + 1;
      95      }
      96      assert(len >= 0);
      97      assert(self->pos < PY_SSIZE_T_MAX - len);
      98  
      99      return len;
     100  }
     101  
     102  /* Internal routine for detaching the shared buffer of BytesIO objects.
     103     The caller should ensure that the 'size' argument is non-negative and
     104     not lesser than self->string_size.  Returns 0 on success, -1 otherwise. */
     105  static int
     106  unshare_buffer(bytesio *self, size_t size)
     107  {
     108      PyObject *new_buf;
     109      assert(SHARED_BUF(self));
     110      assert(self->exports == 0);
     111      assert(size >= (size_t)self->string_size);
     112      new_buf = PyBytes_FromStringAndSize(NULL, size);
     113      if (new_buf == NULL)
     114          return -1;
     115      memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf),
     116             self->string_size);
     117      Py_SETREF(self->buf, new_buf);
     118      return 0;
     119  }
     120  
     121  /* Internal routine for changing the size of the buffer of BytesIO objects.
     122     The caller should ensure that the 'size' argument is non-negative.  Returns
     123     0 on success, -1 otherwise. */
     124  static int
     125  resize_buffer(bytesio *self, size_t size)
     126  {
     127      /* Here, unsigned types are used to avoid dealing with signed integer
     128         overflow, which is undefined in C. */
     129      size_t alloc = PyBytes_GET_SIZE(self->buf);
     130  
     131      assert(self->buf != NULL);
     132  
     133      /* For simplicity, stay in the range of the signed type. Anyway, Python
     134         doesn't allow strings to be longer than this. */
     135      if (size > PY_SSIZE_T_MAX)
     136          goto overflow;
     137  
     138      if (size < alloc / 2) {
     139          /* Major downsize; resize down to exact size. */
     140          alloc = size + 1;
     141      }
     142      else if (size < alloc) {
     143          /* Within allocated size; quick exit */
     144          return 0;
     145      }
     146      else if (size <= alloc * 1.125) {
     147          /* Moderate upsize; overallocate similar to list_resize() */
     148          alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
     149      }
     150      else {
     151          /* Major upsize; resize up to exact size */
     152          alloc = size + 1;
     153      }
     154  
     155      if (alloc > ((size_t)-1) / sizeof(char))
     156          goto overflow;
     157  
     158      if (SHARED_BUF(self)) {
     159          if (unshare_buffer(self, alloc) < 0)
     160              return -1;
     161      }
     162      else {
     163          if (_PyBytes_Resize(&self->buf, alloc) < 0)
     164              return -1;
     165      }
     166  
     167      return 0;
     168  
     169    overflow:
     170      PyErr_SetString(PyExc_OverflowError,
     171                      "new buffer size too large");
     172      return -1;
     173  }
     174  
     175  /* Internal routine for writing a string of bytes to the buffer of a BytesIO
     176     object. Returns the number of bytes written, or -1 on error.
     177     Inlining is disabled because it's significantly decreases performance
     178     of writelines() in PGO build. */
     179  Py_NO_INLINE static Py_ssize_t
     180  write_bytes(bytesio *self, PyObject *b)
     181  {
     182      if (check_closed(self)) {
     183          return -1;
     184      }
     185      if (check_exports(self)) {
     186          return -1;
     187      }
     188  
     189      Py_buffer buf;
     190      if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0) {
     191          return -1;
     192      }
     193      Py_ssize_t len = buf.len;
     194      if (len == 0) {
     195          goto done;
     196      }
     197  
     198      assert(self->pos >= 0);
     199      size_t endpos = (size_t)self->pos + len;
     200      if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
     201          if (resize_buffer(self, endpos) < 0) {
     202              len = -1;
     203              goto done;
     204          }
     205      }
     206      else if (SHARED_BUF(self)) {
     207          if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0) {
     208              len = -1;
     209              goto done;
     210          }
     211      }
     212  
     213      if (self->pos > self->string_size) {
     214          /* In case of overseek, pad with null bytes the buffer region between
     215             the end of stream and the current position.
     216  
     217            0   lo      string_size                           hi
     218            |   |<---used--->|<----------available----------->|
     219            |   |            <--to pad-->|<---to write--->    |
     220            0   buf                   position
     221          */
     222          memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
     223                 (self->pos - self->string_size) * sizeof(char));
     224      }
     225  
     226      /* Copy the data to the internal buffer, overwriting some of the existing
     227         data if self->pos < self->string_size. */
     228      memcpy(PyBytes_AS_STRING(self->buf) + self->pos, buf.buf, len);
     229      self->pos = endpos;
     230  
     231      /* Set the new length of the internal string if it has changed. */
     232      if ((size_t)self->string_size < endpos) {
     233          self->string_size = endpos;
     234      }
     235  
     236    done:
     237      PyBuffer_Release(&buf);
     238      return len;
     239  }
     240  
     241  static PyObject *
     242  bytesio_get_closed(bytesio *self, void *Py_UNUSED(ignored))
     243  {
     244      if (self->buf == NULL) {
     245          Py_RETURN_TRUE;
     246      }
     247      else {
     248          Py_RETURN_FALSE;
     249      }
     250  }
     251  
     252  /*[clinic input]
     253  _io.BytesIO.readable
     254  
     255  Returns True if the IO object can be read.
     256  [clinic start generated code]*/
     257  
     258  static PyObject *
     259  _io_BytesIO_readable_impl(bytesio *self)
     260  /*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/
     261  {
     262      CHECK_CLOSED(self);
     263      Py_RETURN_TRUE;
     264  }
     265  
     266  /*[clinic input]
     267  _io.BytesIO.writable
     268  
     269  Returns True if the IO object can be written.
     270  [clinic start generated code]*/
     271  
     272  static PyObject *
     273  _io_BytesIO_writable_impl(bytesio *self)
     274  /*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/
     275  {
     276      CHECK_CLOSED(self);
     277      Py_RETURN_TRUE;
     278  }
     279  
     280  /*[clinic input]
     281  _io.BytesIO.seekable
     282  
     283  Returns True if the IO object can be seeked.
     284  [clinic start generated code]*/
     285  
     286  static PyObject *
     287  _io_BytesIO_seekable_impl(bytesio *self)
     288  /*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/
     289  {
     290      CHECK_CLOSED(self);
     291      Py_RETURN_TRUE;
     292  }
     293  
     294  /*[clinic input]
     295  _io.BytesIO.flush
     296  
     297  Does nothing.
     298  [clinic start generated code]*/
     299  
     300  static PyObject *
     301  _io_BytesIO_flush_impl(bytesio *self)
     302  /*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/
     303  {
     304      CHECK_CLOSED(self);
     305      Py_RETURN_NONE;
     306  }
     307  
     308  /*[clinic input]
     309  _io.BytesIO.getbuffer
     310  
     311      cls: defining_class
     312      /
     313  
     314  Get a read-write view over the contents of the BytesIO object.
     315  [clinic start generated code]*/
     316  
     317  static PyObject *
     318  _io_BytesIO_getbuffer_impl(bytesio *self, PyTypeObject *cls)
     319  /*[clinic end generated code: output=045091d7ce87fe4e input=0668fbb48f95dffa]*/
     320  {
     321      _PyIO_State *state = get_io_state_by_cls(cls);
     322      PyTypeObject *type = state->PyBytesIOBuffer_Type;
     323      bytesiobuf *buf;
     324      PyObject *view;
     325  
     326      CHECK_CLOSED(self);
     327  
     328      buf = (bytesiobuf *) type->tp_alloc(type, 0);
     329      if (buf == NULL)
     330          return NULL;
     331      buf->source = (bytesio*)Py_NewRef(self);
     332      view = PyMemoryView_FromObject((PyObject *) buf);
     333      Py_DECREF(buf);
     334      return view;
     335  }
     336  
     337  /*[clinic input]
     338  _io.BytesIO.getvalue
     339  
     340  Retrieve the entire contents of the BytesIO object.
     341  [clinic start generated code]*/
     342  
     343  static PyObject *
     344  _io_BytesIO_getvalue_impl(bytesio *self)
     345  /*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/
     346  {
     347      CHECK_CLOSED(self);
     348      if (self->string_size <= 1 || self->exports > 0)
     349          return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
     350                                           self->string_size);
     351  
     352      if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
     353          if (SHARED_BUF(self)) {
     354              if (unshare_buffer(self, self->string_size) < 0)
     355                  return NULL;
     356          }
     357          else {
     358              if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
     359                  return NULL;
     360          }
     361      }
     362      return Py_NewRef(self->buf);
     363  }
     364  
     365  /*[clinic input]
     366  _io.BytesIO.isatty
     367  
     368  Always returns False.
     369  
     370  BytesIO objects are not connected to a TTY-like device.
     371  [clinic start generated code]*/
     372  
     373  static PyObject *
     374  _io_BytesIO_isatty_impl(bytesio *self)
     375  /*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/
     376  {
     377      CHECK_CLOSED(self);
     378      Py_RETURN_FALSE;
     379  }
     380  
     381  /*[clinic input]
     382  _io.BytesIO.tell
     383  
     384  Current file position, an integer.
     385  [clinic start generated code]*/
     386  
     387  static PyObject *
     388  _io_BytesIO_tell_impl(bytesio *self)
     389  /*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/
     390  {
     391      CHECK_CLOSED(self);
     392      return PyLong_FromSsize_t(self->pos);
     393  }
     394  
     395  static PyObject *
     396  read_bytes(bytesio *self, Py_ssize_t size)
     397  {
     398      const char *output;
     399  
     400      assert(self->buf != NULL);
     401      assert(size <= self->string_size);
     402      if (size > 1 &&
     403          self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
     404          self->exports == 0) {
     405          self->pos += size;
     406          return Py_NewRef(self->buf);
     407      }
     408  
     409      output = PyBytes_AS_STRING(self->buf) + self->pos;
     410      self->pos += size;
     411      return PyBytes_FromStringAndSize(output, size);
     412  }
     413  
     414  /*[clinic input]
     415  _io.BytesIO.read
     416      size: Py_ssize_t(accept={int, NoneType}) = -1
     417      /
     418  
     419  Read at most size bytes, returned as a bytes object.
     420  
     421  If the size argument is negative, read until EOF is reached.
     422  Return an empty bytes object at EOF.
     423  [clinic start generated code]*/
     424  
     425  static PyObject *
     426  _io_BytesIO_read_impl(bytesio *self, Py_ssize_t size)
     427  /*[clinic end generated code: output=9cc025f21c75bdd2 input=74344a39f431c3d7]*/
     428  {
     429      Py_ssize_t n;
     430  
     431      CHECK_CLOSED(self);
     432  
     433      /* adjust invalid sizes */
     434      n = self->string_size - self->pos;
     435      if (size < 0 || size > n) {
     436          size = n;
     437          if (size < 0)
     438              size = 0;
     439      }
     440  
     441      return read_bytes(self, size);
     442  }
     443  
     444  
     445  /*[clinic input]
     446  _io.BytesIO.read1
     447      size: Py_ssize_t(accept={int, NoneType}) = -1
     448      /
     449  
     450  Read at most size bytes, returned as a bytes object.
     451  
     452  If the size argument is negative or omitted, read until EOF is reached.
     453  Return an empty bytes object at EOF.
     454  [clinic start generated code]*/
     455  
     456  static PyObject *
     457  _io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
     458  /*[clinic end generated code: output=d0f843285aa95f1c input=440a395bf9129ef5]*/
     459  {
     460      return _io_BytesIO_read_impl(self, size);
     461  }
     462  
     463  /*[clinic input]
     464  _io.BytesIO.readline
     465      size: Py_ssize_t(accept={int, NoneType}) = -1
     466      /
     467  
     468  Next line from the file, as a bytes object.
     469  
     470  Retain newline.  A non-negative size argument limits the maximum
     471  number of bytes to return (an incomplete line may be returned then).
     472  Return an empty bytes object at EOF.
     473  [clinic start generated code]*/
     474  
     475  static PyObject *
     476  _io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size)
     477  /*[clinic end generated code: output=4bff3c251df8ffcd input=e7c3fbd1744e2783]*/
     478  {
     479      Py_ssize_t n;
     480  
     481      CHECK_CLOSED(self);
     482  
     483      n = scan_eol(self, size);
     484  
     485      return read_bytes(self, n);
     486  }
     487  
     488  /*[clinic input]
     489  _io.BytesIO.readlines
     490      size as arg: object = None
     491      /
     492  
     493  List of bytes objects, each a line from the file.
     494  
     495  Call readline() repeatedly and return a list of the lines so read.
     496  The optional size argument, if given, is an approximate bound on the
     497  total number of bytes in the lines returned.
     498  [clinic start generated code]*/
     499  
     500  static PyObject *
     501  _io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
     502  /*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
     503  {
     504      Py_ssize_t maxsize, size, n;
     505      PyObject *result, *line;
     506      const char *output;
     507  
     508      CHECK_CLOSED(self);
     509  
     510      if (PyLong_Check(arg)) {
     511          maxsize = PyLong_AsSsize_t(arg);
     512          if (maxsize == -1 && PyErr_Occurred())
     513              return NULL;
     514      }
     515      else if (arg == Py_None) {
     516          /* No size limit, by default. */
     517          maxsize = -1;
     518      }
     519      else {
     520          PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
     521                       Py_TYPE(arg)->tp_name);
     522          return NULL;
     523      }
     524  
     525      size = 0;
     526      result = PyList_New(0);
     527      if (!result)
     528          return NULL;
     529  
     530      output = PyBytes_AS_STRING(self->buf) + self->pos;
     531      while ((n = scan_eol(self, -1)) != 0) {
     532          self->pos += n;
     533          line = PyBytes_FromStringAndSize(output, n);
     534          if (!line)
     535              goto on_error;
     536          if (PyList_Append(result, line) == -1) {
     537              Py_DECREF(line);
     538              goto on_error;
     539          }
     540          Py_DECREF(line);
     541          size += n;
     542          if (maxsize > 0 && size >= maxsize)
     543              break;
     544          output += n;
     545      }
     546      return result;
     547  
     548    on_error:
     549      Py_DECREF(result);
     550      return NULL;
     551  }
     552  
     553  /*[clinic input]
     554  _io.BytesIO.readinto
     555      buffer: Py_buffer(accept={rwbuffer})
     556      /
     557  
     558  Read bytes into buffer.
     559  
     560  Returns number of bytes read (0 for EOF), or None if the object
     561  is set not to block and has no data to read.
     562  [clinic start generated code]*/
     563  
     564  static PyObject *
     565  _io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
     566  /*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
     567  {
     568      Py_ssize_t len, n;
     569  
     570      CHECK_CLOSED(self);
     571  
     572      /* adjust invalid sizes */
     573      len = buffer->len;
     574      n = self->string_size - self->pos;
     575      if (len > n) {
     576          len = n;
     577          if (len < 0)
     578              len = 0;
     579      }
     580  
     581      memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
     582      assert(self->pos + len < PY_SSIZE_T_MAX);
     583      assert(len >= 0);
     584      self->pos += len;
     585  
     586      return PyLong_FromSsize_t(len);
     587  }
     588  
     589  /*[clinic input]
     590  _io.BytesIO.truncate
     591      size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None
     592      /
     593  
     594  Truncate the file to at most size bytes.
     595  
     596  Size defaults to the current file position, as returned by tell().
     597  The current file position is unchanged.  Returns the new size.
     598  [clinic start generated code]*/
     599  
     600  static PyObject *
     601  _io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size)
     602  /*[clinic end generated code: output=9ad17650c15fa09b input=423759dd42d2f7c1]*/
     603  {
     604      CHECK_CLOSED(self);
     605      CHECK_EXPORTS(self);
     606  
     607      if (size < 0) {
     608          PyErr_Format(PyExc_ValueError,
     609                       "negative size value %zd", size);
     610          return NULL;
     611      }
     612  
     613      if (size < self->string_size) {
     614          self->string_size = size;
     615          if (resize_buffer(self, size) < 0)
     616              return NULL;
     617      }
     618  
     619      return PyLong_FromSsize_t(size);
     620  }
     621  
     622  static PyObject *
     623  bytesio_iternext(bytesio *self)
     624  {
     625      Py_ssize_t n;
     626  
     627      CHECK_CLOSED(self);
     628  
     629      n = scan_eol(self, -1);
     630  
     631      if (n == 0)
     632          return NULL;
     633  
     634      return read_bytes(self, n);
     635  }
     636  
     637  /*[clinic input]
     638  _io.BytesIO.seek
     639      pos: Py_ssize_t
     640      whence: int = 0
     641      /
     642  
     643  Change stream position.
     644  
     645  Seek to byte offset pos relative to position indicated by whence:
     646       0  Start of stream (the default).  pos should be >= 0;
     647       1  Current position - pos may be negative;
     648       2  End of stream - pos usually negative.
     649  Returns the new absolute position.
     650  [clinic start generated code]*/
     651  
     652  static PyObject *
     653  _io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
     654  /*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
     655  {
     656      CHECK_CLOSED(self);
     657  
     658      if (pos < 0 && whence == 0) {
     659          PyErr_Format(PyExc_ValueError,
     660                       "negative seek value %zd", pos);
     661          return NULL;
     662      }
     663  
     664      /* whence = 0: offset relative to beginning of the string.
     665         whence = 1: offset relative to current position.
     666         whence = 2: offset relative the end of the string. */
     667      if (whence == 1) {
     668          if (pos > PY_SSIZE_T_MAX - self->pos) {
     669              PyErr_SetString(PyExc_OverflowError,
     670                              "new position too large");
     671              return NULL;
     672          }
     673          pos += self->pos;
     674      }
     675      else if (whence == 2) {
     676          if (pos > PY_SSIZE_T_MAX - self->string_size) {
     677              PyErr_SetString(PyExc_OverflowError,
     678                              "new position too large");
     679              return NULL;
     680          }
     681          pos += self->string_size;
     682      }
     683      else if (whence != 0) {
     684          PyErr_Format(PyExc_ValueError,
     685                       "invalid whence (%i, should be 0, 1 or 2)", whence);
     686          return NULL;
     687      }
     688  
     689      if (pos < 0)
     690          pos = 0;
     691      self->pos = pos;
     692  
     693      return PyLong_FromSsize_t(self->pos);
     694  }
     695  
     696  /*[clinic input]
     697  _io.BytesIO.write
     698      b: object
     699      /
     700  
     701  Write bytes to file.
     702  
     703  Return the number of bytes written.
     704  [clinic start generated code]*/
     705  
     706  static PyObject *
     707  _io_BytesIO_write(bytesio *self, PyObject *b)
     708  /*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
     709  {
     710      Py_ssize_t n = write_bytes(self, b);
     711      return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
     712  }
     713  
     714  /*[clinic input]
     715  _io.BytesIO.writelines
     716      lines: object
     717      /
     718  
     719  Write lines to the file.
     720  
     721  Note that newlines are not added.  lines can be any iterable object
     722  producing bytes-like objects. This is equivalent to calling write() for
     723  each element.
     724  [clinic start generated code]*/
     725  
     726  static PyObject *
     727  _io_BytesIO_writelines(bytesio *self, PyObject *lines)
     728  /*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
     729  {
     730      PyObject *it, *item;
     731  
     732      CHECK_CLOSED(self);
     733  
     734      it = PyObject_GetIter(lines);
     735      if (it == NULL)
     736          return NULL;
     737  
     738      while ((item = PyIter_Next(it)) != NULL) {
     739          Py_ssize_t ret = write_bytes(self, item);
     740          Py_DECREF(item);
     741          if (ret < 0) {
     742              Py_DECREF(it);
     743              return NULL;
     744          }
     745      }
     746      Py_DECREF(it);
     747  
     748      /* See if PyIter_Next failed */
     749      if (PyErr_Occurred())
     750          return NULL;
     751  
     752      Py_RETURN_NONE;
     753  }
     754  
     755  /*[clinic input]
     756  _io.BytesIO.close
     757  
     758  Disable all I/O operations.
     759  [clinic start generated code]*/
     760  
     761  static PyObject *
     762  _io_BytesIO_close_impl(bytesio *self)
     763  /*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
     764  {
     765      CHECK_EXPORTS(self);
     766      Py_CLEAR(self->buf);
     767      Py_RETURN_NONE;
     768  }
     769  
     770  /* Pickling support.
     771  
     772     Note that only pickle protocol 2 and onward are supported since we use
     773     extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
     774  
     775     Providing support for protocol < 2 would require the __reduce_ex__ method
     776     which is notably long-winded when defined properly.
     777  
     778     For BytesIO, the implementation would similar to one coded for
     779     object.__reduce_ex__, but slightly less general. To be more specific, we
     780     could call bytesio_getstate directly and avoid checking for the presence of
     781     a fallback __reduce__ method. However, we would still need a __newobj__
     782     function to use the efficient instance representation of PEP 307.
     783   */
     784  
     785  static PyObject *
     786  bytesio_getstate(bytesio *self, PyObject *Py_UNUSED(ignored))
     787  {
     788      PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
     789      PyObject *dict;
     790      PyObject *state;
     791  
     792      if (initvalue == NULL)
     793          return NULL;
     794      if (self->dict == NULL) {
     795          dict = Py_NewRef(Py_None);
     796      }
     797      else {
     798          dict = PyDict_Copy(self->dict);
     799          if (dict == NULL) {
     800              Py_DECREF(initvalue);
     801              return NULL;
     802          }
     803      }
     804  
     805      state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
     806      Py_DECREF(initvalue);
     807      return state;
     808  }
     809  
     810  static PyObject *
     811  bytesio_setstate(bytesio *self, PyObject *state)
     812  {
     813      PyObject *result;
     814      PyObject *position_obj;
     815      PyObject *dict;
     816      Py_ssize_t pos;
     817  
     818      assert(state != NULL);
     819  
     820      /* We allow the state tuple to be longer than 3, because we may need
     821         someday to extend the object's state without breaking
     822         backward-compatibility. */
     823      if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) < 3) {
     824          PyErr_Format(PyExc_TypeError,
     825                       "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
     826                       Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
     827          return NULL;
     828      }
     829      CHECK_EXPORTS(self);
     830      /* Reset the object to its default state. This is only needed to handle
     831         the case of repeated calls to __setstate__. */
     832      self->string_size = 0;
     833      self->pos = 0;
     834  
     835      /* Set the value of the internal buffer. If state[0] does not support the
     836         buffer protocol, bytesio_write will raise the appropriate TypeError. */
     837      result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
     838      if (result == NULL)
     839          return NULL;
     840      Py_DECREF(result);
     841  
     842      /* Set carefully the position value. Alternatively, we could use the seek
     843         method instead of modifying self->pos directly to better protect the
     844         object internal state against erroneous (or malicious) inputs. */
     845      position_obj = PyTuple_GET_ITEM(state, 1);
     846      if (!PyLong_Check(position_obj)) {
     847          PyErr_Format(PyExc_TypeError,
     848                       "second item of state must be an integer, not %.200s",
     849                       Py_TYPE(position_obj)->tp_name);
     850          return NULL;
     851      }
     852      pos = PyLong_AsSsize_t(position_obj);
     853      if (pos == -1 && PyErr_Occurred())
     854          return NULL;
     855      if (pos < 0) {
     856          PyErr_SetString(PyExc_ValueError,
     857                          "position value cannot be negative");
     858          return NULL;
     859      }
     860      self->pos = pos;
     861  
     862      /* Set the dictionary of the instance variables. */
     863      dict = PyTuple_GET_ITEM(state, 2);
     864      if (dict != Py_None) {
     865          if (!PyDict_Check(dict)) {
     866              PyErr_Format(PyExc_TypeError,
     867                           "third item of state should be a dict, got a %.200s",
     868                           Py_TYPE(dict)->tp_name);
     869              return NULL;
     870          }
     871          if (self->dict) {
     872              /* Alternatively, we could replace the internal dictionary
     873                 completely. However, it seems more practical to just update it. */
     874              if (PyDict_Update(self->dict, dict) < 0)
     875                  return NULL;
     876          }
     877          else {
     878              self->dict = Py_NewRef(dict);
     879          }
     880      }
     881  
     882      Py_RETURN_NONE;
     883  }
     884  
     885  static void
     886  bytesio_dealloc(bytesio *self)
     887  {
     888      PyTypeObject *tp = Py_TYPE(self);
     889      _PyObject_GC_UNTRACK(self);
     890      if (self->exports > 0) {
     891          PyErr_SetString(PyExc_SystemError,
     892                          "deallocated BytesIO object has exported buffers");
     893          PyErr_Print();
     894      }
     895      Py_CLEAR(self->buf);
     896      Py_CLEAR(self->dict);
     897      if (self->weakreflist != NULL)
     898          PyObject_ClearWeakRefs((PyObject *) self);
     899      tp->tp_free(self);
     900      Py_DECREF(tp);
     901  }
     902  
     903  static PyObject *
     904  bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     905  {
     906      bytesio *self;
     907  
     908      assert(type != NULL && type->tp_alloc != NULL);
     909      self = (bytesio *)type->tp_alloc(type, 0);
     910      if (self == NULL)
     911          return NULL;
     912  
     913      /* tp_alloc initializes all the fields to zero. So we don't have to
     914         initialize them here. */
     915  
     916      self->buf = PyBytes_FromStringAndSize(NULL, 0);
     917      if (self->buf == NULL) {
     918          Py_DECREF(self);
     919          return PyErr_NoMemory();
     920      }
     921  
     922      return (PyObject *)self;
     923  }
     924  
     925  /*[clinic input]
     926  _io.BytesIO.__init__
     927      initial_bytes as initvalue: object(c_default="NULL") = b''
     928  
     929  Buffered I/O implementation using an in-memory bytes buffer.
     930  [clinic start generated code]*/
     931  
     932  static int
     933  _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
     934  /*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
     935  {
     936      /* In case, __init__ is called multiple times. */
     937      self->string_size = 0;
     938      self->pos = 0;
     939  
     940      if (self->exports > 0) {
     941          PyErr_SetString(PyExc_BufferError,
     942                          "Existing exports of data: object cannot be re-sized");
     943          return -1;
     944      }
     945      if (initvalue && initvalue != Py_None) {
     946          if (PyBytes_CheckExact(initvalue)) {
     947              Py_XSETREF(self->buf, Py_NewRef(initvalue));
     948              self->string_size = PyBytes_GET_SIZE(initvalue);
     949          }
     950          else {
     951              PyObject *res;
     952              res = _io_BytesIO_write(self, initvalue);
     953              if (res == NULL)
     954                  return -1;
     955              Py_DECREF(res);
     956              self->pos = 0;
     957          }
     958      }
     959  
     960      return 0;
     961  }
     962  
     963  static PyObject *
     964  bytesio_sizeof(bytesio *self, void *unused)
     965  {
     966      size_t res = _PyObject_SIZE(Py_TYPE(self));
     967      if (self->buf && !SHARED_BUF(self)) {
     968          size_t s = _PySys_GetSizeOf(self->buf);
     969          if (s == (size_t)-1) {
     970              return NULL;
     971          }
     972          res += s;
     973      }
     974      return PyLong_FromSize_t(res);
     975  }
     976  
     977  static int
     978  bytesio_traverse(bytesio *self, visitproc visit, void *arg)
     979  {
     980      Py_VISIT(Py_TYPE(self));
     981      Py_VISIT(self->dict);
     982      Py_VISIT(self->buf);
     983      return 0;
     984  }
     985  
     986  static int
     987  bytesio_clear(bytesio *self)
     988  {
     989      Py_CLEAR(self->dict);
     990      Py_CLEAR(self->buf);
     991      return 0;
     992  }
     993  
     994  
     995  #define clinic_state() (find_io_state_by_def(Py_TYPE(self)))
     996  #include "clinic/bytesio.c.h"
     997  #undef clinic_state
     998  
     999  static PyGetSetDef bytesio_getsetlist[] = {
    1000      {"closed",  (getter)bytesio_get_closed, NULL,
    1001       "True if the file is closed."},
    1002      {NULL},            /* sentinel */
    1003  };
    1004  
    1005  static struct PyMethodDef bytesio_methods[] = {
    1006      _IO_BYTESIO_READABLE_METHODDEF
    1007      _IO_BYTESIO_SEEKABLE_METHODDEF
    1008      _IO_BYTESIO_WRITABLE_METHODDEF
    1009      _IO_BYTESIO_CLOSE_METHODDEF
    1010      _IO_BYTESIO_FLUSH_METHODDEF
    1011      _IO_BYTESIO_ISATTY_METHODDEF
    1012      _IO_BYTESIO_TELL_METHODDEF
    1013      _IO_BYTESIO_WRITE_METHODDEF
    1014      _IO_BYTESIO_WRITELINES_METHODDEF
    1015      _IO_BYTESIO_READ1_METHODDEF
    1016      _IO_BYTESIO_READINTO_METHODDEF
    1017      _IO_BYTESIO_READLINE_METHODDEF
    1018      _IO_BYTESIO_READLINES_METHODDEF
    1019      _IO_BYTESIO_READ_METHODDEF
    1020      _IO_BYTESIO_GETBUFFER_METHODDEF
    1021      _IO_BYTESIO_GETVALUE_METHODDEF
    1022      _IO_BYTESIO_SEEK_METHODDEF
    1023      _IO_BYTESIO_TRUNCATE_METHODDEF
    1024      {"__getstate__",  (PyCFunction)bytesio_getstate,  METH_NOARGS, NULL},
    1025      {"__setstate__",  (PyCFunction)bytesio_setstate,  METH_O, NULL},
    1026      {"__sizeof__", (PyCFunction)bytesio_sizeof,     METH_NOARGS, NULL},
    1027      {NULL, NULL}        /* sentinel */
    1028  };
    1029  
    1030  static PyMemberDef bytesio_members[] = {
    1031      {"__weaklistoffset__", T_PYSSIZET, offsetof(bytesio, weakreflist), READONLY},
    1032      {"__dictoffset__", T_PYSSIZET, offsetof(bytesio, dict), READONLY},
    1033      {NULL}
    1034  };
    1035  
    1036  static PyType_Slot bytesio_slots[] = {
    1037      {Py_tp_dealloc, bytesio_dealloc},
    1038      {Py_tp_doc, (void *)_io_BytesIO___init____doc__},
    1039      {Py_tp_traverse, bytesio_traverse},
    1040      {Py_tp_clear, bytesio_clear},
    1041      {Py_tp_iter, PyObject_SelfIter},
    1042      {Py_tp_iternext, bytesio_iternext},
    1043      {Py_tp_methods, bytesio_methods},
    1044      {Py_tp_members, bytesio_members},
    1045      {Py_tp_getset, bytesio_getsetlist},
    1046      {Py_tp_init, _io_BytesIO___init__},
    1047      {Py_tp_new, bytesio_new},
    1048      {0, NULL},
    1049  };
    1050  
    1051  PyType_Spec bytesio_spec = {
    1052      .name = "_io.BytesIO",
    1053      .basicsize = sizeof(bytesio),
    1054      .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
    1055                Py_TPFLAGS_IMMUTABLETYPE),
    1056      .slots = bytesio_slots,
    1057  };
    1058  
    1059  /*
    1060   * Implementation of the small intermediate object used by getbuffer().
    1061   * getbuffer() returns a memoryview over this object, which should make it
    1062   * invisible from Python code.
    1063   */
    1064  
    1065  static int
    1066  bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
    1067  {
    1068      bytesio *b = (bytesio *) obj->source;
    1069  
    1070      if (view == NULL) {
    1071          PyErr_SetString(PyExc_BufferError,
    1072              "bytesiobuf_getbuffer: view==NULL argument is obsolete");
    1073          return -1;
    1074      }
    1075      if (SHARED_BUF(b)) {
    1076          if (unshare_buffer(b, b->string_size) < 0)
    1077              return -1;
    1078      }
    1079  
    1080      /* cannot fail if view != NULL and readonly == 0 */
    1081      (void)PyBuffer_FillInfo(view, (PyObject*)obj,
    1082                              PyBytes_AS_STRING(b->buf), b->string_size,
    1083                              0, flags);
    1084      b->exports++;
    1085      return 0;
    1086  }
    1087  
    1088  static void
    1089  bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
    1090  {
    1091      bytesio *b = (bytesio *) obj->source;
    1092      b->exports--;
    1093  }
    1094  
    1095  static int
    1096  bytesiobuf_clear(bytesiobuf *self)
    1097  {
    1098      Py_CLEAR(self->source);
    1099      return 0;
    1100  }
    1101  
    1102  static int
    1103  bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
    1104  {
    1105      Py_VISIT(Py_TYPE(self));
    1106      Py_VISIT(self->source);
    1107      return 0;
    1108  }
    1109  
    1110  static void
    1111  bytesiobuf_dealloc(bytesiobuf *self)
    1112  {
    1113      PyTypeObject *tp = Py_TYPE(self);
    1114      /* bpo-31095: UnTrack is needed before calling any callbacks */
    1115      PyObject_GC_UnTrack(self);
    1116      (void)bytesiobuf_clear(self);
    1117      tp->tp_free(self);
    1118      Py_DECREF(tp);
    1119  }
    1120  
    1121  static PyType_Slot bytesiobuf_slots[] = {
    1122      {Py_tp_dealloc, bytesiobuf_dealloc},
    1123      {Py_tp_traverse, bytesiobuf_traverse},
    1124      {Py_tp_clear, bytesiobuf_clear},
    1125  
    1126      // Buffer protocol
    1127      {Py_bf_getbuffer, bytesiobuf_getbuffer},
    1128      {Py_bf_releasebuffer, bytesiobuf_releasebuffer},
    1129      {0, NULL},
    1130  };
    1131  
    1132  PyType_Spec bytesiobuf_spec = {
    1133      .name = "_io._BytesIOBuffer",
    1134      .basicsize = sizeof(bytesiobuf),
    1135      .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
    1136                Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
    1137      .slots = bytesiobuf_slots,
    1138  };