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