/src/Python-3.8.3/Modules/_io/iobase.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | An implementation of the I/O abstract base classes hierarchy |
3 | | as defined by PEP 3116 - "New I/O" |
4 | | |
5 | | Classes defined here: IOBase, RawIOBase. |
6 | | |
7 | | Written by Amaury Forgeot d'Arc and Antoine Pitrou |
8 | | */ |
9 | | |
10 | | |
11 | | #define PY_SSIZE_T_CLEAN |
12 | | #include "Python.h" |
13 | | #include "pycore_object.h" |
14 | | #include "structmember.h" |
15 | | #include "_iomodule.h" |
16 | | |
17 | | /*[clinic input] |
18 | | module _io |
19 | | class _io._IOBase "PyObject *" "&PyIOBase_Type" |
20 | | class _io._RawIOBase "PyObject *" "&PyRawIOBase_Type" |
21 | | [clinic start generated code]*/ |
22 | | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=d29a4d076c2b211c]*/ |
23 | | |
24 | | /* |
25 | | * IOBase class, an abstract class |
26 | | */ |
27 | | |
28 | | typedef struct { |
29 | | PyObject_HEAD |
30 | | |
31 | | PyObject *dict; |
32 | | PyObject *weakreflist; |
33 | | } iobase; |
34 | | |
35 | | PyDoc_STRVAR(iobase_doc, |
36 | | "The abstract base class for all I/O classes, acting on streams of\n" |
37 | | "bytes. There is no public constructor.\n" |
38 | | "\n" |
39 | | "This class provides dummy implementations for many methods that\n" |
40 | | "derived classes can override selectively; the default implementations\n" |
41 | | "represent a file that cannot be read, written or seeked.\n" |
42 | | "\n" |
43 | | "Even though IOBase does not declare read, readinto, or write because\n" |
44 | | "their signatures will vary, implementations and clients should\n" |
45 | | "consider those methods part of the interface. Also, implementations\n" |
46 | | "may raise UnsupportedOperation when operations they do not support are\n" |
47 | | "called.\n" |
48 | | "\n" |
49 | | "The basic type used for binary data read from or written to a file is\n" |
50 | | "bytes. Other bytes-like objects are accepted as method arguments too.\n" |
51 | | "In some cases (such as readinto), a writable object is required. Text\n" |
52 | | "I/O classes work with str data.\n" |
53 | | "\n" |
54 | | "Note that calling any method (except additional calls to close(),\n" |
55 | | "which are ignored) on a closed stream should raise a ValueError.\n" |
56 | | "\n" |
57 | | "IOBase (and its subclasses) support the iterator protocol, meaning\n" |
58 | | "that an IOBase object can be iterated over yielding the lines in a\n" |
59 | | "stream.\n" |
60 | | "\n" |
61 | | "IOBase also supports the :keyword:`with` statement. In this example,\n" |
62 | | "fp is closed after the suite of the with statement is complete:\n" |
63 | | "\n" |
64 | | "with open('spam.txt', 'r') as fp:\n" |
65 | | " fp.write('Spam and eggs!')\n"); |
66 | | |
67 | | /* Use this macro whenever you want to check the internal `closed` status |
68 | | of the IOBase object rather than the virtual `closed` attribute as returned |
69 | | by whatever subclass. */ |
70 | | |
71 | | _Py_IDENTIFIER(__IOBase_closed); |
72 | | _Py_IDENTIFIER(read); |
73 | | |
74 | | |
75 | | /* Internal methods */ |
76 | | static PyObject * |
77 | | iobase_unsupported(const char *message) |
78 | 0 | { |
79 | 0 | _PyIO_State *state = IO_STATE(); |
80 | 0 | if (state != NULL) |
81 | 0 | PyErr_SetString(state->unsupported_operation, message); |
82 | 0 | return NULL; |
83 | 0 | } |
84 | | |
85 | | /* Positioning */ |
86 | | |
87 | | PyDoc_STRVAR(iobase_seek_doc, |
88 | | "Change stream position.\n" |
89 | | "\n" |
90 | | "Change the stream position to the given byte offset. The offset is\n" |
91 | | "interpreted relative to the position indicated by whence. Values\n" |
92 | | "for whence are:\n" |
93 | | "\n" |
94 | | "* 0 -- start of stream (the default); offset should be zero or positive\n" |
95 | | "* 1 -- current stream position; offset may be negative\n" |
96 | | "* 2 -- end of stream; offset is usually negative\n" |
97 | | "\n" |
98 | | "Return the new absolute position."); |
99 | | |
100 | | static PyObject * |
101 | | iobase_seek(PyObject *self, PyObject *args) |
102 | 0 | { |
103 | 0 | return iobase_unsupported("seek"); |
104 | 0 | } |
105 | | |
106 | | /*[clinic input] |
107 | | _io._IOBase.tell |
108 | | |
109 | | Return current stream position. |
110 | | [clinic start generated code]*/ |
111 | | |
112 | | static PyObject * |
113 | | _io__IOBase_tell_impl(PyObject *self) |
114 | | /*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/ |
115 | 0 | { |
116 | 0 | _Py_IDENTIFIER(seek); |
117 | |
|
118 | 0 | return _PyObject_CallMethodId(self, &PyId_seek, "ii", 0, 1); |
119 | 0 | } |
120 | | |
121 | | PyDoc_STRVAR(iobase_truncate_doc, |
122 | | "Truncate file to size bytes.\n" |
123 | | "\n" |
124 | | "File pointer is left unchanged. Size defaults to the current IO\n" |
125 | | "position as reported by tell(). Returns the new size."); |
126 | | |
127 | | static PyObject * |
128 | | iobase_truncate(PyObject *self, PyObject *args) |
129 | 0 | { |
130 | 0 | return iobase_unsupported("truncate"); |
131 | 0 | } |
132 | | |
133 | | static int |
134 | | iobase_is_closed(PyObject *self) |
135 | 709 | { |
136 | 709 | PyObject *res; |
137 | 709 | int ret; |
138 | | /* This gets the derived attribute, which is *not* __IOBase_closed |
139 | | in most cases! */ |
140 | 709 | ret = _PyObject_LookupAttrId(self, &PyId___IOBase_closed, &res); |
141 | 709 | Py_XDECREF(res); |
142 | 709 | return ret; |
143 | 709 | } |
144 | | |
145 | | /* Flush and close methods */ |
146 | | |
147 | | /*[clinic input] |
148 | | _io._IOBase.flush |
149 | | |
150 | | Flush write buffers, if applicable. |
151 | | |
152 | | This is not implemented for read-only and non-blocking streams. |
153 | | [clinic start generated code]*/ |
154 | | |
155 | | static PyObject * |
156 | | _io__IOBase_flush_impl(PyObject *self) |
157 | | /*[clinic end generated code: output=7cef4b4d54656a3b input=773be121abe270aa]*/ |
158 | 473 | { |
159 | | /* XXX Should this return the number of bytes written??? */ |
160 | 473 | int closed = iobase_is_closed(self); |
161 | | |
162 | 473 | if (!closed) { |
163 | 473 | Py_RETURN_NONE; |
164 | 473 | } |
165 | 0 | if (closed > 0) { |
166 | 0 | PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); |
167 | 0 | } |
168 | 0 | return NULL; |
169 | 473 | } |
170 | | |
171 | | static PyObject * |
172 | | iobase_closed_get(PyObject *self, void *context) |
173 | 0 | { |
174 | 0 | int closed = iobase_is_closed(self); |
175 | 0 | if (closed < 0) { |
176 | 0 | return NULL; |
177 | 0 | } |
178 | 0 | return PyBool_FromLong(closed); |
179 | 0 | } |
180 | | |
181 | | static int |
182 | | iobase_check_closed(PyObject *self) |
183 | 237 | { |
184 | 237 | PyObject *res; |
185 | 237 | int closed; |
186 | | /* This gets the derived attribute, which is *not* __IOBase_closed |
187 | | in most cases! */ |
188 | 237 | closed = _PyObject_LookupAttr(self, _PyIO_str_closed, &res); |
189 | 237 | if (closed > 0) { |
190 | 237 | closed = PyObject_IsTrue(res); |
191 | 237 | Py_DECREF(res); |
192 | 237 | if (closed > 0) { |
193 | 0 | PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); |
194 | 0 | return -1; |
195 | 0 | } |
196 | 237 | } |
197 | 237 | return closed; |
198 | 237 | } |
199 | | |
200 | | PyObject * |
201 | | _PyIOBase_check_closed(PyObject *self, PyObject *args) |
202 | 0 | { |
203 | 0 | if (iobase_check_closed(self)) { |
204 | 0 | return NULL; |
205 | 0 | } |
206 | 0 | if (args == Py_True) { |
207 | 0 | return Py_None; |
208 | 0 | } |
209 | 0 | Py_RETURN_NONE; |
210 | 0 | } |
211 | | |
212 | | /* XXX: IOBase thinks it has to maintain its own internal state in |
213 | | `__IOBase_closed` and call flush() by itself, but it is redundant with |
214 | | whatever behaviour a non-trivial derived class will implement. */ |
215 | | |
216 | | /*[clinic input] |
217 | | _io._IOBase.close |
218 | | |
219 | | Flush and close the IO object. |
220 | | |
221 | | This method has no effect if the file is already closed. |
222 | | [clinic start generated code]*/ |
223 | | |
224 | | static PyObject * |
225 | | _io__IOBase_close_impl(PyObject *self) |
226 | | /*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/ |
227 | 236 | { |
228 | 236 | PyObject *res, *exc, *val, *tb; |
229 | 236 | int rc, closed = iobase_is_closed(self); |
230 | | |
231 | 236 | if (closed < 0) { |
232 | 0 | return NULL; |
233 | 0 | } |
234 | 236 | if (closed) { |
235 | 0 | Py_RETURN_NONE; |
236 | 0 | } |
237 | | |
238 | 236 | res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL); |
239 | | |
240 | 236 | PyErr_Fetch(&exc, &val, &tb); |
241 | 236 | rc = _PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True); |
242 | 236 | _PyErr_ChainExceptions(exc, val, tb); |
243 | 236 | if (rc < 0) { |
244 | 0 | Py_CLEAR(res); |
245 | 0 | } |
246 | | |
247 | 236 | if (res == NULL) |
248 | 0 | return NULL; |
249 | | |
250 | 236 | Py_DECREF(res); |
251 | 236 | Py_RETURN_NONE; |
252 | 236 | } |
253 | | |
254 | | /* Finalization and garbage collection support */ |
255 | | |
256 | | static void |
257 | | iobase_finalize(PyObject *self) |
258 | 473 | { |
259 | 473 | PyObject *res; |
260 | 473 | PyObject *error_type, *error_value, *error_traceback; |
261 | 473 | int closed; |
262 | 473 | _Py_IDENTIFIER(_finalizing); |
263 | | |
264 | | /* Save the current exception, if any. */ |
265 | 473 | PyErr_Fetch(&error_type, &error_value, &error_traceback); |
266 | | |
267 | | /* If `closed` doesn't exist or can't be evaluated as bool, then the |
268 | | object is probably in an unusable state, so ignore. */ |
269 | 473 | if (_PyObject_LookupAttr(self, _PyIO_str_closed, &res) <= 0) { |
270 | 0 | PyErr_Clear(); |
271 | 0 | closed = -1; |
272 | 0 | } |
273 | 473 | else { |
274 | 473 | closed = PyObject_IsTrue(res); |
275 | 473 | Py_DECREF(res); |
276 | 473 | if (closed == -1) |
277 | 0 | PyErr_Clear(); |
278 | 473 | } |
279 | 473 | if (closed == 0) { |
280 | | /* Signal close() that it was called as part of the object |
281 | | finalization process. */ |
282 | 0 | if (_PyObject_SetAttrId(self, &PyId__finalizing, Py_True)) |
283 | 0 | PyErr_Clear(); |
284 | 0 | res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close, |
285 | 0 | NULL); |
286 | | /* Silencing I/O errors is bad, but printing spurious tracebacks is |
287 | | equally as bad, and potentially more frequent (because of |
288 | | shutdown issues). */ |
289 | 0 | if (res == NULL) { |
290 | 0 | #ifndef Py_DEBUG |
291 | 0 | const PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; |
292 | 0 | if (config->dev_mode) { |
293 | 0 | PyErr_WriteUnraisable(self); |
294 | 0 | } |
295 | 0 | else { |
296 | 0 | PyErr_Clear(); |
297 | 0 | } |
298 | | #else |
299 | | PyErr_WriteUnraisable(self); |
300 | | #endif |
301 | 0 | } |
302 | 0 | else { |
303 | 0 | Py_DECREF(res); |
304 | 0 | } |
305 | 0 | } |
306 | | |
307 | | /* Restore the saved exception. */ |
308 | 473 | PyErr_Restore(error_type, error_value, error_traceback); |
309 | 473 | } |
310 | | |
311 | | int |
312 | | _PyIOBase_finalize(PyObject *self) |
313 | 473 | { |
314 | 473 | int is_zombie; |
315 | | |
316 | | /* If _PyIOBase_finalize() is called from a destructor, we need to |
317 | | resurrect the object as calling close() can invoke arbitrary code. */ |
318 | 473 | is_zombie = (Py_REFCNT(self) == 0); |
319 | 473 | if (is_zombie) |
320 | 473 | return PyObject_CallFinalizerFromDealloc(self); |
321 | 0 | else { |
322 | 0 | PyObject_CallFinalizer(self); |
323 | 0 | return 0; |
324 | 0 | } |
325 | 473 | } |
326 | | |
327 | | static int |
328 | | iobase_traverse(iobase *self, visitproc visit, void *arg) |
329 | 0 | { |
330 | 0 | Py_VISIT(self->dict); |
331 | 0 | return 0; |
332 | 0 | } |
333 | | |
334 | | static int |
335 | | iobase_clear(iobase *self) |
336 | 0 | { |
337 | 0 | Py_CLEAR(self->dict); |
338 | 0 | return 0; |
339 | 0 | } |
340 | | |
341 | | /* Destructor */ |
342 | | |
343 | | static void |
344 | | iobase_dealloc(iobase *self) |
345 | 0 | { |
346 | | /* NOTE: since IOBaseObject has its own dict, Python-defined attributes |
347 | | are still available here for close() to use. |
348 | | However, if the derived class declares a __slots__, those slots are |
349 | | already gone. |
350 | | */ |
351 | 0 | if (_PyIOBase_finalize((PyObject *) self) < 0) { |
352 | | /* When called from a heap type's dealloc, the type will be |
353 | | decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */ |
354 | 0 | if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) |
355 | 0 | Py_INCREF(Py_TYPE(self)); |
356 | 0 | return; |
357 | 0 | } |
358 | 0 | _PyObject_GC_UNTRACK(self); |
359 | 0 | if (self->weakreflist != NULL) |
360 | 0 | PyObject_ClearWeakRefs((PyObject *) self); |
361 | 0 | Py_CLEAR(self->dict); |
362 | 0 | Py_TYPE(self)->tp_free((PyObject *) self); |
363 | 0 | } |
364 | | |
365 | | /* Inquiry methods */ |
366 | | |
367 | | /*[clinic input] |
368 | | _io._IOBase.seekable |
369 | | |
370 | | Return whether object supports random access. |
371 | | |
372 | | If False, seek(), tell() and truncate() will raise OSError. |
373 | | This method may need to do a test seek(). |
374 | | [clinic start generated code]*/ |
375 | | |
376 | | static PyObject * |
377 | | _io__IOBase_seekable_impl(PyObject *self) |
378 | | /*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/ |
379 | 0 | { |
380 | 0 | Py_RETURN_FALSE; |
381 | 0 | } |
382 | | |
383 | | PyObject * |
384 | | _PyIOBase_check_seekable(PyObject *self, PyObject *args) |
385 | 1 | { |
386 | 1 | PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL); |
387 | 1 | if (res == NULL) |
388 | 0 | return NULL; |
389 | 1 | if (res != Py_True) { |
390 | 0 | Py_CLEAR(res); |
391 | 0 | iobase_unsupported("File or stream is not seekable."); |
392 | 0 | return NULL; |
393 | 0 | } |
394 | 1 | if (args == Py_True) { |
395 | 1 | Py_DECREF(res); |
396 | 1 | } |
397 | 1 | return res; |
398 | 1 | } |
399 | | |
400 | | /*[clinic input] |
401 | | _io._IOBase.readable |
402 | | |
403 | | Return whether object was opened for reading. |
404 | | |
405 | | If False, read() will raise OSError. |
406 | | [clinic start generated code]*/ |
407 | | |
408 | | static PyObject * |
409 | | _io__IOBase_readable_impl(PyObject *self) |
410 | | /*[clinic end generated code: output=e48089250686388b input=285b3b866a0ec35f]*/ |
411 | 28 | { |
412 | 28 | Py_RETURN_FALSE; |
413 | 28 | } |
414 | | |
415 | | /* May be called with any object */ |
416 | | PyObject * |
417 | | _PyIOBase_check_readable(PyObject *self, PyObject *args) |
418 | 250 | { |
419 | 250 | PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL); |
420 | 250 | if (res == NULL) |
421 | 0 | return NULL; |
422 | 250 | if (res != Py_True) { |
423 | 0 | Py_CLEAR(res); |
424 | 0 | iobase_unsupported("File or stream is not readable."); |
425 | 0 | return NULL; |
426 | 0 | } |
427 | 250 | if (args == Py_True) { |
428 | 250 | Py_DECREF(res); |
429 | 250 | } |
430 | 250 | return res; |
431 | 250 | } |
432 | | |
433 | | /*[clinic input] |
434 | | _io._IOBase.writable |
435 | | |
436 | | Return whether object was opened for writing. |
437 | | |
438 | | If False, write() will raise OSError. |
439 | | [clinic start generated code]*/ |
440 | | |
441 | | static PyObject * |
442 | | _io__IOBase_writable_impl(PyObject *self) |
443 | | /*[clinic end generated code: output=406001d0985be14f input=9dcac18a013a05b5]*/ |
444 | 15 | { |
445 | 15 | Py_RETURN_FALSE; |
446 | 15 | } |
447 | | |
448 | | /* May be called with any object */ |
449 | | PyObject * |
450 | | _PyIOBase_check_writable(PyObject *self, PyObject *args) |
451 | 28 | { |
452 | 28 | PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL); |
453 | 28 | if (res == NULL) |
454 | 0 | return NULL; |
455 | 28 | if (res != Py_True) { |
456 | 0 | Py_CLEAR(res); |
457 | 0 | iobase_unsupported("File or stream is not writable."); |
458 | 0 | return NULL; |
459 | 0 | } |
460 | 28 | if (args == Py_True) { |
461 | 28 | Py_DECREF(res); |
462 | 28 | } |
463 | 28 | return res; |
464 | 28 | } |
465 | | |
466 | | /* Context manager */ |
467 | | |
468 | | static PyObject * |
469 | | iobase_enter(PyObject *self, PyObject *args) |
470 | 236 | { |
471 | 236 | if (iobase_check_closed(self)) |
472 | 0 | return NULL; |
473 | | |
474 | 236 | Py_INCREF(self); |
475 | 236 | return self; |
476 | 236 | } |
477 | | |
478 | | static PyObject * |
479 | | iobase_exit(PyObject *self, PyObject *args) |
480 | 236 | { |
481 | 236 | return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL); |
482 | 236 | } |
483 | | |
484 | | /* Lower-level APIs */ |
485 | | |
486 | | /* XXX Should these be present even if unimplemented? */ |
487 | | |
488 | | /*[clinic input] |
489 | | _io._IOBase.fileno |
490 | | |
491 | | Returns underlying file descriptor if one exists. |
492 | | |
493 | | OSError is raised if the IO object does not use a file descriptor. |
494 | | [clinic start generated code]*/ |
495 | | |
496 | | static PyObject * |
497 | | _io__IOBase_fileno_impl(PyObject *self) |
498 | | /*[clinic end generated code: output=7cc0973f0f5f3b73 input=4e37028947dc1cc8]*/ |
499 | 0 | { |
500 | 0 | return iobase_unsupported("fileno"); |
501 | 0 | } |
502 | | |
503 | | /*[clinic input] |
504 | | _io._IOBase.isatty |
505 | | |
506 | | Return whether this is an 'interactive' stream. |
507 | | |
508 | | Return False if it can't be determined. |
509 | | [clinic start generated code]*/ |
510 | | |
511 | | static PyObject * |
512 | | _io__IOBase_isatty_impl(PyObject *self) |
513 | | /*[clinic end generated code: output=60cab77cede41cdd input=9ef76530d368458b]*/ |
514 | 0 | { |
515 | 0 | if (iobase_check_closed(self)) |
516 | 0 | return NULL; |
517 | 0 | Py_RETURN_FALSE; |
518 | 0 | } |
519 | | |
520 | | /* Readline(s) and writelines */ |
521 | | |
522 | | /*[clinic input] |
523 | | _io._IOBase.readline |
524 | | size as limit: Py_ssize_t(accept={int, NoneType}) = -1 |
525 | | / |
526 | | |
527 | | Read and return a line from the stream. |
528 | | |
529 | | If size is specified, at most size bytes will be read. |
530 | | |
531 | | The line terminator is always b'\n' for binary files; for text |
532 | | files, the newlines argument to open can be used to select the line |
533 | | terminator(s) recognized. |
534 | | [clinic start generated code]*/ |
535 | | |
536 | | static PyObject * |
537 | | _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) |
538 | | /*[clinic end generated code: output=4479f79b58187840 input=d0c596794e877bff]*/ |
539 | 0 | { |
540 | | /* For backwards compatibility, a (slowish) readline(). */ |
541 | |
|
542 | 0 | PyObject *peek, *buffer, *result; |
543 | 0 | Py_ssize_t old_size = -1; |
544 | |
|
545 | 0 | if (_PyObject_LookupAttr(self, _PyIO_str_peek, &peek) < 0) { |
546 | 0 | return NULL; |
547 | 0 | } |
548 | | |
549 | 0 | buffer = PyByteArray_FromStringAndSize(NULL, 0); |
550 | 0 | if (buffer == NULL) { |
551 | 0 | Py_XDECREF(peek); |
552 | 0 | return NULL; |
553 | 0 | } |
554 | | |
555 | 0 | while (limit < 0 || PyByteArray_GET_SIZE(buffer) < limit) { |
556 | 0 | Py_ssize_t nreadahead = 1; |
557 | 0 | PyObject *b; |
558 | |
|
559 | 0 | if (peek != NULL) { |
560 | 0 | PyObject *readahead = PyObject_CallFunctionObjArgs(peek, _PyLong_One, NULL); |
561 | 0 | if (readahead == NULL) { |
562 | | /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() |
563 | | when EINTR occurs so we needn't do it ourselves. */ |
564 | 0 | if (_PyIO_trap_eintr()) { |
565 | 0 | continue; |
566 | 0 | } |
567 | 0 | goto fail; |
568 | 0 | } |
569 | 0 | if (!PyBytes_Check(readahead)) { |
570 | 0 | PyErr_Format(PyExc_OSError, |
571 | 0 | "peek() should have returned a bytes object, " |
572 | 0 | "not '%.200s'", Py_TYPE(readahead)->tp_name); |
573 | 0 | Py_DECREF(readahead); |
574 | 0 | goto fail; |
575 | 0 | } |
576 | 0 | if (PyBytes_GET_SIZE(readahead) > 0) { |
577 | 0 | Py_ssize_t n = 0; |
578 | 0 | const char *buf = PyBytes_AS_STRING(readahead); |
579 | 0 | if (limit >= 0) { |
580 | 0 | do { |
581 | 0 | if (n >= PyBytes_GET_SIZE(readahead) || n >= limit) |
582 | 0 | break; |
583 | 0 | if (buf[n++] == '\n') |
584 | 0 | break; |
585 | 0 | } while (1); |
586 | 0 | } |
587 | 0 | else { |
588 | 0 | do { |
589 | 0 | if (n >= PyBytes_GET_SIZE(readahead)) |
590 | 0 | break; |
591 | 0 | if (buf[n++] == '\n') |
592 | 0 | break; |
593 | 0 | } while (1); |
594 | 0 | } |
595 | 0 | nreadahead = n; |
596 | 0 | } |
597 | 0 | Py_DECREF(readahead); |
598 | 0 | } |
599 | | |
600 | 0 | b = _PyObject_CallMethodId(self, &PyId_read, "n", nreadahead); |
601 | 0 | if (b == NULL) { |
602 | | /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() |
603 | | when EINTR occurs so we needn't do it ourselves. */ |
604 | 0 | if (_PyIO_trap_eintr()) { |
605 | 0 | continue; |
606 | 0 | } |
607 | 0 | goto fail; |
608 | 0 | } |
609 | 0 | if (!PyBytes_Check(b)) { |
610 | 0 | PyErr_Format(PyExc_OSError, |
611 | 0 | "read() should have returned a bytes object, " |
612 | 0 | "not '%.200s'", Py_TYPE(b)->tp_name); |
613 | 0 | Py_DECREF(b); |
614 | 0 | goto fail; |
615 | 0 | } |
616 | 0 | if (PyBytes_GET_SIZE(b) == 0) { |
617 | 0 | Py_DECREF(b); |
618 | 0 | break; |
619 | 0 | } |
620 | | |
621 | 0 | old_size = PyByteArray_GET_SIZE(buffer); |
622 | 0 | if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) { |
623 | 0 | Py_DECREF(b); |
624 | 0 | goto fail; |
625 | 0 | } |
626 | 0 | memcpy(PyByteArray_AS_STRING(buffer) + old_size, |
627 | 0 | PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b)); |
628 | |
|
629 | 0 | Py_DECREF(b); |
630 | |
|
631 | 0 | if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n') |
632 | 0 | break; |
633 | 0 | } |
634 | | |
635 | 0 | result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer), |
636 | 0 | PyByteArray_GET_SIZE(buffer)); |
637 | 0 | Py_XDECREF(peek); |
638 | 0 | Py_DECREF(buffer); |
639 | 0 | return result; |
640 | 0 | fail: |
641 | 0 | Py_XDECREF(peek); |
642 | 0 | Py_DECREF(buffer); |
643 | 0 | return NULL; |
644 | 0 | } |
645 | | |
646 | | static PyObject * |
647 | | iobase_iter(PyObject *self) |
648 | 1 | { |
649 | 1 | if (iobase_check_closed(self)) |
650 | 0 | return NULL; |
651 | | |
652 | 1 | Py_INCREF(self); |
653 | 1 | return self; |
654 | 1 | } |
655 | | |
656 | | static PyObject * |
657 | | iobase_iternext(PyObject *self) |
658 | 0 | { |
659 | 0 | PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL); |
660 | |
|
661 | 0 | if (line == NULL) |
662 | 0 | return NULL; |
663 | | |
664 | 0 | if (PyObject_Size(line) <= 0) { |
665 | | /* Error or empty */ |
666 | 0 | Py_DECREF(line); |
667 | 0 | return NULL; |
668 | 0 | } |
669 | | |
670 | 0 | return line; |
671 | 0 | } |
672 | | |
673 | | /*[clinic input] |
674 | | _io._IOBase.readlines |
675 | | hint: Py_ssize_t(accept={int, NoneType}) = -1 |
676 | | / |
677 | | |
678 | | Return a list of lines from the stream. |
679 | | |
680 | | hint can be specified to control the number of lines read: no more |
681 | | lines will be read if the total size (in bytes/characters) of all |
682 | | lines so far exceeds hint. |
683 | | [clinic start generated code]*/ |
684 | | |
685 | | static PyObject * |
686 | | _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) |
687 | | /*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/ |
688 | 1 | { |
689 | 1 | Py_ssize_t length = 0; |
690 | 1 | PyObject *result, *it = NULL; |
691 | | |
692 | 1 | result = PyList_New(0); |
693 | 1 | if (result == NULL) |
694 | 0 | return NULL; |
695 | | |
696 | 1 | if (hint <= 0) { |
697 | | /* XXX special-casing this made sense in the Python version in order |
698 | | to remove the bytecode interpretation overhead, but it could |
699 | | probably be removed here. */ |
700 | 1 | _Py_IDENTIFIER(extend); |
701 | 1 | PyObject *ret = _PyObject_CallMethodIdObjArgs(result, &PyId_extend, |
702 | 1 | self, NULL); |
703 | | |
704 | 1 | if (ret == NULL) { |
705 | 0 | goto error; |
706 | 0 | } |
707 | 1 | Py_DECREF(ret); |
708 | 1 | return result; |
709 | 1 | } |
710 | | |
711 | 0 | it = PyObject_GetIter(self); |
712 | 0 | if (it == NULL) { |
713 | 0 | goto error; |
714 | 0 | } |
715 | | |
716 | 0 | while (1) { |
717 | 0 | Py_ssize_t line_length; |
718 | 0 | PyObject *line = PyIter_Next(it); |
719 | 0 | if (line == NULL) { |
720 | 0 | if (PyErr_Occurred()) { |
721 | 0 | goto error; |
722 | 0 | } |
723 | 0 | else |
724 | 0 | break; /* StopIteration raised */ |
725 | 0 | } |
726 | | |
727 | 0 | if (PyList_Append(result, line) < 0) { |
728 | 0 | Py_DECREF(line); |
729 | 0 | goto error; |
730 | 0 | } |
731 | 0 | line_length = PyObject_Size(line); |
732 | 0 | Py_DECREF(line); |
733 | 0 | if (line_length < 0) { |
734 | 0 | goto error; |
735 | 0 | } |
736 | 0 | if (line_length > hint - length) |
737 | 0 | break; |
738 | 0 | length += line_length; |
739 | 0 | } |
740 | | |
741 | 0 | Py_DECREF(it); |
742 | 0 | return result; |
743 | | |
744 | 0 | error: |
745 | 0 | Py_XDECREF(it); |
746 | 0 | Py_DECREF(result); |
747 | 0 | return NULL; |
748 | 0 | } |
749 | | |
750 | | /*[clinic input] |
751 | | _io._IOBase.writelines |
752 | | lines: object |
753 | | / |
754 | | |
755 | | Write a list of lines to stream. |
756 | | |
757 | | Line separators are not added, so it is usual for each of the |
758 | | lines provided to have a line separator at the end. |
759 | | [clinic start generated code]*/ |
760 | | |
761 | | static PyObject * |
762 | | _io__IOBase_writelines(PyObject *self, PyObject *lines) |
763 | | /*[clinic end generated code: output=976eb0a9b60a6628 input=cac3fc8864183359]*/ |
764 | 0 | { |
765 | 0 | PyObject *iter, *res; |
766 | |
|
767 | 0 | if (iobase_check_closed(self)) |
768 | 0 | return NULL; |
769 | | |
770 | 0 | iter = PyObject_GetIter(lines); |
771 | 0 | if (iter == NULL) |
772 | 0 | return NULL; |
773 | | |
774 | 0 | while (1) { |
775 | 0 | PyObject *line = PyIter_Next(iter); |
776 | 0 | if (line == NULL) { |
777 | 0 | if (PyErr_Occurred()) { |
778 | 0 | Py_DECREF(iter); |
779 | 0 | return NULL; |
780 | 0 | } |
781 | 0 | else |
782 | 0 | break; /* Stop Iteration */ |
783 | 0 | } |
784 | | |
785 | 0 | res = NULL; |
786 | 0 | do { |
787 | 0 | res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL); |
788 | 0 | } while (res == NULL && _PyIO_trap_eintr()); |
789 | 0 | Py_DECREF(line); |
790 | 0 | if (res == NULL) { |
791 | 0 | Py_DECREF(iter); |
792 | 0 | return NULL; |
793 | 0 | } |
794 | 0 | Py_DECREF(res); |
795 | 0 | } |
796 | 0 | Py_DECREF(iter); |
797 | 0 | Py_RETURN_NONE; |
798 | 0 | } |
799 | | |
800 | | #include "clinic/iobase.c.h" |
801 | | |
802 | | static PyMethodDef iobase_methods[] = { |
803 | | {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc}, |
804 | | _IO__IOBASE_TELL_METHODDEF |
805 | | {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc}, |
806 | | _IO__IOBASE_FLUSH_METHODDEF |
807 | | _IO__IOBASE_CLOSE_METHODDEF |
808 | | |
809 | | _IO__IOBASE_SEEKABLE_METHODDEF |
810 | | _IO__IOBASE_READABLE_METHODDEF |
811 | | _IO__IOBASE_WRITABLE_METHODDEF |
812 | | |
813 | | {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS}, |
814 | | {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS}, |
815 | | {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS}, |
816 | | {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS}, |
817 | | |
818 | | _IO__IOBASE_FILENO_METHODDEF |
819 | | _IO__IOBASE_ISATTY_METHODDEF |
820 | | |
821 | | {"__enter__", iobase_enter, METH_NOARGS}, |
822 | | {"__exit__", iobase_exit, METH_VARARGS}, |
823 | | |
824 | | _IO__IOBASE_READLINE_METHODDEF |
825 | | _IO__IOBASE_READLINES_METHODDEF |
826 | | _IO__IOBASE_WRITELINES_METHODDEF |
827 | | |
828 | | {NULL, NULL} |
829 | | }; |
830 | | |
831 | | static PyGetSetDef iobase_getset[] = { |
832 | | {"__dict__", PyObject_GenericGetDict, NULL, NULL}, |
833 | | {"closed", (getter)iobase_closed_get, NULL, NULL}, |
834 | | {NULL} |
835 | | }; |
836 | | |
837 | | |
838 | | PyTypeObject PyIOBase_Type = { |
839 | | PyVarObject_HEAD_INIT(NULL, 0) |
840 | | "_io._IOBase", /*tp_name*/ |
841 | | sizeof(iobase), /*tp_basicsize*/ |
842 | | 0, /*tp_itemsize*/ |
843 | | (destructor)iobase_dealloc, /*tp_dealloc*/ |
844 | | 0, /*tp_vectorcall_offset*/ |
845 | | 0, /*tp_getattr*/ |
846 | | 0, /*tp_setattr*/ |
847 | | 0, /*tp_as_async*/ |
848 | | 0, /*tp_repr*/ |
849 | | 0, /*tp_as_number*/ |
850 | | 0, /*tp_as_sequence*/ |
851 | | 0, /*tp_as_mapping*/ |
852 | | 0, /*tp_hash */ |
853 | | 0, /*tp_call*/ |
854 | | 0, /*tp_str*/ |
855 | | 0, /*tp_getattro*/ |
856 | | 0, /*tp_setattro*/ |
857 | | 0, /*tp_as_buffer*/ |
858 | | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
859 | | | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ |
860 | | iobase_doc, /* tp_doc */ |
861 | | (traverseproc)iobase_traverse, /* tp_traverse */ |
862 | | (inquiry)iobase_clear, /* tp_clear */ |
863 | | 0, /* tp_richcompare */ |
864 | | offsetof(iobase, weakreflist), /* tp_weaklistoffset */ |
865 | | iobase_iter, /* tp_iter */ |
866 | | iobase_iternext, /* tp_iternext */ |
867 | | iobase_methods, /* tp_methods */ |
868 | | 0, /* tp_members */ |
869 | | iobase_getset, /* tp_getset */ |
870 | | 0, /* tp_base */ |
871 | | 0, /* tp_dict */ |
872 | | 0, /* tp_descr_get */ |
873 | | 0, /* tp_descr_set */ |
874 | | offsetof(iobase, dict), /* tp_dictoffset */ |
875 | | 0, /* tp_init */ |
876 | | 0, /* tp_alloc */ |
877 | | PyType_GenericNew, /* tp_new */ |
878 | | 0, /* tp_free */ |
879 | | 0, /* tp_is_gc */ |
880 | | 0, /* tp_bases */ |
881 | | 0, /* tp_mro */ |
882 | | 0, /* tp_cache */ |
883 | | 0, /* tp_subclasses */ |
884 | | 0, /* tp_weaklist */ |
885 | | 0, /* tp_del */ |
886 | | 0, /* tp_version_tag */ |
887 | | iobase_finalize, /* tp_finalize */ |
888 | | }; |
889 | | |
890 | | |
891 | | /* |
892 | | * RawIOBase class, Inherits from IOBase. |
893 | | */ |
894 | | PyDoc_STRVAR(rawiobase_doc, |
895 | | "Base class for raw binary I/O."); |
896 | | |
897 | | /* |
898 | | * The read() method is implemented by calling readinto(); derived classes |
899 | | * that want to support read() only need to implement readinto() as a |
900 | | * primitive operation. In general, readinto() can be more efficient than |
901 | | * read(). |
902 | | * |
903 | | * (It would be tempting to also provide an implementation of readinto() in |
904 | | * terms of read(), in case the latter is a more suitable primitive operation, |
905 | | * but that would lead to nasty recursion in case a subclass doesn't implement |
906 | | * either.) |
907 | | */ |
908 | | |
909 | | /*[clinic input] |
910 | | _io._RawIOBase.read |
911 | | size as n: Py_ssize_t = -1 |
912 | | / |
913 | | [clinic start generated code]*/ |
914 | | |
915 | | static PyObject * |
916 | | _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n) |
917 | | /*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/ |
918 | 0 | { |
919 | 0 | PyObject *b, *res; |
920 | |
|
921 | 0 | if (n < 0) { |
922 | 0 | _Py_IDENTIFIER(readall); |
923 | |
|
924 | 0 | return _PyObject_CallMethodId(self, &PyId_readall, NULL); |
925 | 0 | } |
926 | | |
927 | | /* TODO: allocate a bytes object directly instead and manually construct |
928 | | a writable memoryview pointing to it. */ |
929 | 0 | b = PyByteArray_FromStringAndSize(NULL, n); |
930 | 0 | if (b == NULL) |
931 | 0 | return NULL; |
932 | | |
933 | 0 | res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL); |
934 | 0 | if (res == NULL || res == Py_None) { |
935 | 0 | Py_DECREF(b); |
936 | 0 | return res; |
937 | 0 | } |
938 | | |
939 | 0 | n = PyNumber_AsSsize_t(res, PyExc_ValueError); |
940 | 0 | Py_DECREF(res); |
941 | 0 | if (n == -1 && PyErr_Occurred()) { |
942 | 0 | Py_DECREF(b); |
943 | 0 | return NULL; |
944 | 0 | } |
945 | | |
946 | 0 | res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n); |
947 | 0 | Py_DECREF(b); |
948 | 0 | return res; |
949 | 0 | } |
950 | | |
951 | | |
952 | | /*[clinic input] |
953 | | _io._RawIOBase.readall |
954 | | |
955 | | Read until EOF, using multiple read() call. |
956 | | [clinic start generated code]*/ |
957 | | |
958 | | static PyObject * |
959 | | _io__RawIOBase_readall_impl(PyObject *self) |
960 | | /*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/ |
961 | 0 | { |
962 | 0 | int r; |
963 | 0 | PyObject *chunks = PyList_New(0); |
964 | 0 | PyObject *result; |
965 | |
|
966 | 0 | if (chunks == NULL) |
967 | 0 | return NULL; |
968 | | |
969 | 0 | while (1) { |
970 | 0 | PyObject *data = _PyObject_CallMethodId(self, &PyId_read, |
971 | 0 | "i", DEFAULT_BUFFER_SIZE); |
972 | 0 | if (!data) { |
973 | | /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() |
974 | | when EINTR occurs so we needn't do it ourselves. */ |
975 | 0 | if (_PyIO_trap_eintr()) { |
976 | 0 | continue; |
977 | 0 | } |
978 | 0 | Py_DECREF(chunks); |
979 | 0 | return NULL; |
980 | 0 | } |
981 | 0 | if (data == Py_None) { |
982 | 0 | if (PyList_GET_SIZE(chunks) == 0) { |
983 | 0 | Py_DECREF(chunks); |
984 | 0 | return data; |
985 | 0 | } |
986 | 0 | Py_DECREF(data); |
987 | 0 | break; |
988 | 0 | } |
989 | 0 | if (!PyBytes_Check(data)) { |
990 | 0 | Py_DECREF(chunks); |
991 | 0 | Py_DECREF(data); |
992 | 0 | PyErr_SetString(PyExc_TypeError, "read() should return bytes"); |
993 | 0 | return NULL; |
994 | 0 | } |
995 | 0 | if (PyBytes_GET_SIZE(data) == 0) { |
996 | | /* EOF */ |
997 | 0 | Py_DECREF(data); |
998 | 0 | break; |
999 | 0 | } |
1000 | 0 | r = PyList_Append(chunks, data); |
1001 | 0 | Py_DECREF(data); |
1002 | 0 | if (r < 0) { |
1003 | 0 | Py_DECREF(chunks); |
1004 | 0 | return NULL; |
1005 | 0 | } |
1006 | 0 | } |
1007 | 0 | result = _PyBytes_Join(_PyIO_empty_bytes, chunks); |
1008 | 0 | Py_DECREF(chunks); |
1009 | 0 | return result; |
1010 | 0 | } |
1011 | | |
1012 | | static PyObject * |
1013 | | rawiobase_readinto(PyObject *self, PyObject *args) |
1014 | 0 | { |
1015 | 0 | PyErr_SetNone(PyExc_NotImplementedError); |
1016 | 0 | return NULL; |
1017 | 0 | } |
1018 | | |
1019 | | static PyObject * |
1020 | | rawiobase_write(PyObject *self, PyObject *args) |
1021 | 0 | { |
1022 | 0 | PyErr_SetNone(PyExc_NotImplementedError); |
1023 | 0 | return NULL; |
1024 | 0 | } |
1025 | | |
1026 | | static PyMethodDef rawiobase_methods[] = { |
1027 | | _IO__RAWIOBASE_READ_METHODDEF |
1028 | | _IO__RAWIOBASE_READALL_METHODDEF |
1029 | | {"readinto", rawiobase_readinto, METH_VARARGS}, |
1030 | | {"write", rawiobase_write, METH_VARARGS}, |
1031 | | {NULL, NULL} |
1032 | | }; |
1033 | | |
1034 | | PyTypeObject PyRawIOBase_Type = { |
1035 | | PyVarObject_HEAD_INIT(NULL, 0) |
1036 | | "_io._RawIOBase", /*tp_name*/ |
1037 | | 0, /*tp_basicsize*/ |
1038 | | 0, /*tp_itemsize*/ |
1039 | | 0, /*tp_dealloc*/ |
1040 | | 0, /*tp_vectorcall_offset*/ |
1041 | | 0, /*tp_getattr*/ |
1042 | | 0, /*tp_setattr*/ |
1043 | | 0, /*tp_as_async*/ |
1044 | | 0, /*tp_repr*/ |
1045 | | 0, /*tp_as_number*/ |
1046 | | 0, /*tp_as_sequence*/ |
1047 | | 0, /*tp_as_mapping*/ |
1048 | | 0, /*tp_hash */ |
1049 | | 0, /*tp_call*/ |
1050 | | 0, /*tp_str*/ |
1051 | | 0, /*tp_getattro*/ |
1052 | | 0, /*tp_setattro*/ |
1053 | | 0, /*tp_as_buffer*/ |
1054 | | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ |
1055 | | rawiobase_doc, /* tp_doc */ |
1056 | | 0, /* tp_traverse */ |
1057 | | 0, /* tp_clear */ |
1058 | | 0, /* tp_richcompare */ |
1059 | | 0, /* tp_weaklistoffset */ |
1060 | | 0, /* tp_iter */ |
1061 | | 0, /* tp_iternext */ |
1062 | | rawiobase_methods, /* tp_methods */ |
1063 | | 0, /* tp_members */ |
1064 | | 0, /* tp_getset */ |
1065 | | &PyIOBase_Type, /* tp_base */ |
1066 | | 0, /* tp_dict */ |
1067 | | 0, /* tp_descr_get */ |
1068 | | 0, /* tp_descr_set */ |
1069 | | 0, /* tp_dictoffset */ |
1070 | | 0, /* tp_init */ |
1071 | | 0, /* tp_alloc */ |
1072 | | 0, /* tp_new */ |
1073 | | 0, /* tp_free */ |
1074 | | 0, /* tp_is_gc */ |
1075 | | 0, /* tp_bases */ |
1076 | | 0, /* tp_mro */ |
1077 | | 0, /* tp_cache */ |
1078 | | 0, /* tp_subclasses */ |
1079 | | 0, /* tp_weaklist */ |
1080 | | 0, /* tp_del */ |
1081 | | 0, /* tp_version_tag */ |
1082 | | 0, /* tp_finalize */ |
1083 | | }; |