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