PageRenderTime 592ms CodeModel.GetById 232ms app.highlight 201ms RepoModel.GetById 151ms app.codeStats 1ms

/Modules/_bytesio.c

http://unladen-swallow.googlecode.com/
C | 763 lines | 598 code | 121 blank | 44 comment | 135 complexity | b78363ddd495e95edaffdef43611e9d0 MD5 | raw file
  1#include "Python.h"
  2
  3typedef struct {
  4    PyObject_HEAD
  5    char *buf;
  6    Py_ssize_t pos;
  7    Py_ssize_t string_size;
  8    size_t buf_size;
  9} BytesIOObject;
 10
 11#define CHECK_CLOSED(self)                                  \
 12    if ((self)->buf == NULL) {                              \
 13        PyErr_SetString(PyExc_ValueError,                   \
 14                        "I/O operation on closed file.");   \
 15        return NULL;                                        \
 16    }
 17
 18/* Internal routine to get a line from the buffer of a BytesIO
 19   object. Returns the length between the current position to the
 20   next newline character. */
 21static Py_ssize_t
 22get_line(BytesIOObject *self, char **output)
 23{
 24    char *n;
 25    const char *str_end;
 26    Py_ssize_t len;
 27
 28    assert(self->buf != NULL);
 29
 30    /* Move to the end of the line, up to the end of the string, s. */
 31    str_end = self->buf + self->string_size;
 32    for (n = self->buf + self->pos;
 33         n < str_end && *n != '\n';
 34         n++);
 35
 36    /* Skip the newline character */
 37    if (n < str_end)
 38        n++;
 39
 40    /* Get the length from the current position to the end of the line. */
 41    len = n - (self->buf + self->pos);
 42    *output = self->buf + self->pos;
 43
 44    assert(len >= 0);
 45    assert(self->pos < PY_SSIZE_T_MAX - len);
 46    self->pos += len;
 47
 48    return len;
 49}
 50
 51/* Internal routine for changing the size of the buffer of BytesIO objects.
 52   The caller should ensure that the 'size' argument is non-negative.  Returns
 53   0 on success, -1 otherwise. */
 54static int
 55resize_buffer(BytesIOObject *self, size_t size)
 56{
 57    /* Here, unsigned types are used to avoid dealing with signed integer
 58       overflow, which is undefined in C. */
 59    size_t alloc = self->buf_size;
 60    char *new_buf = NULL;
 61
 62    assert(self->buf != NULL);
 63
 64    /* For simplicity, stay in the range of the signed type. Anyway, Python
 65       doesn't allow strings to be longer than this. */
 66    if (size > PY_SSIZE_T_MAX)
 67        goto overflow;
 68
 69    if (size < alloc / 2) {
 70        /* Major downsize; resize down to exact size. */
 71        alloc = size + 1;
 72    }
 73    else if (size < alloc) {
 74        /* Within allocated size; quick exit */
 75        return 0;
 76    }
 77    else if (size <= alloc * 1.125) {
 78        /* Moderate upsize; overallocate similar to list_resize() */
 79        alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
 80    }
 81    else {
 82        /* Major upsize; resize up to exact size */
 83        alloc = size + 1;
 84    }
 85
 86    if (alloc > ((size_t)-1) / sizeof(char))
 87        goto overflow;
 88    new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char));
 89    if (new_buf == NULL) {
 90        PyErr_NoMemory();
 91        return -1;
 92    }
 93    self->buf_size = alloc;
 94    self->buf = new_buf;
 95
 96    return 0;
 97
 98  overflow:
 99    PyErr_SetString(PyExc_OverflowError,
100                    "new buffer size too large");
101    return -1;
102}
103
104/* Internal routine for writing a string of bytes to the buffer of a BytesIO
105   object. Returns the number of bytes wrote, or -1 on error. */
106static Py_ssize_t
107write_bytes(BytesIOObject *self, const char *bytes, Py_ssize_t len)
108{
109    assert(self->buf != NULL);
110    assert(self->pos >= 0);
111    assert(len >= 0);
112
113    if ((size_t)self->pos + len > self->buf_size) {
114        if (resize_buffer(self, (size_t)self->pos + len) < 0)
115            return -1;
116    }
117
118    if (self->pos > self->string_size) {
119        /* In case of overseek, pad with null bytes the buffer region between
120           the end of stream and the current position.
121
122          0   lo      string_size                           hi
123          |   |<---used--->|<----------available----------->|
124          |   |            <--to pad-->|<---to write--->    |
125          0   buf                   position
126        */
127        memset(self->buf + self->string_size, '\0',
128               (self->pos - self->string_size) * sizeof(char));
129    }
130
131    /* Copy the data to the internal buffer, overwriting some of the existing
132       data if self->pos < self->string_size. */
133    memcpy(self->buf + self->pos, bytes, len);
134    self->pos += len;
135
136    /* Set the new length of the internal string if it has changed. */
137    if (self->string_size < self->pos) {
138        self->string_size = self->pos;
139    }
140
141    return len;
142}
143
144static PyObject *
145bytesio_get_closed(BytesIOObject *self)
146{
147    if (self->buf == NULL)
148        Py_RETURN_TRUE;
149    else
150        Py_RETURN_FALSE;
151}
152
153/* Generic getter for the writable, readable and seekable properties */
154static PyObject *
155return_true(BytesIOObject *self)
156{
157    Py_RETURN_TRUE;
158}
159
160PyDoc_STRVAR(flush_doc,
161"flush() -> None.  Does nothing.");
162
163static PyObject *
164bytesio_flush(BytesIOObject *self)
165{
166    Py_RETURN_NONE;
167}
168
169PyDoc_STRVAR(getval_doc,
170"getvalue() -> bytes.\n"
171"\n"
172"Retrieve the entire contents of the BytesIO object.");
173
174static PyObject *
175bytesio_getvalue(BytesIOObject *self)
176{
177    CHECK_CLOSED(self);
178    return PyString_FromStringAndSize(self->buf, self->string_size);
179}
180
181PyDoc_STRVAR(isatty_doc,
182"isatty() -> False.\n"
183"\n"
184"Always returns False since BytesIO objects are not connected\n"
185"to a tty-like device.");
186
187static PyObject *
188bytesio_isatty(BytesIOObject *self)
189{
190    CHECK_CLOSED(self);
191    Py_RETURN_FALSE;
192}
193
194PyDoc_STRVAR(tell_doc,
195"tell() -> current file position, an integer\n");
196
197static PyObject *
198bytesio_tell(BytesIOObject *self)
199{
200    CHECK_CLOSED(self);
201    return PyInt_FromSsize_t(self->pos);
202}
203
204PyDoc_STRVAR(read_doc,
205"read([size]) -> read at most size bytes, returned as a string.\n"
206"\n"
207"If the size argument is negative, read until EOF is reached.\n"
208"Return an empty string at EOF.");
209
210static PyObject *
211bytesio_read(BytesIOObject *self, PyObject *args)
212{
213    Py_ssize_t size, n;
214    char *output;
215    PyObject *arg = Py_None;
216
217    CHECK_CLOSED(self);
218
219    if (!PyArg_ParseTuple(args, "|O:read", &arg))
220        return NULL;
221
222    if (PyInt_Check(arg)) {
223        size = PyInt_AsSsize_t(arg);
224        if (size == -1 && PyErr_Occurred())
225            return NULL;
226    }
227    else if (arg == Py_None) {
228        /* Read until EOF is reached, by default. */
229        size = -1;
230    }
231    else {
232        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
233                     Py_TYPE(arg)->tp_name);
234        return NULL;
235    }
236
237    /* adjust invalid sizes */
238    n = self->string_size - self->pos;
239    if (size < 0 || size > n) {
240        size = n;
241        if (size < 0)
242            size = 0;
243    }
244
245    assert(self->buf != NULL);
246    output = self->buf + self->pos;
247    self->pos += size;
248
249    return PyString_FromStringAndSize(output, size);
250}
251
252
253PyDoc_STRVAR(read1_doc,
254"read1(size) -> read at most size bytes, returned as a string.\n"
255"\n"
256"If the size argument is negative or omitted, read until EOF is reached.\n"
257"Return an empty string at EOF.");
258
259static PyObject *
260bytesio_read1(BytesIOObject *self, PyObject *n)
261{
262    PyObject *arg, *res;
263
264    arg = PyTuple_Pack(1, n);
265    if (arg == NULL)
266        return NULL;
267    res  = bytesio_read(self, arg);
268    Py_DECREF(arg);
269    return res;
270}
271
272PyDoc_STRVAR(readline_doc,
273"readline([size]) -> next line from the file, as a string.\n"
274"\n"
275"Retain newline.  A non-negative size argument limits the maximum\n"
276"number of bytes to return (an incomplete line may be returned then).\n"
277"Return an empty string at EOF.\n");
278
279static PyObject *
280bytesio_readline(BytesIOObject *self, PyObject *args)
281{
282    Py_ssize_t size, n;
283    char *output;
284    PyObject *arg = Py_None;
285
286    CHECK_CLOSED(self);
287
288    if (!PyArg_ParseTuple(args, "|O:readline", &arg))
289        return NULL;
290
291    if (PyInt_Check(arg)) {
292        size = PyInt_AsSsize_t(arg);
293        if (size == -1 && PyErr_Occurred())
294            return NULL;
295    }
296    else if (arg == Py_None) {
297        /* No size limit, by default. */
298        size = -1;
299    }
300    else {
301        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
302                     Py_TYPE(arg)->tp_name);
303        return NULL;
304    }
305
306    n = get_line(self, &output);
307
308    if (size >= 0 && size < n) {
309        size = n - size;
310        n -= size;
311        self->pos -= size;
312    }
313
314    return PyString_FromStringAndSize(output, n);
315}
316
317PyDoc_STRVAR(readlines_doc,
318"readlines([size]) -> list of strings, each a line from the file.\n"
319"\n"
320"Call readline() repeatedly and return a list of the lines so read.\n"
321"The optional size argument, if given, is an approximate bound on the\n"
322"total number of bytes in the lines returned.\n");
323
324static PyObject *
325bytesio_readlines(BytesIOObject *self, PyObject *args)
326{
327    Py_ssize_t maxsize, size, n;
328    PyObject *result, *line;
329    char *output;
330    PyObject *arg = Py_None;
331
332    CHECK_CLOSED(self);
333
334    if (!PyArg_ParseTuple(args, "|O:readlines", &arg))
335        return NULL;
336
337    if (PyInt_Check(arg)) {
338        maxsize = PyInt_AsSsize_t(arg);
339        if (maxsize == -1 && PyErr_Occurred())
340            return NULL;
341    }
342    else if (arg == Py_None) {
343        /* No size limit, by default. */
344        maxsize = -1;
345    }
346    else {
347        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
348                     Py_TYPE(arg)->tp_name);
349        return NULL;
350    }
351
352    size = 0;
353    result = PyList_New(0);
354    if (!result)
355        return NULL;
356
357    while ((n = get_line(self, &output)) != 0) {
358        line = PyString_FromStringAndSize(output, n);
359        if (!line)
360            goto on_error;
361        if (PyList_Append(result, line) == -1) {
362            Py_DECREF(line);
363            goto on_error;
364        }
365        Py_DECREF(line);
366        size += n;
367        if (maxsize > 0 && size >= maxsize)
368            break;
369    }
370    return result;
371
372  on_error:
373    Py_DECREF(result);
374    return NULL;
375}
376
377PyDoc_STRVAR(readinto_doc,
378"readinto(bytearray) -> int.  Read up to len(b) bytes into b.\n"
379"\n"
380"Returns number of bytes read (0 for EOF), or None if the object\n"
381"is set not to block as has no data to read.");
382
383static PyObject *
384bytesio_readinto(BytesIOObject *self, PyObject *buffer)
385{
386    void *raw_buffer;
387    Py_ssize_t len;
388
389    CHECK_CLOSED(self);
390
391    if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1)
392        return NULL;
393
394    if (self->pos + len > self->string_size)
395        len = self->string_size - self->pos;
396
397    memcpy(raw_buffer, self->buf + self->pos, len);
398    assert(self->pos + len < PY_SSIZE_T_MAX);
399    assert(len >= 0);
400    self->pos += len;
401
402    return PyInt_FromSsize_t(len);
403}
404
405PyDoc_STRVAR(truncate_doc,
406"truncate([size]) -> int.  Truncate the file to at most size bytes.\n"
407"\n"
408"Size defaults to the current file position, as returned by tell().\n"
409"Returns the new size.  Imply an absolute seek to the position size.");
410
411static PyObject *
412bytesio_truncate(BytesIOObject *self, PyObject *args)
413{
414    Py_ssize_t size;
415    PyObject *arg = Py_None;
416
417    CHECK_CLOSED(self);
418
419    if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
420        return NULL;
421
422    if (PyInt_Check(arg)) {
423        size = PyInt_AsSsize_t(arg);
424        if (size == -1 && PyErr_Occurred())
425            return NULL;
426    }
427    else if (arg == Py_None) {
428        /* Truncate to current position if no argument is passed. */
429        size = self->pos;
430    }
431    else {
432        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
433                     Py_TYPE(arg)->tp_name);
434        return NULL;
435    }
436
437    if (size < 0) {
438        PyErr_Format(PyExc_ValueError,
439                     "negative size value %zd", size);
440        return NULL;
441    }
442
443    if (size < self->string_size) {
444        self->string_size = size;
445        if (resize_buffer(self, size) < 0)
446            return NULL;
447    }
448    self->pos = size;
449
450    return PyInt_FromSsize_t(size);
451}
452
453static PyObject *
454bytesio_iternext(BytesIOObject *self)
455{
456    char *next;
457    Py_ssize_t n;
458
459    CHECK_CLOSED(self);
460
461    n = get_line(self, &next);
462
463    if (!next || n == 0)
464        return NULL;
465
466    return PyString_FromStringAndSize(next, n);
467}
468
469PyDoc_STRVAR(seek_doc,
470"seek(pos, whence=0) -> int.  Change stream position.\n"
471"\n"
472"Seek to byte offset pos relative to position indicated by whence:\n"
473"     0  Start of stream (the default).  pos should be >= 0;\n"
474"     1  Current position - pos may be negative;\n"
475"     2  End of stream - pos usually negative.\n"
476"Returns the new absolute position.");
477
478static PyObject *
479bytesio_seek(BytesIOObject *self, PyObject *args)
480{
481    PyObject *pos_obj, *mode_obj;
482    Py_ssize_t pos;
483    int mode = 0;
484
485    CHECK_CLOSED(self);
486
487    /* Special-case for 2.x to prevent floats from passing through.
488       This only needed to make a test in test_io succeed. */
489    if (!PyArg_UnpackTuple(args, "seek", 1, 2, &pos_obj, &mode_obj))
490        return NULL;
491    if (PyFloat_Check(pos_obj)) {
492        PyErr_SetString(PyExc_TypeError,
493                        "position argument must be an integer");
494        return NULL;
495    }
496
497    if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode))
498        return NULL;
499
500    if (pos < 0 && mode == 0) {
501        PyErr_Format(PyExc_ValueError,
502                     "negative seek value %zd", pos);
503        return NULL;
504    }
505
506    /* mode 0: offset relative to beginning of the string.
507       mode 1: offset relative to current position.
508       mode 2: offset relative the end of the string. */
509    if (mode == 1) {
510        if (pos > PY_SSIZE_T_MAX - self->pos) {
511            PyErr_SetString(PyExc_OverflowError,
512                            "new position too large");
513            return NULL;
514        }
515        pos += self->pos;
516    }
517    else if (mode == 2) {
518        if (pos > PY_SSIZE_T_MAX - self->string_size) {
519            PyErr_SetString(PyExc_OverflowError,
520                            "new position too large");
521            return NULL;
522        }
523        pos += self->string_size;
524    }
525    else if (mode != 0) {
526        PyErr_Format(PyExc_ValueError,
527                     "invalid whence (%i, should be 0, 1 or 2)", mode);
528        return NULL;
529    }
530
531    if (pos < 0)
532        pos = 0;
533    self->pos = pos;
534
535    return PyInt_FromSsize_t(self->pos);
536}
537
538PyDoc_STRVAR(write_doc,
539"write(bytes) -> int.  Write bytes to file.\n"
540"\n"
541"Return the number of bytes written.");
542
543static PyObject *
544bytesio_write(BytesIOObject *self, PyObject *obj)
545{
546    const char *bytes;
547    Py_ssize_t size;
548    Py_ssize_t n = 0;
549
550    CHECK_CLOSED(self);
551
552    /* Special-case in 2.x to prevent unicode objects to pass through. */
553    if (PyUnicode_Check(obj)) {
554	    PyErr_SetString(PyExc_TypeError,
555                        "expecting a bytes object, got unicode");
556        return NULL;
557    }
558
559    if (PyObject_AsReadBuffer(obj, (void *)&bytes, &size) < 0)
560        return NULL;
561
562    if (size != 0) {
563        n = write_bytes(self, bytes, size);
564        if (n < 0)
565            return NULL;
566    }
567
568    return PyInt_FromSsize_t(n);
569}
570
571PyDoc_STRVAR(writelines_doc,
572"writelines(sequence_of_strings) -> None.  Write strings to the file.\n"
573"\n"
574"Note that newlines are not added.  The sequence can be any iterable\n"
575"object producing strings. This is equivalent to calling write() for\n"
576"each string.");
577
578static PyObject *
579bytesio_writelines(BytesIOObject *self, PyObject *v)
580{
581    PyObject *it, *item;
582    PyObject *ret;
583
584    CHECK_CLOSED(self);
585
586    it = PyObject_GetIter(v);
587    if (it == NULL)
588        return NULL;
589
590    while ((item = PyIter_Next(it)) != NULL) {
591        ret = bytesio_write(self, item);
592        Py_DECREF(item);
593        if (ret == NULL) {
594            Py_DECREF(it);
595            return NULL;
596        }
597        Py_DECREF(ret);
598    }
599    Py_DECREF(it);
600
601    /* See if PyIter_Next failed */
602    if (PyErr_Occurred())
603        return NULL;
604
605    Py_RETURN_NONE;
606}
607
608PyDoc_STRVAR(close_doc,
609"close() -> None.  Disable all I/O operations.");
610
611static PyObject *
612bytesio_close(BytesIOObject *self)
613{
614    if (self->buf != NULL) {
615        PyMem_Free(self->buf);
616        self->buf = NULL;
617    }
618    Py_RETURN_NONE;
619}
620
621static void
622bytesio_dealloc(BytesIOObject *self)
623{
624    if (self->buf != NULL) {
625        PyMem_Free(self->buf);
626        self->buf = NULL;
627    }
628    Py_TYPE(self)->tp_free(self);
629}
630
631static PyObject *
632bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
633{
634    BytesIOObject *self;
635
636    assert(type != NULL && type->tp_alloc != NULL);
637    self = (BytesIOObject *)type->tp_alloc(type, 0);
638    if (self == NULL)
639        return NULL;
640
641    self->string_size = 0;
642    self->pos = 0;
643    self->buf_size = 0;
644    self->buf = (char *)PyMem_Malloc(0);
645    if (self->buf == NULL) {
646        Py_DECREF(self);
647        return PyErr_NoMemory();
648    }
649
650    return (PyObject *)self;
651}
652
653static int
654bytesio_init(BytesIOObject *self, PyObject *args, PyObject *kwds)
655{
656    PyObject *initvalue = NULL;
657
658    if (!PyArg_ParseTuple(args, "|O:BytesIO", &initvalue))
659        return -1;
660
661    /* In case, __init__ is called multiple times. */
662    self->string_size = 0;
663    self->pos = 0;
664
665    if (initvalue && initvalue != Py_None) {
666        PyObject *res;
667        res = bytesio_write(self, initvalue);
668        if (res == NULL)
669            return -1;
670        Py_DECREF(res);
671        self->pos = 0;
672    }
673
674    return 0;
675}
676
677static PyGetSetDef bytesio_getsetlist[] = {
678    {"closed",  (getter)bytesio_get_closed, NULL,
679     "True if the file is closed."},
680    {0},            /* sentinel */
681};
682
683static struct PyMethodDef bytesio_methods[] = {
684    {"readable",   (PyCFunction)return_true,        METH_NOARGS, NULL},
685    {"seekable",   (PyCFunction)return_true,        METH_NOARGS, NULL},
686    {"writable",   (PyCFunction)return_true,        METH_NOARGS, NULL},
687    {"close",      (PyCFunction)bytesio_close,      METH_NOARGS, close_doc},
688    {"flush",      (PyCFunction)bytesio_flush,      METH_NOARGS, flush_doc},
689    {"isatty",     (PyCFunction)bytesio_isatty,     METH_NOARGS, isatty_doc},
690    {"tell",       (PyCFunction)bytesio_tell,       METH_NOARGS, tell_doc},
691    {"write",      (PyCFunction)bytesio_write,      METH_O, write_doc},
692    {"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc},
693    {"read1",      (PyCFunction)bytesio_read1,      METH_O, read1_doc},
694    {"readinto",   (PyCFunction)bytesio_readinto,   METH_O, readinto_doc},
695    {"readline",   (PyCFunction)bytesio_readline,   METH_VARARGS, readline_doc},
696    {"readlines",  (PyCFunction)bytesio_readlines,  METH_VARARGS, readlines_doc},
697    {"read",       (PyCFunction)bytesio_read,       METH_VARARGS, read_doc},
698    {"getvalue",   (PyCFunction)bytesio_getvalue,   METH_VARARGS, getval_doc},
699    {"seek",       (PyCFunction)bytesio_seek,       METH_VARARGS, seek_doc},
700    {"truncate",   (PyCFunction)bytesio_truncate,   METH_VARARGS, truncate_doc},
701    {NULL, NULL}        /* sentinel */
702};
703
704PyDoc_STRVAR(bytesio_doc,
705"BytesIO([buffer]) -> object\n"
706"\n"
707"Create a buffered I/O implementation using an in-memory bytes\n"
708"buffer, ready for reading and writing.");
709
710static PyTypeObject BytesIO_Type = {
711    PyVarObject_HEAD_INIT(NULL, 0)
712    "_bytesio._BytesIO",                       /*tp_name*/
713    sizeof(BytesIOObject),                     /*tp_basicsize*/
714    0,                                         /*tp_itemsize*/
715    (destructor)bytesio_dealloc,               /*tp_dealloc*/
716    0,                                         /*tp_print*/
717    0,                                         /*tp_getattr*/
718    0,                                         /*tp_setattr*/
719    0,                                         /*tp_compare*/
720    0,                                         /*tp_repr*/
721    0,                                         /*tp_as_number*/
722    0,                                         /*tp_as_sequence*/
723    0,                                         /*tp_as_mapping*/
724    0,                                         /*tp_hash*/
725    0,                                         /*tp_call*/
726    0,                                         /*tp_str*/
727    0,                                         /*tp_getattro*/
728    0,                                         /*tp_setattro*/
729    0,                                         /*tp_as_buffer*/
730    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
731    bytesio_doc,                               /*tp_doc*/
732    0,                                         /*tp_traverse*/
733    0,                                         /*tp_clear*/
734    0,                                         /*tp_richcompare*/
735    0,                                         /*tp_weaklistoffset*/
736    PyObject_SelfIter,                         /*tp_iter*/
737    (iternextfunc)bytesio_iternext,            /*tp_iternext*/
738    bytesio_methods,                           /*tp_methods*/
739    0,                                         /*tp_members*/
740    bytesio_getsetlist,                        /*tp_getset*/
741    0,                                         /*tp_base*/
742    0,                                         /*tp_dict*/
743    0,                                         /*tp_descr_get*/
744    0,                                         /*tp_descr_set*/
745    0,                                         /*tp_dictoffset*/
746    (initproc)bytesio_init,                    /*tp_init*/
747    0,                                         /*tp_alloc*/
748    bytesio_new,                               /*tp_new*/
749};
750
751PyMODINIT_FUNC
752init_bytesio(void)
753{
754    PyObject *m;
755
756    if (PyType_Ready(&BytesIO_Type) < 0)
757        return;
758    m = Py_InitModule("_bytesio", NULL);
759    if (m == NULL)
760        return;
761    Py_INCREF(&BytesIO_Type);
762    PyModule_AddObject(m, "_BytesIO", (PyObject *)&BytesIO_Type);
763}