blob: 2c799e331581b85d1169ed97ddc119dd72c9999c [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
2 An implementation of Text I/O as defined by PEP 3116 - "New I/O"
Antoine Pitrou24f36292009-03-28 22:16:42 +00003
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00004 Classes defined here: TextIOBase, IncrementalNewlineDecoder, TextIOWrapper.
Antoine Pitrou24f36292009-03-28 22:16:42 +00005
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00006 Written by Amaury Forgeot d'Arc and Antoine Pitrou
7*/
8
9#define PY_SSIZE_T_CLEAN
10#include "Python.h"
11#include "structmember.h"
12#include "_iomodule.h"
13
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030014/*[clinic input]
15module _io
16class _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type"
17class _io.TextIOWrapper "textio *" "&TextIOWrapper_TYpe"
18[clinic start generated code]*/
19/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2097a4fc85670c26]*/
20
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020021_Py_IDENTIFIER(close);
22_Py_IDENTIFIER(_dealloc_warn);
23_Py_IDENTIFIER(decode);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020024_Py_IDENTIFIER(fileno);
25_Py_IDENTIFIER(flush);
26_Py_IDENTIFIER(getpreferredencoding);
27_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020028_Py_IDENTIFIER(mode);
29_Py_IDENTIFIER(name);
30_Py_IDENTIFIER(raw);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020031_Py_IDENTIFIER(read);
Martin v. Löwis767046a2011-10-14 15:35:36 +020032_Py_IDENTIFIER(read1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020033_Py_IDENTIFIER(readable);
34_Py_IDENTIFIER(replace);
35_Py_IDENTIFIER(reset);
36_Py_IDENTIFIER(seek);
37_Py_IDENTIFIER(seekable);
38_Py_IDENTIFIER(setstate);
39_Py_IDENTIFIER(tell);
40_Py_IDENTIFIER(writable);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020041
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000042/* TextIOBase */
43
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000044PyDoc_STRVAR(textiobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000045 "Base class for text I/O.\n"
46 "\n"
47 "This class provides a character and line based interface to stream\n"
48 "I/O. There is no readinto method because Python's character strings\n"
49 "are immutable. There is no public constructor.\n"
50 );
51
52static PyObject *
53_unsupported(const char *message)
54{
Antoine Pitrou712cb732013-12-21 15:51:54 +010055 _PyIO_State *state = IO_STATE();
56 if (state != NULL)
57 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000058 return NULL;
59}
60
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000061PyDoc_STRVAR(textiobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +000062 "Separate the underlying buffer from the TextIOBase and return it.\n"
63 "\n"
64 "After the underlying buffer has been detached, the TextIO is in an\n"
65 "unusable state.\n"
66 );
67
68static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000069textiobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +000070{
71 return _unsupported("detach");
72}
73
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000074PyDoc_STRVAR(textiobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000075 "Read at most n characters from stream.\n"
76 "\n"
77 "Read from underlying buffer until we have n characters or we hit EOF.\n"
78 "If n is negative or omitted, read until EOF.\n"
79 );
80
81static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000082textiobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000083{
84 return _unsupported("read");
85}
86
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000087PyDoc_STRVAR(textiobase_readline_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000088 "Read until newline or EOF.\n"
89 "\n"
90 "Returns an empty string if EOF is hit immediately.\n"
91 );
92
93static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000094textiobase_readline(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000095{
96 return _unsupported("readline");
97}
98
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000099PyDoc_STRVAR(textiobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000100 "Write string to stream.\n"
101 "Returns the number of characters written (which is always equal to\n"
102 "the length of the string).\n"
103 );
104
105static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000106textiobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000107{
108 return _unsupported("write");
109}
110
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000111PyDoc_STRVAR(textiobase_encoding_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000112 "Encoding of the text stream.\n"
113 "\n"
114 "Subclasses should override.\n"
115 );
116
117static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000118textiobase_encoding_get(PyObject *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000119{
120 Py_RETURN_NONE;
121}
122
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000123PyDoc_STRVAR(textiobase_newlines_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000124 "Line endings translated so far.\n"
125 "\n"
126 "Only line endings translated during reading are considered.\n"
127 "\n"
128 "Subclasses should override.\n"
129 );
130
131static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000132textiobase_newlines_get(PyObject *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000133{
134 Py_RETURN_NONE;
135}
136
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000137PyDoc_STRVAR(textiobase_errors_doc,
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000138 "The error setting of the decoder or encoder.\n"
139 "\n"
140 "Subclasses should override.\n"
141 );
142
143static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000144textiobase_errors_get(PyObject *self, void *context)
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000145{
146 Py_RETURN_NONE;
147}
148
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000149
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000150static PyMethodDef textiobase_methods[] = {
151 {"detach", (PyCFunction)textiobase_detach, METH_NOARGS, textiobase_detach_doc},
152 {"read", textiobase_read, METH_VARARGS, textiobase_read_doc},
153 {"readline", textiobase_readline, METH_VARARGS, textiobase_readline_doc},
154 {"write", textiobase_write, METH_VARARGS, textiobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000155 {NULL, NULL}
156};
157
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000158static PyGetSetDef textiobase_getset[] = {
159 {"encoding", (getter)textiobase_encoding_get, NULL, textiobase_encoding_doc},
160 {"newlines", (getter)textiobase_newlines_get, NULL, textiobase_newlines_doc},
161 {"errors", (getter)textiobase_errors_get, NULL, textiobase_errors_doc},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000162 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000163};
164
165PyTypeObject PyTextIOBase_Type = {
166 PyVarObject_HEAD_INIT(NULL, 0)
167 "_io._TextIOBase", /*tp_name*/
168 0, /*tp_basicsize*/
169 0, /*tp_itemsize*/
170 0, /*tp_dealloc*/
171 0, /*tp_print*/
172 0, /*tp_getattr*/
173 0, /*tp_setattr*/
174 0, /*tp_compare */
175 0, /*tp_repr*/
176 0, /*tp_as_number*/
177 0, /*tp_as_sequence*/
178 0, /*tp_as_mapping*/
179 0, /*tp_hash */
180 0, /*tp_call*/
181 0, /*tp_str*/
182 0, /*tp_getattro*/
183 0, /*tp_setattro*/
184 0, /*tp_as_buffer*/
Antoine Pitrou796564c2013-07-30 19:59:21 +0200185 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
186 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000187 textiobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000188 0, /* tp_traverse */
189 0, /* tp_clear */
190 0, /* tp_richcompare */
191 0, /* tp_weaklistoffset */
192 0, /* tp_iter */
193 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194 textiobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000196 textiobase_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000197 &PyIOBase_Type, /* tp_base */
198 0, /* tp_dict */
199 0, /* tp_descr_get */
200 0, /* tp_descr_set */
201 0, /* tp_dictoffset */
202 0, /* tp_init */
203 0, /* tp_alloc */
204 0, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200205 0, /* tp_free */
206 0, /* tp_is_gc */
207 0, /* tp_bases */
208 0, /* tp_mro */
209 0, /* tp_cache */
210 0, /* tp_subclasses */
211 0, /* tp_weaklist */
212 0, /* tp_del */
213 0, /* tp_version_tag */
214 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000215};
216
217
218/* IncrementalNewlineDecoder */
219
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000220typedef struct {
221 PyObject_HEAD
222 PyObject *decoder;
223 PyObject *errors;
Victor Stinner7d7e7752014-06-17 23:31:25 +0200224 unsigned int pendingcr: 1;
225 unsigned int translate: 1;
Antoine Pitrouca767bd2009-09-21 21:37:02 +0000226 unsigned int seennl: 3;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000227} nldecoder_object;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000228
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300229/*[clinic input]
230_io.IncrementalNewlineDecoder.__init__
231 decoder: object
232 translate: int
233 errors: object(c_default="NULL") = "strict"
234
235Codec used when reading a file in universal newlines mode.
236
237It wraps another incremental decoder, translating \r\n and \r into \n.
238It also records the types of newlines encountered. When used with
239translate=False, it ensures that the newline sequence is returned in
240one piece. When used with decoder=None, it expects unicode strings as
241decode input and translates newlines without first invoking an external
242decoder.
243[clinic start generated code]*/
244
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000245static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300246_io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self,
247 PyObject *decoder, int translate,
248 PyObject *errors)
249/*[clinic end generated code: output=fbd04d443e764ec2 input=89db6b19c6b126bf]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000250{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000251 self->decoder = decoder;
252 Py_INCREF(decoder);
253
254 if (errors == NULL) {
255 self->errors = PyUnicode_FromString("strict");
256 if (self->errors == NULL)
257 return -1;
258 }
259 else {
260 Py_INCREF(errors);
261 self->errors = errors;
262 }
263
264 self->translate = translate;
265 self->seennl = 0;
266 self->pendingcr = 0;
267
268 return 0;
269}
270
271static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000272incrementalnewlinedecoder_dealloc(nldecoder_object *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000273{
274 Py_CLEAR(self->decoder);
275 Py_CLEAR(self->errors);
276 Py_TYPE(self)->tp_free((PyObject *)self);
277}
278
Serhiy Storchaka94dc6732013-02-03 17:03:31 +0200279static int
280check_decoded(PyObject *decoded)
281{
282 if (decoded == NULL)
283 return -1;
284 if (!PyUnicode_Check(decoded)) {
285 PyErr_Format(PyExc_TypeError,
286 "decoder should return a string result, not '%.200s'",
287 Py_TYPE(decoded)->tp_name);
288 Py_DECREF(decoded);
289 return -1;
290 }
Serhiy Storchakad03ce4a2013-02-03 17:07:32 +0200291 if (PyUnicode_READY(decoded) < 0) {
292 Py_DECREF(decoded);
293 return -1;
294 }
Serhiy Storchaka94dc6732013-02-03 17:03:31 +0200295 return 0;
296}
297
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000298#define SEEN_CR 1
299#define SEEN_LF 2
300#define SEEN_CRLF 4
301#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF)
302
303PyObject *
Antoine Pitrou09fcb722013-10-23 19:20:21 +0200304_PyIncrementalNewlineDecoder_decode(PyObject *myself,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000305 PyObject *input, int final)
306{
307 PyObject *output;
308 Py_ssize_t output_len;
Antoine Pitrou09fcb722013-10-23 19:20:21 +0200309 nldecoder_object *self = (nldecoder_object *) myself;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000310
311 if (self->decoder == NULL) {
312 PyErr_SetString(PyExc_ValueError,
313 "IncrementalNewlineDecoder.__init__ not called");
314 return NULL;
315 }
316
317 /* decode input (with the eventual \r from a previous pass) */
318 if (self->decoder != Py_None) {
319 output = PyObject_CallMethodObjArgs(self->decoder,
320 _PyIO_str_decode, input, final ? Py_True : Py_False, NULL);
321 }
322 else {
323 output = input;
324 Py_INCREF(output);
325 }
326
Serhiy Storchaka94dc6732013-02-03 17:03:31 +0200327 if (check_decoded(output) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000328 return NULL;
329
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200330 output_len = PyUnicode_GET_LENGTH(output);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000331 if (self->pendingcr && (final || output_len > 0)) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200332 /* Prefix output with CR */
333 int kind;
334 PyObject *modified;
335 char *out;
336
337 modified = PyUnicode_New(output_len + 1,
338 PyUnicode_MAX_CHAR_VALUE(output));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000339 if (modified == NULL)
340 goto error;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200341 kind = PyUnicode_KIND(modified);
342 out = PyUnicode_DATA(modified);
343 PyUnicode_WRITE(kind, PyUnicode_DATA(modified), 0, '\r');
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200344 memcpy(out + kind, PyUnicode_DATA(output), kind * output_len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000345 Py_DECREF(output);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200346 output = modified; /* output remains ready */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000347 self->pendingcr = 0;
348 output_len++;
349 }
350
351 /* retain last \r even when not translating data:
352 * then readline() is sure to get \r\n in one pass
353 */
354 if (!final) {
Antoine Pitrou24f36292009-03-28 22:16:42 +0000355 if (output_len > 0
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200356 && PyUnicode_READ_CHAR(output, output_len - 1) == '\r')
357 {
358 PyObject *modified = PyUnicode_Substring(output, 0, output_len -1);
359 if (modified == NULL)
360 goto error;
361 Py_DECREF(output);
362 output = modified;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000363 self->pendingcr = 1;
364 }
365 }
366
367 /* Record which newlines are read and do newline translation if desired,
368 all in one pass. */
369 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200370 void *in_str;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000371 Py_ssize_t len;
372 int seennl = self->seennl;
373 int only_lf = 0;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200374 int kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000375
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200376 in_str = PyUnicode_DATA(output);
377 len = PyUnicode_GET_LENGTH(output);
378 kind = PyUnicode_KIND(output);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000379
380 if (len == 0)
381 return output;
382
383 /* If, up to now, newlines are consistently \n, do a quick check
384 for the \r *byte* with the libc's optimized memchr.
385 */
386 if (seennl == SEEN_LF || seennl == 0) {
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200387 only_lf = (memchr(in_str, '\r', kind * len) == NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000388 }
389
Antoine Pitrou66913e22009-03-06 23:40:56 +0000390 if (only_lf) {
391 /* If not already seen, quick scan for a possible "\n" character.
392 (there's nothing else to be done, even when in translation mode)
393 */
394 if (seennl == 0 &&
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200395 memchr(in_str, '\n', kind * len) != NULL) {
Antoine Pitrouc28e2e52011-11-13 03:53:42 +0100396 if (kind == PyUnicode_1BYTE_KIND)
397 seennl |= SEEN_LF;
398 else {
399 Py_ssize_t i = 0;
400 for (;;) {
401 Py_UCS4 c;
402 /* Fast loop for non-control characters */
403 while (PyUnicode_READ(kind, in_str, i) > '\n')
404 i++;
405 c = PyUnicode_READ(kind, in_str, i++);
406 if (c == '\n') {
407 seennl |= SEEN_LF;
408 break;
409 }
410 if (i >= len)
411 break;
Antoine Pitrou66913e22009-03-06 23:40:56 +0000412 }
Antoine Pitrou66913e22009-03-06 23:40:56 +0000413 }
414 }
415 /* Finished: we have scanned for newlines, and none of them
416 need translating */
417 }
418 else if (!self->translate) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200419 Py_ssize_t i = 0;
Antoine Pitrou66913e22009-03-06 23:40:56 +0000420 /* We have already seen all newline types, no need to scan again */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000421 if (seennl == SEEN_ALL)
422 goto endscan;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000423 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200424 Py_UCS4 c;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000425 /* Fast loop for non-control characters */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200426 while (PyUnicode_READ(kind, in_str, i) > '\r')
427 i++;
428 c = PyUnicode_READ(kind, in_str, i++);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000429 if (c == '\n')
430 seennl |= SEEN_LF;
431 else if (c == '\r') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200432 if (PyUnicode_READ(kind, in_str, i) == '\n') {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000433 seennl |= SEEN_CRLF;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200434 i++;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000435 }
436 else
437 seennl |= SEEN_CR;
438 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200439 if (i >= len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000440 break;
441 if (seennl == SEEN_ALL)
442 break;
443 }
444 endscan:
445 ;
446 }
Antoine Pitrou66913e22009-03-06 23:40:56 +0000447 else {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200448 void *translated;
449 int kind = PyUnicode_KIND(output);
450 void *in_str = PyUnicode_DATA(output);
451 Py_ssize_t in, out;
452 /* XXX: Previous in-place translation here is disabled as
453 resizing is not possible anymore */
454 /* We could try to optimize this so that we only do a copy
455 when there is something to translate. On the other hand,
456 we already know there is a \r byte, so chances are high
457 that something needs to be done. */
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200458 translated = PyMem_Malloc(kind * len);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200459 if (translated == NULL) {
460 PyErr_NoMemory();
461 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000462 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200463 in = out = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000464 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200465 Py_UCS4 c;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466 /* Fast loop for non-control characters */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200467 while ((c = PyUnicode_READ(kind, in_str, in++)) > '\r')
468 PyUnicode_WRITE(kind, translated, out++, c);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000469 if (c == '\n') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200470 PyUnicode_WRITE(kind, translated, out++, c);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000471 seennl |= SEEN_LF;
472 continue;
473 }
474 if (c == '\r') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200475 if (PyUnicode_READ(kind, in_str, in) == '\n') {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000476 in++;
477 seennl |= SEEN_CRLF;
478 }
479 else
480 seennl |= SEEN_CR;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200481 PyUnicode_WRITE(kind, translated, out++, '\n');
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482 continue;
483 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200484 if (in > len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000485 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200486 PyUnicode_WRITE(kind, translated, out++, c);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200488 Py_DECREF(output);
489 output = PyUnicode_FromKindAndData(kind, translated, out);
Antoine Pitrouc1b0bfd2011-11-12 22:34:28 +0100490 PyMem_Free(translated);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200491 if (!output)
Ross Lagerwall0f9eec12012-04-07 07:09:57 +0200492 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000493 }
494 self->seennl |= seennl;
495 }
496
497 return output;
498
499 error:
500 Py_DECREF(output);
501 return NULL;
502}
503
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300504/*[clinic input]
505_io.IncrementalNewlineDecoder.decode
506 input: object
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200507 final: bool(accept={int}) = False
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300508[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000509
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300510static PyObject *
511_io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self,
512 PyObject *input, int final)
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200513/*[clinic end generated code: output=0d486755bb37a66e input=a4ea97f26372d866]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300514{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000515 return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final);
516}
517
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300518/*[clinic input]
519_io.IncrementalNewlineDecoder.getstate
520[clinic start generated code]*/
521
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300523_io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self)
524/*[clinic end generated code: output=f0d2c9c136f4e0d0 input=f8ff101825e32e7f]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000525{
526 PyObject *buffer;
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700527 unsigned long long flag;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000528
529 if (self->decoder != Py_None) {
530 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
531 _PyIO_str_getstate, NULL);
532 if (state == NULL)
533 return NULL;
Serhiy Storchakabb72c472015-04-19 20:38:19 +0300534 if (!PyArg_ParseTuple(state, "OK", &buffer, &flag)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000535 Py_DECREF(state);
536 return NULL;
537 }
538 Py_INCREF(buffer);
539 Py_DECREF(state);
540 }
541 else {
542 buffer = PyBytes_FromString("");
543 flag = 0;
544 }
545 flag <<= 1;
546 if (self->pendingcr)
547 flag |= 1;
548 return Py_BuildValue("NK", buffer, flag);
549}
550
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300551/*[clinic input]
552_io.IncrementalNewlineDecoder.setstate
553 state: object
554 /
555[clinic start generated code]*/
556
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000557static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300558_io_IncrementalNewlineDecoder_setstate(nldecoder_object *self,
559 PyObject *state)
560/*[clinic end generated code: output=c10c622508b576cb input=c53fb505a76dbbe2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000561{
562 PyObject *buffer;
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700563 unsigned long long flag;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000564
Serhiy Storchakabb72c472015-04-19 20:38:19 +0300565 if (!PyArg_ParseTuple(state, "OK", &buffer, &flag))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000566 return NULL;
567
Victor Stinner7d7e7752014-06-17 23:31:25 +0200568 self->pendingcr = (int) (flag & 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569 flag >>= 1;
570
571 if (self->decoder != Py_None)
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200572 return _PyObject_CallMethodId(self->decoder,
573 &PyId_setstate, "((OK))", buffer, flag);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000574 else
575 Py_RETURN_NONE;
576}
577
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300578/*[clinic input]
579_io.IncrementalNewlineDecoder.reset
580[clinic start generated code]*/
581
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000582static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300583_io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self)
584/*[clinic end generated code: output=32fa40c7462aa8ff input=728678ddaea776df]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000585{
586 self->seennl = 0;
587 self->pendingcr = 0;
588 if (self->decoder != Py_None)
589 return PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
590 else
591 Py_RETURN_NONE;
592}
593
594static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000595incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000596{
597 switch (self->seennl) {
598 case SEEN_CR:
599 return PyUnicode_FromString("\r");
600 case SEEN_LF:
601 return PyUnicode_FromString("\n");
602 case SEEN_CRLF:
603 return PyUnicode_FromString("\r\n");
604 case SEEN_CR | SEEN_LF:
605 return Py_BuildValue("ss", "\r", "\n");
606 case SEEN_CR | SEEN_CRLF:
607 return Py_BuildValue("ss", "\r", "\r\n");
608 case SEEN_LF | SEEN_CRLF:
609 return Py_BuildValue("ss", "\n", "\r\n");
610 case SEEN_CR | SEEN_LF | SEEN_CRLF:
611 return Py_BuildValue("sss", "\r", "\n", "\r\n");
612 default:
613 Py_RETURN_NONE;
614 }
615
616}
617
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000618/* TextIOWrapper */
619
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000620typedef PyObject *
621 (*encodefunc_t)(PyObject *, PyObject *);
622
623typedef struct
624{
625 PyObject_HEAD
626 int ok; /* initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000627 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000628 Py_ssize_t chunk_size;
629 PyObject *buffer;
630 PyObject *encoding;
631 PyObject *encoder;
632 PyObject *decoder;
633 PyObject *readnl;
634 PyObject *errors;
635 const char *writenl; /* utf-8 encoded, NULL stands for \n */
636 char line_buffering;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200637 char write_through;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000638 char readuniversal;
639 char readtranslate;
640 char writetranslate;
641 char seekable;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200642 char has_read1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643 char telling;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200644 char finalizing;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000645 /* Specialized encoding func (see below) */
646 encodefunc_t encodefunc;
Antoine Pitroue4501852009-05-14 18:55:55 +0000647 /* Whether or not it's the start of the stream */
648 char encoding_start_of_stream;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000649
650 /* Reads and writes are internally buffered in order to speed things up.
651 However, any read will first flush the write buffer if itsn't empty.
Antoine Pitrou24f36292009-03-28 22:16:42 +0000652
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653 Please also note that text to be written is first encoded before being
654 buffered. This is necessary so that encoding errors are immediately
655 reported to the caller, but it unfortunately means that the
656 IncrementalEncoder (whose encode() method is always written in Python)
657 becomes a bottleneck for small writes.
658 */
659 PyObject *decoded_chars; /* buffer for text returned from decoder */
660 Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */
661 PyObject *pending_bytes; /* list of bytes objects waiting to be
662 written, or NULL */
663 Py_ssize_t pending_bytes_count;
Antoine Pitrou211b81d2011-02-25 20:27:33 +0000664
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000665 /* snapshot is either None, or a tuple (dec_flags, next_input) where
666 * dec_flags is the second (integer) item of the decoder state and
667 * next_input is the chunk of input bytes that comes next after the
668 * snapshot point. We use this to reconstruct decoder states in tell().
669 */
Antoine Pitrou211b81d2011-02-25 20:27:33 +0000670 PyObject *snapshot;
671 /* Bytes-to-characters ratio for the current chunk. Serves as input for
672 the heuristic in tell(). */
673 double b2cratio;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000674
675 /* Cache raw object if it's a FileIO object */
676 PyObject *raw;
677
678 PyObject *weakreflist;
679 PyObject *dict;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000680} textio;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000682/* A couple of specialized cases in order to bypass the slow incremental
683 encoding methods for the most popular encodings. */
684
685static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000686ascii_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000687{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200688 return _PyUnicode_AsASCIIString(text, PyBytes_AS_STRING(self->errors));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689}
690
691static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000692utf16be_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000693{
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100694 return _PyUnicode_EncodeUTF16(text,
695 PyBytes_AS_STRING(self->errors), 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000696}
697
698static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000699utf16le_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000700{
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100701 return _PyUnicode_EncodeUTF16(text,
702 PyBytes_AS_STRING(self->errors), -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000703}
704
705static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000706utf16_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000707{
Antoine Pitroue4501852009-05-14 18:55:55 +0000708 if (!self->encoding_start_of_stream) {
709 /* Skip the BOM and use native byte ordering */
Christian Heimes743e0cd2012-10-17 23:52:17 +0200710#if PY_BIG_ENDIAN
Antoine Pitroue4501852009-05-14 18:55:55 +0000711 return utf16be_encode(self, text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000712#else
Antoine Pitroue4501852009-05-14 18:55:55 +0000713 return utf16le_encode(self, text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000714#endif
Antoine Pitroue4501852009-05-14 18:55:55 +0000715 }
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100716 return _PyUnicode_EncodeUTF16(text,
717 PyBytes_AS_STRING(self->errors), 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000718}
719
Antoine Pitroue4501852009-05-14 18:55:55 +0000720static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000721utf32be_encode(textio *self, PyObject *text)
Antoine Pitroue4501852009-05-14 18:55:55 +0000722{
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100723 return _PyUnicode_EncodeUTF32(text,
724 PyBytes_AS_STRING(self->errors), 1);
Antoine Pitroue4501852009-05-14 18:55:55 +0000725}
726
727static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000728utf32le_encode(textio *self, PyObject *text)
Antoine Pitroue4501852009-05-14 18:55:55 +0000729{
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100730 return _PyUnicode_EncodeUTF32(text,
731 PyBytes_AS_STRING(self->errors), -1);
Antoine Pitroue4501852009-05-14 18:55:55 +0000732}
733
734static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000735utf32_encode(textio *self, PyObject *text)
Antoine Pitroue4501852009-05-14 18:55:55 +0000736{
737 if (!self->encoding_start_of_stream) {
738 /* Skip the BOM and use native byte ordering */
Christian Heimes743e0cd2012-10-17 23:52:17 +0200739#if PY_BIG_ENDIAN
Antoine Pitroue4501852009-05-14 18:55:55 +0000740 return utf32be_encode(self, text);
741#else
742 return utf32le_encode(self, text);
743#endif
744 }
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100745 return _PyUnicode_EncodeUTF32(text,
746 PyBytes_AS_STRING(self->errors), 0);
Antoine Pitroue4501852009-05-14 18:55:55 +0000747}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000748
749static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000750utf8_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000751{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200752 return _PyUnicode_AsUTF8String(text, PyBytes_AS_STRING(self->errors));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000753}
754
755static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000756latin1_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000757{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200758 return _PyUnicode_AsLatin1String(text, PyBytes_AS_STRING(self->errors));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000759}
760
761/* Map normalized encoding names onto the specialized encoding funcs */
762
763typedef struct {
764 const char *name;
765 encodefunc_t encodefunc;
766} encodefuncentry;
767
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200768static const encodefuncentry encodefuncs[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000769 {"ascii", (encodefunc_t) ascii_encode},
770 {"iso8859-1", (encodefunc_t) latin1_encode},
Antoine Pitroue4501852009-05-14 18:55:55 +0000771 {"utf-8", (encodefunc_t) utf8_encode},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000772 {"utf-16-be", (encodefunc_t) utf16be_encode},
773 {"utf-16-le", (encodefunc_t) utf16le_encode},
774 {"utf-16", (encodefunc_t) utf16_encode},
Antoine Pitroue4501852009-05-14 18:55:55 +0000775 {"utf-32-be", (encodefunc_t) utf32be_encode},
776 {"utf-32-le", (encodefunc_t) utf32le_encode},
777 {"utf-32", (encodefunc_t) utf32_encode},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000778 {NULL, NULL}
779};
780
781
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300782/*[clinic input]
783_io.TextIOWrapper.__init__
784 buffer: object
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700785 encoding: str(accept={str, NoneType}) = NULL
786 errors: str(accept={str, NoneType}) = NULL
787 newline: str(accept={str, NoneType}) = NULL
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200788 line_buffering: bool(accept={int}) = False
789 write_through: bool(accept={int}) = False
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000790
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300791Character and line based layer over a BufferedIOBase object, buffer.
792
793encoding gives the name of the encoding that the stream will be
794decoded or encoded with. It defaults to locale.getpreferredencoding(False).
795
796errors determines the strictness of encoding and decoding (see
797help(codecs.Codec) or the documentation for codecs.register) and
798defaults to "strict".
799
800newline controls how line endings are handled. It can be None, '',
801'\n', '\r', and '\r\n'. It works as follows:
802
803* On input, if newline is None, universal newlines mode is
804 enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
805 these are translated into '\n' before being returned to the
806 caller. If it is '', universal newline mode is enabled, but line
807 endings are returned to the caller untranslated. If it has any of
808 the other legal values, input lines are only terminated by the given
809 string, and the line ending is returned to the caller untranslated.
810
811* On output, if newline is None, any '\n' characters written are
812 translated to the system default line separator, os.linesep. If
813 newline is '' or '\n', no translation takes place. If newline is any
814 of the other legal values, any '\n' characters written are translated
815 to the given string.
816
817If line_buffering is True, a call to flush is implied when a call to
818write contains a newline character.
819[clinic start generated code]*/
820
821static int
822_io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
823 const char *encoding, const char *errors,
824 const char *newline, int line_buffering,
825 int write_through)
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200826/*[clinic end generated code: output=56a83402ce2a8381 input=598d10cc5f2ed7dd]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300827{
828 PyObject *raw, *codec_info = NULL;
829 _PyIO_State *state = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000830 PyObject *res;
831 int r;
832
833 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000834 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000835
836 if (newline && newline[0] != '\0'
837 && !(newline[0] == '\n' && newline[1] == '\0')
838 && !(newline[0] == '\r' && newline[1] == '\0')
839 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
840 PyErr_Format(PyExc_ValueError,
841 "illegal newline value: %s", newline);
842 return -1;
843 }
844
845 Py_CLEAR(self->buffer);
846 Py_CLEAR(self->encoding);
847 Py_CLEAR(self->encoder);
848 Py_CLEAR(self->decoder);
849 Py_CLEAR(self->readnl);
850 Py_CLEAR(self->decoded_chars);
851 Py_CLEAR(self->pending_bytes);
852 Py_CLEAR(self->snapshot);
853 Py_CLEAR(self->errors);
854 Py_CLEAR(self->raw);
855 self->decoded_chars_used = 0;
856 self->pending_bytes_count = 0;
857 self->encodefunc = NULL;
Antoine Pitrou211b81d2011-02-25 20:27:33 +0000858 self->b2cratio = 0.0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000859
860 if (encoding == NULL) {
861 /* Try os.device_encoding(fileno) */
862 PyObject *fileno;
Antoine Pitrou712cb732013-12-21 15:51:54 +0100863 state = IO_STATE();
864 if (state == NULL)
865 goto error;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200866 fileno = _PyObject_CallMethodId(buffer, &PyId_fileno, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000867 /* Ignore only AttributeError and UnsupportedOperation */
868 if (fileno == NULL) {
869 if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
870 PyErr_ExceptionMatches(state->unsupported_operation)) {
871 PyErr_Clear();
872 }
873 else {
874 goto error;
875 }
876 }
877 else {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200878 int fd = _PyLong_AsInt(fileno);
Brett Cannonefb00c02012-02-29 18:31:31 -0500879 Py_DECREF(fileno);
880 if (fd == -1 && PyErr_Occurred()) {
881 goto error;
882 }
883
884 self->encoding = _Py_device_encoding(fd);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000885 if (self->encoding == NULL)
886 goto error;
887 else if (!PyUnicode_Check(self->encoding))
888 Py_CLEAR(self->encoding);
889 }
890 }
891 if (encoding == NULL && self->encoding == NULL) {
Antoine Pitrou932ff832013-08-01 21:04:50 +0200892 PyObject *locale_module = _PyIO_get_locale_module(state);
893 if (locale_module == NULL)
894 goto catch_ImportError;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100895 self->encoding = _PyObject_CallMethodIdObjArgs(
896 locale_module, &PyId_getpreferredencoding, Py_False, NULL);
Antoine Pitrou932ff832013-08-01 21:04:50 +0200897 Py_DECREF(locale_module);
898 if (self->encoding == NULL) {
899 catch_ImportError:
900 /*
Martin Panter7462b6492015-11-02 03:37:02 +0000901 Importing locale can raise an ImportError because of
902 _functools, and locale.getpreferredencoding can raise an
Antoine Pitrou932ff832013-08-01 21:04:50 +0200903 ImportError if _locale is not available. These will happen
904 during module building.
905 */
906 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
907 PyErr_Clear();
908 self->encoding = PyUnicode_FromString("ascii");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000909 }
Antoine Pitrou932ff832013-08-01 21:04:50 +0200910 else
911 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000912 }
Antoine Pitrou932ff832013-08-01 21:04:50 +0200913 else if (!PyUnicode_Check(self->encoding))
914 Py_CLEAR(self->encoding);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000915 }
Victor Stinnerf6c57832010-05-19 01:17:01 +0000916 if (self->encoding != NULL) {
Serhiy Storchaka06515832016-11-20 09:13:07 +0200917 encoding = PyUnicode_AsUTF8(self->encoding);
Victor Stinnerf6c57832010-05-19 01:17:01 +0000918 if (encoding == NULL)
919 goto error;
920 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000921 else if (encoding != NULL) {
922 self->encoding = PyUnicode_FromString(encoding);
923 if (self->encoding == NULL)
924 goto error;
925 }
926 else {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300927 PyErr_SetString(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000928 "could not determine default encoding");
929 }
930
Nick Coghlana9b15242014-02-04 22:11:18 +1000931 /* Check we have been asked for a real text encoding */
932 codec_info = _PyCodec_LookupTextEncoding(encoding, "codecs.open()");
933 if (codec_info == NULL) {
934 Py_CLEAR(self->encoding);
935 goto error;
936 }
937
938 /* XXX: Failures beyond this point have the potential to leak elements
939 * of the partially constructed object (like self->encoding)
940 */
941
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000942 if (errors == NULL)
943 errors = "strict";
944 self->errors = PyBytes_FromString(errors);
945 if (self->errors == NULL)
946 goto error;
947
948 self->chunk_size = 8192;
949 self->readuniversal = (newline == NULL || newline[0] == '\0');
950 self->line_buffering = line_buffering;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200951 self->write_through = write_through;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000952 self->readtranslate = (newline == NULL);
953 if (newline) {
954 self->readnl = PyUnicode_FromString(newline);
955 if (self->readnl == NULL)
Nick Coghlana9b15242014-02-04 22:11:18 +1000956 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957 }
958 self->writetranslate = (newline == NULL || newline[0] != '\0');
959 if (!self->readuniversal && self->readnl) {
Serhiy Storchaka06515832016-11-20 09:13:07 +0200960 self->writenl = PyUnicode_AsUTF8(self->readnl);
Victor Stinnerf6c57832010-05-19 01:17:01 +0000961 if (self->writenl == NULL)
962 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000963 if (!strcmp(self->writenl, "\n"))
964 self->writenl = NULL;
965 }
966#ifdef MS_WINDOWS
967 else
968 self->writenl = "\r\n";
969#endif
970
971 /* Build the decoder object */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200972 res = _PyObject_CallMethodId(buffer, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000973 if (res == NULL)
974 goto error;
975 r = PyObject_IsTrue(res);
976 Py_DECREF(res);
977 if (r == -1)
978 goto error;
979 if (r == 1) {
Nick Coghlana9b15242014-02-04 22:11:18 +1000980 self->decoder = _PyCodecInfo_GetIncrementalDecoder(codec_info,
981 errors);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000982 if (self->decoder == NULL)
983 goto error;
984
985 if (self->readuniversal) {
986 PyObject *incrementalDecoder = PyObject_CallFunction(
987 (PyObject *)&PyIncrementalNewlineDecoder_Type,
988 "Oi", self->decoder, (int)self->readtranslate);
989 if (incrementalDecoder == NULL)
990 goto error;
Serhiy Storchaka48842712016-04-06 09:45:48 +0300991 Py_XSETREF(self->decoder, incrementalDecoder);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000992 }
993 }
994
995 /* Build the encoder object */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200996 res = _PyObject_CallMethodId(buffer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000997 if (res == NULL)
998 goto error;
999 r = PyObject_IsTrue(res);
1000 Py_DECREF(res);
1001 if (r == -1)
1002 goto error;
1003 if (r == 1) {
Nick Coghlana9b15242014-02-04 22:11:18 +10001004 self->encoder = _PyCodecInfo_GetIncrementalEncoder(codec_info,
1005 errors);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001006 if (self->encoder == NULL)
1007 goto error;
Martin Panter536d70e2017-01-14 08:23:08 +00001008 /* Get the normalized name of the codec */
Nick Coghlana9b15242014-02-04 22:11:18 +10001009 res = _PyObject_GetAttrId(codec_info, &PyId_name);
Benjamin Peterson2cfca792009-06-06 20:46:48 +00001010 if (res == NULL) {
1011 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1012 PyErr_Clear();
1013 else
1014 goto error;
1015 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001016 else if (PyUnicode_Check(res)) {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001017 const encodefuncentry *e = encodefuncs;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001018 while (e->name != NULL) {
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001019 if (_PyUnicode_EqualToASCIIString(res, e->name)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001020 self->encodefunc = e->encodefunc;
1021 break;
1022 }
1023 e++;
1024 }
1025 }
1026 Py_XDECREF(res);
1027 }
1028
Nick Coghlana9b15242014-02-04 22:11:18 +10001029 /* Finished sorting out the codec details */
Benjamin Peterson6c14f232014-11-12 10:19:46 -05001030 Py_CLEAR(codec_info);
Nick Coghlana9b15242014-02-04 22:11:18 +10001031
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001032 self->buffer = buffer;
1033 Py_INCREF(buffer);
Antoine Pitrou24f36292009-03-28 22:16:42 +00001034
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001035 if (Py_TYPE(buffer) == &PyBufferedReader_Type ||
1036 Py_TYPE(buffer) == &PyBufferedWriter_Type ||
1037 Py_TYPE(buffer) == &PyBufferedRandom_Type) {
Martin v. Löwis767046a2011-10-14 15:35:36 +02001038 raw = _PyObject_GetAttrId(buffer, &PyId_raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001039 /* Cache the raw FileIO object to speed up 'closed' checks */
Benjamin Peterson2cfca792009-06-06 20:46:48 +00001040 if (raw == NULL) {
1041 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1042 PyErr_Clear();
1043 else
1044 goto error;
1045 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001046 else if (Py_TYPE(raw) == &PyFileIO_Type)
1047 self->raw = raw;
1048 else
1049 Py_DECREF(raw);
1050 }
1051
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001052 res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001053 if (res == NULL)
1054 goto error;
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001055 r = PyObject_IsTrue(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001056 Py_DECREF(res);
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001057 if (r < 0)
1058 goto error;
1059 self->seekable = self->telling = r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001060
Martin v. Löwis767046a2011-10-14 15:35:36 +02001061 self->has_read1 = _PyObject_HasAttrId(buffer, &PyId_read1);
Antoine Pitroue96ec682011-07-23 21:46:35 +02001062
Antoine Pitroue4501852009-05-14 18:55:55 +00001063 self->encoding_start_of_stream = 0;
1064 if (self->seekable && self->encoder) {
1065 PyObject *cookieObj;
1066 int cmp;
1067
1068 self->encoding_start_of_stream = 1;
1069
1070 cookieObj = PyObject_CallMethodObjArgs(buffer, _PyIO_str_tell, NULL);
1071 if (cookieObj == NULL)
1072 goto error;
1073
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001074 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ);
Antoine Pitroue4501852009-05-14 18:55:55 +00001075 Py_DECREF(cookieObj);
1076 if (cmp < 0) {
1077 goto error;
1078 }
1079
1080 if (cmp == 0) {
1081 self->encoding_start_of_stream = 0;
1082 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001083 _PyLong_Zero, NULL);
Antoine Pitroue4501852009-05-14 18:55:55 +00001084 if (res == NULL)
1085 goto error;
1086 Py_DECREF(res);
1087 }
1088 }
1089
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001090 self->ok = 1;
1091 return 0;
1092
1093 error:
Nick Coghlana9b15242014-02-04 22:11:18 +10001094 Py_XDECREF(codec_info);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001095 return -1;
1096}
1097
1098static int
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001099textiowrapper_clear(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001100{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001101 self->ok = 0;
1102 Py_CLEAR(self->buffer);
1103 Py_CLEAR(self->encoding);
1104 Py_CLEAR(self->encoder);
1105 Py_CLEAR(self->decoder);
1106 Py_CLEAR(self->readnl);
1107 Py_CLEAR(self->decoded_chars);
1108 Py_CLEAR(self->pending_bytes);
1109 Py_CLEAR(self->snapshot);
1110 Py_CLEAR(self->errors);
1111 Py_CLEAR(self->raw);
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001112
1113 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001114 return 0;
1115}
1116
1117static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001118textiowrapper_dealloc(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001119{
Antoine Pitrou796564c2013-07-30 19:59:21 +02001120 self->finalizing = 1;
1121 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001122 return;
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001123 self->ok = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001124 _PyObject_GC_UNTRACK(self);
1125 if (self->weakreflist != NULL)
1126 PyObject_ClearWeakRefs((PyObject *)self);
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001127 textiowrapper_clear(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001128 Py_TYPE(self)->tp_free((PyObject *)self);
1129}
1130
1131static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001132textiowrapper_traverse(textio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001133{
1134 Py_VISIT(self->buffer);
1135 Py_VISIT(self->encoding);
1136 Py_VISIT(self->encoder);
1137 Py_VISIT(self->decoder);
1138 Py_VISIT(self->readnl);
1139 Py_VISIT(self->decoded_chars);
1140 Py_VISIT(self->pending_bytes);
1141 Py_VISIT(self->snapshot);
1142 Py_VISIT(self->errors);
1143 Py_VISIT(self->raw);
1144
1145 Py_VISIT(self->dict);
1146 return 0;
1147}
1148
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001149static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001150textiowrapper_closed_get(textio *self, void *context);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001151
1152/* This macro takes some shortcuts to make the common case faster. */
1153#define CHECK_CLOSED(self) \
1154 do { \
1155 int r; \
1156 PyObject *_res; \
1157 if (Py_TYPE(self) == &PyTextIOWrapper_Type) { \
1158 if (self->raw != NULL) \
1159 r = _PyFileIO_closed(self->raw); \
1160 else { \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001161 _res = textiowrapper_closed_get(self, NULL); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001162 if (_res == NULL) \
1163 return NULL; \
1164 r = PyObject_IsTrue(_res); \
1165 Py_DECREF(_res); \
1166 if (r < 0) \
1167 return NULL; \
1168 } \
1169 if (r > 0) { \
1170 PyErr_SetString(PyExc_ValueError, \
1171 "I/O operation on closed file."); \
1172 return NULL; \
1173 } \
1174 } \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001175 else if (_PyIOBase_check_closed((PyObject *)self, Py_True) == NULL) \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001176 return NULL; \
1177 } while (0)
1178
1179#define CHECK_INITIALIZED(self) \
1180 if (self->ok <= 0) { \
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001181 PyErr_SetString(PyExc_ValueError, \
1182 "I/O operation on uninitialized object"); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001183 return NULL; \
1184 }
1185
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001186#define CHECK_ATTACHED(self) \
1187 CHECK_INITIALIZED(self); \
1188 if (self->detached) { \
1189 PyErr_SetString(PyExc_ValueError, \
1190 "underlying buffer has been detached"); \
1191 return NULL; \
1192 }
1193
1194#define CHECK_ATTACHED_INT(self) \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001195 if (self->ok <= 0) { \
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001196 PyErr_SetString(PyExc_ValueError, \
1197 "I/O operation on uninitialized object"); \
1198 return -1; \
1199 } else if (self->detached) { \
1200 PyErr_SetString(PyExc_ValueError, \
1201 "underlying buffer has been detached"); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001202 return -1; \
1203 }
1204
1205
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001206/*[clinic input]
1207_io.TextIOWrapper.detach
1208[clinic start generated code]*/
1209
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001210static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001211_io_TextIOWrapper_detach_impl(textio *self)
1212/*[clinic end generated code: output=7ba3715cd032d5f2 input=e5a71fbda9e1d9f9]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001213{
1214 PyObject *buffer, *res;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001215 CHECK_ATTACHED(self);
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001216 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
1217 if (res == NULL)
1218 return NULL;
1219 Py_DECREF(res);
1220 buffer = self->buffer;
1221 self->buffer = NULL;
1222 self->detached = 1;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001223 return buffer;
1224}
1225
Antoine Pitrou24f36292009-03-28 22:16:42 +00001226/* Flush the internal write buffer. This doesn't explicitly flush the
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001227 underlying buffered object, though. */
1228static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001229_textiowrapper_writeflush(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001230{
Amaury Forgeot d'Arcccd686a2009-08-29 23:00:38 +00001231 PyObject *pending, *b, *ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001232
1233 if (self->pending_bytes == NULL)
1234 return 0;
Amaury Forgeot d'Arcccd686a2009-08-29 23:00:38 +00001235
1236 pending = self->pending_bytes;
1237 Py_INCREF(pending);
1238 self->pending_bytes_count = 0;
1239 Py_CLEAR(self->pending_bytes);
1240
1241 b = _PyBytes_Join(_PyIO_empty_bytes, pending);
1242 Py_DECREF(pending);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001243 if (b == NULL)
1244 return -1;
Gregory P. Smithb9817b02013-02-01 13:03:39 -08001245 ret = NULL;
1246 do {
1247 ret = PyObject_CallMethodObjArgs(self->buffer,
1248 _PyIO_str_write, b, NULL);
1249 } while (ret == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001250 Py_DECREF(b);
1251 if (ret == NULL)
1252 return -1;
1253 Py_DECREF(ret);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001254 return 0;
1255}
1256
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001257/*[clinic input]
1258_io.TextIOWrapper.write
1259 text: unicode
1260 /
1261[clinic start generated code]*/
1262
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001263static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001264_io_TextIOWrapper_write_impl(textio *self, PyObject *text)
1265/*[clinic end generated code: output=d2deb0d50771fcec input=fdf19153584a0e44]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001266{
1267 PyObject *ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001268 PyObject *b;
1269 Py_ssize_t textlen;
1270 int haslf = 0;
Antoine Pitrouc644e7c2014-05-09 00:24:50 +02001271 int needflush = 0, text_needflush = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001272
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001273 if (PyUnicode_READY(text) == -1)
1274 return NULL;
1275
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001276 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001277 CHECK_CLOSED(self);
1278
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001279 if (self->encoder == NULL)
1280 return _unsupported("not writable");
Benjamin Peterson81971ea2009-05-14 22:01:31 +00001281
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001282 Py_INCREF(text);
1283
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001284 textlen = PyUnicode_GET_LENGTH(text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001285
1286 if ((self->writetranslate && self->writenl != NULL) || self->line_buffering)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001287 if (PyUnicode_FindChar(text, '\n', 0, PyUnicode_GET_LENGTH(text), 1) != -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288 haslf = 1;
1289
1290 if (haslf && self->writetranslate && self->writenl != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001291 PyObject *newtext = _PyObject_CallMethodId(
1292 text, &PyId_replace, "ss", "\n", self->writenl);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001293 Py_DECREF(text);
1294 if (newtext == NULL)
1295 return NULL;
1296 text = newtext;
1297 }
1298
Antoine Pitroue96ec682011-07-23 21:46:35 +02001299 if (self->write_through)
Antoine Pitrouc644e7c2014-05-09 00:24:50 +02001300 text_needflush = 1;
1301 if (self->line_buffering &&
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001302 (haslf ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001303 PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001304 needflush = 1;
1305
1306 /* XXX What if we were just reading? */
Antoine Pitroue4501852009-05-14 18:55:55 +00001307 if (self->encodefunc != NULL) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001308 b = (*self->encodefunc)((PyObject *) self, text);
Antoine Pitroue4501852009-05-14 18:55:55 +00001309 self->encoding_start_of_stream = 0;
1310 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001311 else
1312 b = PyObject_CallMethodObjArgs(self->encoder,
1313 _PyIO_str_encode, text, NULL);
1314 Py_DECREF(text);
1315 if (b == NULL)
1316 return NULL;
1317
1318 if (self->pending_bytes == NULL) {
1319 self->pending_bytes = PyList_New(0);
1320 if (self->pending_bytes == NULL) {
1321 Py_DECREF(b);
1322 return NULL;
1323 }
1324 self->pending_bytes_count = 0;
1325 }
1326 if (PyList_Append(self->pending_bytes, b) < 0) {
1327 Py_DECREF(b);
1328 return NULL;
1329 }
1330 self->pending_bytes_count += PyBytes_GET_SIZE(b);
1331 Py_DECREF(b);
Antoine Pitrouc644e7c2014-05-09 00:24:50 +02001332 if (self->pending_bytes_count > self->chunk_size || needflush ||
1333 text_needflush) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001334 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001335 return NULL;
1336 }
Antoine Pitrou24f36292009-03-28 22:16:42 +00001337
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001338 if (needflush) {
1339 ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL);
1340 if (ret == NULL)
1341 return NULL;
1342 Py_DECREF(ret);
1343 }
1344
1345 Py_CLEAR(self->snapshot);
1346
1347 if (self->decoder) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001348 ret = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001349 if (ret == NULL)
1350 return NULL;
1351 Py_DECREF(ret);
1352 }
1353
1354 return PyLong_FromSsize_t(textlen);
1355}
1356
1357/* Steal a reference to chars and store it in the decoded_char buffer;
1358 */
1359static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001360textiowrapper_set_decoded_chars(textio *self, PyObject *chars)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001361{
Serhiy Storchaka48842712016-04-06 09:45:48 +03001362 Py_XSETREF(self->decoded_chars, chars);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001363 self->decoded_chars_used = 0;
1364}
1365
1366static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001367textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001368{
1369 PyObject *chars;
1370 Py_ssize_t avail;
1371
1372 if (self->decoded_chars == NULL)
1373 return PyUnicode_FromStringAndSize(NULL, 0);
1374
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001375 /* decoded_chars is guaranteed to be "ready". */
1376 avail = (PyUnicode_GET_LENGTH(self->decoded_chars)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001377 - self->decoded_chars_used);
1378
1379 assert(avail >= 0);
1380
1381 if (n < 0 || n > avail)
1382 n = avail;
1383
1384 if (self->decoded_chars_used > 0 || n < avail) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001385 chars = PyUnicode_Substring(self->decoded_chars,
1386 self->decoded_chars_used,
1387 self->decoded_chars_used + n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001388 if (chars == NULL)
1389 return NULL;
1390 }
1391 else {
1392 chars = self->decoded_chars;
1393 Py_INCREF(chars);
1394 }
1395
1396 self->decoded_chars_used += n;
1397 return chars;
1398}
1399
1400/* Read and decode the next chunk of data from the BufferedReader.
1401 */
1402static int
Antoine Pitroue5324562011-11-19 00:39:01 +01001403textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001404{
1405 PyObject *dec_buffer = NULL;
1406 PyObject *dec_flags = NULL;
1407 PyObject *input_chunk = NULL;
Antoine Pitroub8503892014-04-29 10:14:02 +02001408 Py_buffer input_chunk_buf;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001409 PyObject *decoded_chars, *chunk_size;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00001410 Py_ssize_t nbytes, nchars;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001411 int eof;
1412
1413 /* The return value is True unless EOF was reached. The decoded string is
1414 * placed in self._decoded_chars (replacing its previous value). The
1415 * entire input chunk is sent to the decoder, though some of it may remain
1416 * buffered in the decoder, yet to be converted.
1417 */
1418
1419 if (self->decoder == NULL) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001420 _unsupported("not readable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001421 return -1;
1422 }
1423
1424 if (self->telling) {
1425 /* To prepare for tell(), we need to snapshot a point in the file
1426 * where the decoder's input buffer is empty.
1427 */
1428
1429 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
1430 _PyIO_str_getstate, NULL);
1431 if (state == NULL)
1432 return -1;
1433 /* Given this, we know there was a valid snapshot point
1434 * len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
1435 */
Serhiy Storchakabb72c472015-04-19 20:38:19 +03001436 if (PyArg_ParseTuple(state, "OO", &dec_buffer, &dec_flags) < 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001437 Py_DECREF(state);
1438 return -1;
1439 }
Antoine Pitroub8503892014-04-29 10:14:02 +02001440
1441 if (!PyBytes_Check(dec_buffer)) {
1442 PyErr_Format(PyExc_TypeError,
1443 "decoder getstate() should have returned a bytes "
1444 "object, not '%.200s'",
1445 Py_TYPE(dec_buffer)->tp_name);
1446 Py_DECREF(state);
1447 return -1;
1448 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001449 Py_INCREF(dec_buffer);
1450 Py_INCREF(dec_flags);
1451 Py_DECREF(state);
1452 }
1453
1454 /* Read a chunk, decode it, and put the result in self._decoded_chars. */
Antoine Pitroue5324562011-11-19 00:39:01 +01001455 if (size_hint > 0) {
Victor Stinnerf8facac2011-11-22 02:30:47 +01001456 size_hint = (Py_ssize_t)(Py_MAX(self->b2cratio, 1.0) * size_hint);
Antoine Pitroue5324562011-11-19 00:39:01 +01001457 }
1458 chunk_size = PyLong_FromSsize_t(Py_MAX(self->chunk_size, size_hint));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001459 if (chunk_size == NULL)
1460 goto fail;
Antoine Pitroub8503892014-04-29 10:14:02 +02001461
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001462 input_chunk = PyObject_CallMethodObjArgs(self->buffer,
Antoine Pitroue96ec682011-07-23 21:46:35 +02001463 (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read),
1464 chunk_size, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001465 Py_DECREF(chunk_size);
1466 if (input_chunk == NULL)
1467 goto fail;
Antoine Pitroub8503892014-04-29 10:14:02 +02001468
1469 if (PyObject_GetBuffer(input_chunk, &input_chunk_buf, 0) != 0) {
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001470 PyErr_Format(PyExc_TypeError,
Antoine Pitroub8503892014-04-29 10:14:02 +02001471 "underlying %s() should have returned a bytes-like object, "
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001472 "not '%.200s'", (self->has_read1 ? "read1": "read"),
1473 Py_TYPE(input_chunk)->tp_name);
1474 goto fail;
1475 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001476
Antoine Pitroub8503892014-04-29 10:14:02 +02001477 nbytes = input_chunk_buf.len;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00001478 eof = (nbytes == 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001479 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) {
1480 decoded_chars = _PyIncrementalNewlineDecoder_decode(
1481 self->decoder, input_chunk, eof);
1482 }
1483 else {
1484 decoded_chars = PyObject_CallMethodObjArgs(self->decoder,
1485 _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL);
1486 }
Antoine Pitroub8503892014-04-29 10:14:02 +02001487 PyBuffer_Release(&input_chunk_buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001488
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001489 if (check_decoded(decoded_chars) < 0)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001490 goto fail;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001491 textiowrapper_set_decoded_chars(self, decoded_chars);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001492 nchars = PyUnicode_GET_LENGTH(decoded_chars);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00001493 if (nchars > 0)
1494 self->b2cratio = (double) nbytes / nchars;
1495 else
1496 self->b2cratio = 0.0;
1497 if (nchars > 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001498 eof = 0;
1499
1500 if (self->telling) {
1501 /* At the snapshot point, len(dec_buffer) bytes before the read, the
1502 * next input to be decoded is dec_buffer + input_chunk.
1503 */
Antoine Pitroub8503892014-04-29 10:14:02 +02001504 PyObject *next_input = dec_buffer;
1505 PyBytes_Concat(&next_input, input_chunk);
1506 if (next_input == NULL) {
1507 dec_buffer = NULL; /* Reference lost to PyBytes_Concat */
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001508 goto fail;
1509 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001510 Py_XSETREF(self->snapshot, Py_BuildValue("NN", dec_flags, next_input));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001511 }
1512 Py_DECREF(input_chunk);
1513
1514 return (eof == 0);
1515
1516 fail:
1517 Py_XDECREF(dec_buffer);
1518 Py_XDECREF(dec_flags);
1519 Py_XDECREF(input_chunk);
1520 return -1;
1521}
1522
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001523/*[clinic input]
1524_io.TextIOWrapper.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001525 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001526 /
1527[clinic start generated code]*/
1528
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001529static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001530_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001531/*[clinic end generated code: output=7e651ce6cc6a25a6 input=123eecbfe214aeb8]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001532{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001533 PyObject *result = NULL, *chunks = NULL;
1534
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001535 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001536 CHECK_CLOSED(self);
1537
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001538 if (self->decoder == NULL)
1539 return _unsupported("not readable");
Benjamin Petersona1b49012009-03-31 23:11:32 +00001540
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001541 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001542 return NULL;
1543
1544 if (n < 0) {
1545 /* Read everything */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001546 PyObject *bytes = _PyObject_CallMethodId(self->buffer, &PyId_read, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001547 PyObject *decoded;
1548 if (bytes == NULL)
1549 goto fail;
Victor Stinnerfd821132011-05-25 22:01:33 +02001550
1551 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type)
1552 decoded = _PyIncrementalNewlineDecoder_decode(self->decoder,
1553 bytes, 1);
1554 else
1555 decoded = PyObject_CallMethodObjArgs(
1556 self->decoder, _PyIO_str_decode, bytes, Py_True, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001557 Py_DECREF(bytes);
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001558 if (check_decoded(decoded) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001559 goto fail;
1560
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001561 result = textiowrapper_get_decoded_chars(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001562
1563 if (result == NULL) {
1564 Py_DECREF(decoded);
1565 return NULL;
1566 }
1567
1568 PyUnicode_AppendAndDel(&result, decoded);
1569 if (result == NULL)
1570 goto fail;
1571
1572 Py_CLEAR(self->snapshot);
1573 return result;
1574 }
1575 else {
1576 int res = 1;
1577 Py_ssize_t remaining = n;
1578
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001579 result = textiowrapper_get_decoded_chars(self, n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001580 if (result == NULL)
1581 goto fail;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001582 if (PyUnicode_READY(result) == -1)
1583 goto fail;
1584 remaining -= PyUnicode_GET_LENGTH(result);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001585
1586 /* Keep reading chunks until we have n characters to return */
1587 while (remaining > 0) {
Antoine Pitroue5324562011-11-19 00:39:01 +01001588 res = textiowrapper_read_chunk(self, remaining);
Gregory P. Smith51359922012-06-23 23:55:39 -07001589 if (res < 0) {
1590 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1591 when EINTR occurs so we needn't do it ourselves. */
1592 if (_PyIO_trap_eintr()) {
1593 continue;
1594 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001595 goto fail;
Gregory P. Smith51359922012-06-23 23:55:39 -07001596 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001597 if (res == 0) /* EOF */
1598 break;
1599 if (chunks == NULL) {
1600 chunks = PyList_New(0);
1601 if (chunks == NULL)
1602 goto fail;
1603 }
Antoine Pitroue5324562011-11-19 00:39:01 +01001604 if (PyUnicode_GET_LENGTH(result) > 0 &&
1605 PyList_Append(chunks, result) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001606 goto fail;
1607 Py_DECREF(result);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001608 result = textiowrapper_get_decoded_chars(self, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001609 if (result == NULL)
1610 goto fail;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001611 remaining -= PyUnicode_GET_LENGTH(result);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001612 }
1613 if (chunks != NULL) {
1614 if (result != NULL && PyList_Append(chunks, result) < 0)
1615 goto fail;
Serhiy Storchaka48842712016-04-06 09:45:48 +03001616 Py_XSETREF(result, PyUnicode_Join(_PyIO_empty_str, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001617 if (result == NULL)
1618 goto fail;
1619 Py_CLEAR(chunks);
1620 }
1621 return result;
1622 }
1623 fail:
1624 Py_XDECREF(result);
1625 Py_XDECREF(chunks);
1626 return NULL;
1627}
1628
1629
Victor Stinnerf7b8cb62011-09-29 03:28:17 +02001630/* NOTE: `end` must point to the real end of the Py_UCS4 storage,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001631 that is to the NUL character. Otherwise the function will produce
1632 incorrect results. */
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001633static const char *
1634find_control_char(int kind, const char *s, const char *end, Py_UCS4 ch)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001635{
Antoine Pitrouc28e2e52011-11-13 03:53:42 +01001636 if (kind == PyUnicode_1BYTE_KIND) {
1637 assert(ch < 256);
1638 return (char *) memchr((void *) s, (char) ch, end - s);
1639 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001640 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001641 while (PyUnicode_READ(kind, s, 0) > ch)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001642 s += kind;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001643 if (PyUnicode_READ(kind, s, 0) == ch)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001644 return s;
1645 if (s == end)
1646 return NULL;
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001647 s += kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001648 }
1649}
1650
1651Py_ssize_t
1652_PyIO_find_line_ending(
1653 int translated, int universal, PyObject *readnl,
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001654 int kind, const char *start, const char *end, Py_ssize_t *consumed)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001655{
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001656 Py_ssize_t len = ((char*)end - (char*)start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001657
1658 if (translated) {
1659 /* Newlines are already translated, only search for \n */
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001660 const char *pos = find_control_char(kind, start, end, '\n');
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001661 if (pos != NULL)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001662 return (pos - start)/kind + 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001663 else {
1664 *consumed = len;
1665 return -1;
1666 }
1667 }
1668 else if (universal) {
1669 /* Universal newline search. Find any of \r, \r\n, \n
1670 * The decoder ensures that \r\n are not split in two pieces
1671 */
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001672 const char *s = start;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001673 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001674 Py_UCS4 ch;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001675 /* Fast path for non-control chars. The loop always ends
Victor Stinnerf7b8cb62011-09-29 03:28:17 +02001676 since the Unicode string is NUL-terminated. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001677 while (PyUnicode_READ(kind, s, 0) > '\r')
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001678 s += kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001679 if (s >= end) {
1680 *consumed = len;
1681 return -1;
1682 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001683 ch = PyUnicode_READ(kind, s, 0);
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001684 s += kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001685 if (ch == '\n')
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001686 return (s - start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001687 if (ch == '\r') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001688 if (PyUnicode_READ(kind, s, 0) == '\n')
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001689 return (s - start)/kind + 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001690 else
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001691 return (s - start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001692 }
1693 }
1694 }
1695 else {
1696 /* Non-universal mode. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001697 Py_ssize_t readnl_len = PyUnicode_GET_LENGTH(readnl);
Victor Stinner706768c2014-08-16 01:03:39 +02001698 Py_UCS1 *nl = PyUnicode_1BYTE_DATA(readnl);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001699 /* Assume that readnl is an ASCII character. */
1700 assert(PyUnicode_KIND(readnl) == PyUnicode_1BYTE_KIND);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001701 if (readnl_len == 1) {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001702 const char *pos = find_control_char(kind, start, end, nl[0]);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001703 if (pos != NULL)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001704 return (pos - start)/kind + 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001705 *consumed = len;
1706 return -1;
1707 }
1708 else {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001709 const char *s = start;
1710 const char *e = end - (readnl_len - 1)*kind;
1711 const char *pos;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001712 if (e < s)
1713 e = s;
1714 while (s < e) {
1715 Py_ssize_t i;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001716 const char *pos = find_control_char(kind, s, end, nl[0]);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001717 if (pos == NULL || pos >= e)
1718 break;
1719 for (i = 1; i < readnl_len; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001720 if (PyUnicode_READ(kind, pos, i) != nl[i])
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001721 break;
1722 }
1723 if (i == readnl_len)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001724 return (pos - start)/kind + readnl_len;
1725 s = pos + kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001726 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001727 pos = find_control_char(kind, e, end, nl[0]);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001728 if (pos == NULL)
1729 *consumed = len;
1730 else
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001731 *consumed = (pos - start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001732 return -1;
1733 }
1734 }
1735}
1736
1737static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001738_textiowrapper_readline(textio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001739{
1740 PyObject *line = NULL, *chunks = NULL, *remaining = NULL;
1741 Py_ssize_t start, endpos, chunked, offset_to_buffer;
1742 int res;
1743
1744 CHECK_CLOSED(self);
1745
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001746 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001747 return NULL;
1748
1749 chunked = 0;
1750
1751 while (1) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001752 char *ptr;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001753 Py_ssize_t line_len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001754 int kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001755 Py_ssize_t consumed = 0;
1756
1757 /* First, get some data if necessary */
1758 res = 1;
1759 while (!self->decoded_chars ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001760 !PyUnicode_GET_LENGTH(self->decoded_chars)) {
Antoine Pitroue5324562011-11-19 00:39:01 +01001761 res = textiowrapper_read_chunk(self, 0);
Gregory P. Smith51359922012-06-23 23:55:39 -07001762 if (res < 0) {
1763 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1764 when EINTR occurs so we needn't do it ourselves. */
1765 if (_PyIO_trap_eintr()) {
1766 continue;
1767 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001768 goto error;
Gregory P. Smith51359922012-06-23 23:55:39 -07001769 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001770 if (res == 0)
1771 break;
1772 }
1773 if (res == 0) {
1774 /* end of file */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001775 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001776 Py_CLEAR(self->snapshot);
1777 start = endpos = offset_to_buffer = 0;
1778 break;
1779 }
1780
1781 if (remaining == NULL) {
1782 line = self->decoded_chars;
1783 start = self->decoded_chars_used;
1784 offset_to_buffer = 0;
1785 Py_INCREF(line);
1786 }
1787 else {
1788 assert(self->decoded_chars_used == 0);
1789 line = PyUnicode_Concat(remaining, self->decoded_chars);
1790 start = 0;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001791 offset_to_buffer = PyUnicode_GET_LENGTH(remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001792 Py_CLEAR(remaining);
1793 if (line == NULL)
1794 goto error;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001795 if (PyUnicode_READY(line) == -1)
1796 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797 }
1798
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001799 ptr = PyUnicode_DATA(line);
1800 line_len = PyUnicode_GET_LENGTH(line);
1801 kind = PyUnicode_KIND(line);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001802
1803 endpos = _PyIO_find_line_ending(
1804 self->readtranslate, self->readuniversal, self->readnl,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001805 kind,
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001806 ptr + kind * start,
1807 ptr + kind * line_len,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001808 &consumed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001809 if (endpos >= 0) {
1810 endpos += start;
1811 if (limit >= 0 && (endpos - start) + chunked >= limit)
1812 endpos = start + limit - chunked;
1813 break;
1814 }
1815
1816 /* We can put aside up to `endpos` */
1817 endpos = consumed + start;
1818 if (limit >= 0 && (endpos - start) + chunked >= limit) {
1819 /* Didn't find line ending, but reached length limit */
1820 endpos = start + limit - chunked;
1821 break;
1822 }
1823
1824 if (endpos > start) {
1825 /* No line ending seen yet - put aside current data */
1826 PyObject *s;
1827 if (chunks == NULL) {
1828 chunks = PyList_New(0);
1829 if (chunks == NULL)
1830 goto error;
1831 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001832 s = PyUnicode_Substring(line, start, endpos);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001833 if (s == NULL)
1834 goto error;
1835 if (PyList_Append(chunks, s) < 0) {
1836 Py_DECREF(s);
1837 goto error;
1838 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001839 chunked += PyUnicode_GET_LENGTH(s);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001840 Py_DECREF(s);
1841 }
1842 /* There may be some remaining bytes we'll have to prepend to the
1843 next chunk of data */
1844 if (endpos < line_len) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001845 remaining = PyUnicode_Substring(line, endpos, line_len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001846 if (remaining == NULL)
1847 goto error;
1848 }
1849 Py_CLEAR(line);
1850 /* We have consumed the buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001851 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001852 }
1853
1854 if (line != NULL) {
1855 /* Our line ends in the current buffer */
1856 self->decoded_chars_used = endpos - offset_to_buffer;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001857 if (start > 0 || endpos < PyUnicode_GET_LENGTH(line)) {
1858 PyObject *s = PyUnicode_Substring(line, start, endpos);
1859 Py_CLEAR(line);
1860 if (s == NULL)
1861 goto error;
1862 line = s;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001863 }
1864 }
1865 if (remaining != NULL) {
1866 if (chunks == NULL) {
1867 chunks = PyList_New(0);
1868 if (chunks == NULL)
1869 goto error;
1870 }
1871 if (PyList_Append(chunks, remaining) < 0)
1872 goto error;
1873 Py_CLEAR(remaining);
1874 }
1875 if (chunks != NULL) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001876 if (line != NULL) {
1877 if (PyList_Append(chunks, line) < 0)
1878 goto error;
1879 Py_DECREF(line);
1880 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001881 line = PyUnicode_Join(_PyIO_empty_str, chunks);
1882 if (line == NULL)
1883 goto error;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001884 Py_CLEAR(chunks);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001885 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001886 if (line == NULL) {
1887 Py_INCREF(_PyIO_empty_str);
1888 line = _PyIO_empty_str;
1889 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001890
1891 return line;
1892
1893 error:
1894 Py_XDECREF(chunks);
1895 Py_XDECREF(remaining);
1896 Py_XDECREF(line);
1897 return NULL;
1898}
1899
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001900/*[clinic input]
1901_io.TextIOWrapper.readline
1902 size: Py_ssize_t = -1
1903 /
1904[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001905
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001906static PyObject *
1907_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size)
1908/*[clinic end generated code: output=344afa98804e8b25 input=56c7172483b36db6]*/
1909{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001910 CHECK_ATTACHED(self);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001911 return _textiowrapper_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001912}
1913
1914/* Seek and Tell */
1915
1916typedef struct {
1917 Py_off_t start_pos;
1918 int dec_flags;
1919 int bytes_to_feed;
1920 int chars_to_skip;
1921 char need_eof;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001922} cookie_type;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001923
1924/*
1925 To speed up cookie packing/unpacking, we store the fields in a temporary
1926 string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.).
1927 The following macros define at which offsets in the intermediary byte
1928 string the various CookieStruct fields will be stored.
1929 */
1930
1931#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char))
1932
Christian Heimes743e0cd2012-10-17 23:52:17 +02001933#if PY_BIG_ENDIAN
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001934/* We want the least significant byte of start_pos to also be the least
1935 significant byte of the cookie, which means that in big-endian mode we
1936 must copy the fields in reverse order. */
1937
1938# define OFF_START_POS (sizeof(char) + 3 * sizeof(int))
1939# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int))
1940# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int))
1941# define OFF_CHARS_TO_SKIP (sizeof(char))
1942# define OFF_NEED_EOF 0
1943
1944#else
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001945/* Little-endian mode: the least significant byte of start_pos will
1946 naturally end up the least significant byte of the cookie. */
1947
1948# define OFF_START_POS 0
1949# define OFF_DEC_FLAGS (sizeof(Py_off_t))
1950# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int))
1951# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int))
1952# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int))
1953
1954#endif
1955
1956static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001957textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001958{
1959 unsigned char buffer[COOKIE_BUF_LEN];
1960 PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj);
1961 if (cookieLong == NULL)
1962 return -1;
1963
1964 if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
Christian Heimes743e0cd2012-10-17 23:52:17 +02001965 PY_LITTLE_ENDIAN, 0) < 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001966 Py_DECREF(cookieLong);
1967 return -1;
1968 }
1969 Py_DECREF(cookieLong);
1970
Antoine Pitrou2db74c22009-03-06 21:49:02 +00001971 memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos));
1972 memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags));
1973 memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed));
1974 memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip));
1975 memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001976
1977 return 0;
1978}
1979
1980static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001981textiowrapper_build_cookie(cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001982{
1983 unsigned char buffer[COOKIE_BUF_LEN];
1984
Antoine Pitrou2db74c22009-03-06 21:49:02 +00001985 memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos));
1986 memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags));
1987 memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed));
1988 memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip));
1989 memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001990
Christian Heimes743e0cd2012-10-17 23:52:17 +02001991 return _PyLong_FromByteArray(buffer, sizeof(buffer),
1992 PY_LITTLE_ENDIAN, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001994
1995static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001996_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001997{
1998 PyObject *res;
1999 /* When seeking to the start of the stream, we call decoder.reset()
2000 rather than decoder.getstate().
2001 This is for a few decoders such as utf-16 for which the state value
2002 at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of
2003 utf-16, that we are expecting a BOM).
2004 */
2005 if (cookie->start_pos == 0 && cookie->dec_flags == 0)
2006 res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
2007 else
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002008 res = _PyObject_CallMethodId(self->decoder, &PyId_setstate,
2009 "((yi))", "", cookie->dec_flags);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 if (res == NULL)
2011 return -1;
2012 Py_DECREF(res);
2013 return 0;
2014}
2015
Antoine Pitroue4501852009-05-14 18:55:55 +00002016static int
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002017_textiowrapper_encoder_reset(textio *self, int start_of_stream)
Antoine Pitroue4501852009-05-14 18:55:55 +00002018{
2019 PyObject *res;
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002020 if (start_of_stream) {
Antoine Pitroue4501852009-05-14 18:55:55 +00002021 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL);
2022 self->encoding_start_of_stream = 1;
2023 }
2024 else {
2025 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002026 _PyLong_Zero, NULL);
Antoine Pitroue4501852009-05-14 18:55:55 +00002027 self->encoding_start_of_stream = 0;
2028 }
2029 if (res == NULL)
2030 return -1;
2031 Py_DECREF(res);
2032 return 0;
2033}
2034
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002035static int
2036_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie)
2037{
2038 /* Same as _textiowrapper_decoder_setstate() above. */
2039 return _textiowrapper_encoder_reset(
2040 self, cookie->start_pos == 0 && cookie->dec_flags == 0);
2041}
2042
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002043/*[clinic input]
2044_io.TextIOWrapper.seek
2045 cookie as cookieObj: object
2046 whence: int = 0
2047 /
2048[clinic start generated code]*/
2049
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002050static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002051_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence)
2052/*[clinic end generated code: output=0a15679764e2d04d input=0458abeb3d7842be]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002053{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002054 PyObject *posobj;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002055 cookie_type cookie;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002056 PyObject *res;
2057 int cmp;
2058
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002059 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002060 CHECK_CLOSED(self);
2061
2062 Py_INCREF(cookieObj);
2063
2064 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002065 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002066 goto fail;
2067 }
2068
2069 if (whence == 1) {
2070 /* seek relative to current position */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002071 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002072 if (cmp < 0)
2073 goto fail;
2074
2075 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002076 _unsupported("can't do nonzero cur-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002077 goto fail;
2078 }
2079
2080 /* Seeking to the current position should attempt to
2081 * sync the underlying buffer with the current position.
2082 */
2083 Py_DECREF(cookieObj);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002084 cookieObj = _PyObject_CallMethodId((PyObject *)self, &PyId_tell, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002085 if (cookieObj == NULL)
2086 goto fail;
2087 }
2088 else if (whence == 2) {
2089 /* seek relative to end of file */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002090 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002091 if (cmp < 0)
2092 goto fail;
2093
2094 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002095 _unsupported("can't do nonzero end-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002096 goto fail;
2097 }
2098
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002099 res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002100 if (res == NULL)
2101 goto fail;
2102 Py_DECREF(res);
2103
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002104 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002105 Py_CLEAR(self->snapshot);
2106 if (self->decoder) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002107 res = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002108 if (res == NULL)
2109 goto fail;
2110 Py_DECREF(res);
2111 }
2112
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002113 res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2);
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002114 Py_CLEAR(cookieObj);
2115 if (res == NULL)
2116 goto fail;
2117 if (self->encoder) {
2118 /* If seek() == 0, we are at the start of stream, otherwise not */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002119 cmp = PyObject_RichCompareBool(res, _PyLong_Zero, Py_EQ);
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002120 if (cmp < 0 || _textiowrapper_encoder_reset(self, cmp)) {
2121 Py_DECREF(res);
2122 goto fail;
2123 }
2124 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002125 return res;
2126 }
2127 else if (whence != 0) {
2128 PyErr_Format(PyExc_ValueError,
2129 "invalid whence (%d, should be 0, 1 or 2)", whence);
2130 goto fail;
2131 }
2132
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002133 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_LT);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002134 if (cmp < 0)
2135 goto fail;
2136
2137 if (cmp == 1) {
2138 PyErr_Format(PyExc_ValueError,
2139 "negative seek position %R", cookieObj);
2140 goto fail;
2141 }
2142
2143 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
2144 if (res == NULL)
2145 goto fail;
2146 Py_DECREF(res);
2147
2148 /* The strategy of seek() is to go back to the safe start point
2149 * and replay the effect of read(chars_to_skip) from there.
2150 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002151 if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002152 goto fail;
2153
2154 /* Seek back to the safe start point. */
2155 posobj = PyLong_FromOff_t(cookie.start_pos);
2156 if (posobj == NULL)
2157 goto fail;
2158 res = PyObject_CallMethodObjArgs(self->buffer,
2159 _PyIO_str_seek, posobj, NULL);
2160 Py_DECREF(posobj);
2161 if (res == NULL)
2162 goto fail;
2163 Py_DECREF(res);
2164
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002165 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166 Py_CLEAR(self->snapshot);
2167
2168 /* Restore the decoder to its state from the safe start point. */
2169 if (self->decoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002170 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002171 goto fail;
2172 }
2173
2174 if (cookie.chars_to_skip) {
2175 /* Just like _read_chunk, feed the decoder and save a snapshot. */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002176 PyObject *input_chunk = _PyObject_CallMethodId(
2177 self->buffer, &PyId_read, "i", cookie.bytes_to_feed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002178 PyObject *decoded;
2179
2180 if (input_chunk == NULL)
2181 goto fail;
2182
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02002183 if (!PyBytes_Check(input_chunk)) {
2184 PyErr_Format(PyExc_TypeError,
2185 "underlying read() should have returned a bytes "
2186 "object, not '%.200s'",
2187 Py_TYPE(input_chunk)->tp_name);
2188 Py_DECREF(input_chunk);
2189 goto fail;
2190 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002191
2192 self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
2193 if (self->snapshot == NULL) {
2194 Py_DECREF(input_chunk);
2195 goto fail;
2196 }
2197
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002198 decoded = _PyObject_CallMethodId(self->decoder, &PyId_decode,
2199 "Oi", input_chunk, (int)cookie.need_eof);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002200
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02002201 if (check_decoded(decoded) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002202 goto fail;
2203
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002204 textiowrapper_set_decoded_chars(self, decoded);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002205
2206 /* Skip chars_to_skip of the decoded characters. */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002207 if (PyUnicode_GetLength(self->decoded_chars) < cookie.chars_to_skip) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002208 PyErr_SetString(PyExc_OSError, "can't restore logical file position");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002209 goto fail;
2210 }
2211 self->decoded_chars_used = cookie.chars_to_skip;
2212 }
2213 else {
2214 self->snapshot = Py_BuildValue("iy", cookie.dec_flags, "");
2215 if (self->snapshot == NULL)
2216 goto fail;
2217 }
2218
Antoine Pitroue4501852009-05-14 18:55:55 +00002219 /* Finally, reset the encoder (merely useful for proper BOM handling) */
2220 if (self->encoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002221 if (_textiowrapper_encoder_setstate(self, &cookie) < 0)
Antoine Pitroue4501852009-05-14 18:55:55 +00002222 goto fail;
2223 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 return cookieObj;
2225 fail:
2226 Py_XDECREF(cookieObj);
2227 return NULL;
2228
2229}
2230
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002231/*[clinic input]
2232_io.TextIOWrapper.tell
2233[clinic start generated code]*/
2234
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002235static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002236_io_TextIOWrapper_tell_impl(textio *self)
2237/*[clinic end generated code: output=4f168c08bf34ad5f input=9a2caf88c24f9ddf]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002238{
2239 PyObject *res;
2240 PyObject *posobj = NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002241 cookie_type cookie = {0,0,0,0,0};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242 PyObject *next_input;
2243 Py_ssize_t chars_to_skip, chars_decoded;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002244 Py_ssize_t skip_bytes, skip_back;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002245 PyObject *saved_state = NULL;
2246 char *input, *input_end;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002247 Py_ssize_t dec_buffer_len;
2248 int dec_flags;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002250 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002251 CHECK_CLOSED(self);
2252
2253 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002254 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002255 goto fail;
2256 }
2257 if (!self->telling) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002258 PyErr_SetString(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002259 "telling position disabled by next() call");
2260 goto fail;
2261 }
2262
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002263 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002264 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002265 res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002266 if (res == NULL)
2267 goto fail;
2268 Py_DECREF(res);
2269
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002270 posobj = _PyObject_CallMethodId(self->buffer, &PyId_tell, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002271 if (posobj == NULL)
2272 goto fail;
2273
2274 if (self->decoder == NULL || self->snapshot == NULL) {
Victor Stinner9e30aa52011-11-21 02:49:52 +01002275 assert (self->decoded_chars == NULL || PyUnicode_GetLength(self->decoded_chars) == 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002276 return posobj;
2277 }
2278
2279#if defined(HAVE_LARGEFILE_SUPPORT)
2280 cookie.start_pos = PyLong_AsLongLong(posobj);
2281#else
2282 cookie.start_pos = PyLong_AsLong(posobj);
2283#endif
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002284 Py_DECREF(posobj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002285 if (PyErr_Occurred())
2286 goto fail;
2287
2288 /* Skip backward to the snapshot point (see _read_chunk). */
Serhiy Storchakabb72c472015-04-19 20:38:19 +03002289 if (!PyArg_ParseTuple(self->snapshot, "iO", &cookie.dec_flags, &next_input))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002290 goto fail;
2291
2292 assert (PyBytes_Check(next_input));
2293
2294 cookie.start_pos -= PyBytes_GET_SIZE(next_input);
2295
2296 /* How many decoded characters have been used up since the snapshot? */
2297 if (self->decoded_chars_used == 0) {
2298 /* We haven't moved from the snapshot point. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002299 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002300 }
2301
2302 chars_to_skip = self->decoded_chars_used;
2303
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002304 /* Decoder state will be restored at the end */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002305 saved_state = PyObject_CallMethodObjArgs(self->decoder,
2306 _PyIO_str_getstate, NULL);
2307 if (saved_state == NULL)
2308 goto fail;
2309
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002310#define DECODER_GETSTATE() do { \
Serhiy Storchaka008d88b2015-05-06 09:53:07 +03002311 PyObject *dec_buffer; \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002312 PyObject *_state = PyObject_CallMethodObjArgs(self->decoder, \
2313 _PyIO_str_getstate, NULL); \
2314 if (_state == NULL) \
2315 goto fail; \
Serhiy Storchaka008d88b2015-05-06 09:53:07 +03002316 if (!PyArg_ParseTuple(_state, "Oi", &dec_buffer, &dec_flags)) { \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002317 Py_DECREF(_state); \
2318 goto fail; \
2319 } \
Serhiy Storchaka008d88b2015-05-06 09:53:07 +03002320 if (!PyBytes_Check(dec_buffer)) { \
2321 PyErr_Format(PyExc_TypeError, \
2322 "decoder getstate() should have returned a bytes " \
2323 "object, not '%.200s'", \
2324 Py_TYPE(dec_buffer)->tp_name); \
2325 Py_DECREF(_state); \
2326 goto fail; \
2327 } \
2328 dec_buffer_len = PyBytes_GET_SIZE(dec_buffer); \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002329 Py_DECREF(_state); \
2330 } while (0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002331
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002332#define DECODER_DECODE(start, len, res) do { \
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002333 PyObject *_decoded = _PyObject_CallMethodId( \
2334 self->decoder, &PyId_decode, "y#", start, len); \
Serhiy Storchakad03ce4a2013-02-03 17:07:32 +02002335 if (check_decoded(_decoded) < 0) \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002336 goto fail; \
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002337 res = PyUnicode_GET_LENGTH(_decoded); \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002338 Py_DECREF(_decoded); \
2339 } while (0)
2340
2341 /* Fast search for an acceptable start point, close to our
2342 current pos */
2343 skip_bytes = (Py_ssize_t) (self->b2cratio * chars_to_skip);
2344 skip_back = 1;
2345 assert(skip_back <= PyBytes_GET_SIZE(next_input));
2346 input = PyBytes_AS_STRING(next_input);
2347 while (skip_bytes > 0) {
2348 /* Decode up to temptative start point */
2349 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
2350 goto fail;
2351 DECODER_DECODE(input, skip_bytes, chars_decoded);
2352 if (chars_decoded <= chars_to_skip) {
2353 DECODER_GETSTATE();
2354 if (dec_buffer_len == 0) {
2355 /* Before pos and no bytes buffered in decoder => OK */
2356 cookie.dec_flags = dec_flags;
2357 chars_to_skip -= chars_decoded;
2358 break;
2359 }
2360 /* Skip back by buffered amount and reset heuristic */
2361 skip_bytes -= dec_buffer_len;
2362 skip_back = 1;
2363 }
2364 else {
2365 /* We're too far ahead, skip back a bit */
2366 skip_bytes -= skip_back;
2367 skip_back *= 2;
2368 }
2369 }
2370 if (skip_bytes <= 0) {
2371 skip_bytes = 0;
2372 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
2373 goto fail;
2374 }
2375
2376 /* Note our initial start point. */
2377 cookie.start_pos += skip_bytes;
Victor Stinner9a282972013-06-24 23:01:33 +02002378 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002379 if (chars_to_skip == 0)
2380 goto finally;
2381
2382 /* We should be close to the desired position. Now feed the decoder one
2383 * byte at a time until we reach the `chars_to_skip` target.
2384 * As we go, note the nearest "safe start point" before the current
2385 * location (a point where the decoder has nothing buffered, so seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002386 * can safely start from there and advance to this location).
2387 */
2388 chars_decoded = 0;
2389 input = PyBytes_AS_STRING(next_input);
2390 input_end = input + PyBytes_GET_SIZE(next_input);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002391 input += skip_bytes;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002392 while (input < input_end) {
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002393 Py_ssize_t n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002394
Serhiy Storchakaec67d182013-08-20 20:04:47 +03002395 DECODER_DECODE(input, (Py_ssize_t)1, n);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002396 /* We got n chars for 1 byte */
2397 chars_decoded += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002398 cookie.bytes_to_feed += 1;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002399 DECODER_GETSTATE();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002400
2401 if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) {
2402 /* Decoder buffer is empty, so this is a safe start point. */
2403 cookie.start_pos += cookie.bytes_to_feed;
2404 chars_to_skip -= chars_decoded;
2405 cookie.dec_flags = dec_flags;
2406 cookie.bytes_to_feed = 0;
2407 chars_decoded = 0;
2408 }
2409 if (chars_decoded >= chars_to_skip)
2410 break;
2411 input++;
2412 }
2413 if (input == input_end) {
2414 /* We didn't get enough decoded data; signal EOF to get more. */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002415 PyObject *decoded = _PyObject_CallMethodId(
2416 self->decoder, &PyId_decode, "yi", "", /* final = */ 1);
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02002417 if (check_decoded(decoded) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002418 goto fail;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002419 chars_decoded += PyUnicode_GET_LENGTH(decoded);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002420 Py_DECREF(decoded);
2421 cookie.need_eof = 1;
2422
2423 if (chars_decoded < chars_to_skip) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002424 PyErr_SetString(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002425 "can't reconstruct logical file position");
2426 goto fail;
2427 }
2428 }
2429
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002430finally:
Victor Stinner7e425412016-12-09 00:36:19 +01002431 res = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002432 Py_DECREF(saved_state);
2433 if (res == NULL)
2434 return NULL;
2435 Py_DECREF(res);
2436
2437 /* The returned cookie corresponds to the last safe start point. */
2438 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002439 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002440
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002441fail:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002442 if (saved_state) {
2443 PyObject *type, *value, *traceback;
2444 PyErr_Fetch(&type, &value, &traceback);
Victor Stinner7e425412016-12-09 00:36:19 +01002445 res = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL);
Serhiy Storchaka04d09eb2015-03-30 09:58:41 +03002446 _PyErr_ChainExceptions(type, value, traceback);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002447 Py_DECREF(saved_state);
Serhiy Storchaka04d09eb2015-03-30 09:58:41 +03002448 Py_XDECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002449 }
2450 return NULL;
2451}
2452
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002453/*[clinic input]
2454_io.TextIOWrapper.truncate
2455 pos: object = None
2456 /
2457[clinic start generated code]*/
2458
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002459static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002460_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos)
2461/*[clinic end generated code: output=90ec2afb9bb7745f input=56ec8baa65aea377]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002462{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002463 PyObject *res;
2464
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002465 CHECK_ATTACHED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002466
2467 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL);
2468 if (res == NULL)
2469 return NULL;
2470 Py_DECREF(res);
2471
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00002472 return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, pos, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002473}
2474
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002475static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002476textiowrapper_repr(textio *self)
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002477{
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002478 PyObject *nameobj, *modeobj, *res, *s;
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002479 int status;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002480
2481 CHECK_INITIALIZED(self);
2482
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002483 res = PyUnicode_FromString("<_io.TextIOWrapper");
2484 if (res == NULL)
2485 return NULL;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002486
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002487 status = Py_ReprEnter((PyObject *)self);
2488 if (status != 0) {
2489 if (status > 0) {
2490 PyErr_Format(PyExc_RuntimeError,
2491 "reentrant call inside %s.__repr__",
2492 Py_TYPE(self)->tp_name);
2493 }
2494 goto error;
2495 }
Martin v. Löwis767046a2011-10-14 15:35:36 +02002496 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00002497 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002498 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00002499 PyErr_Clear();
2500 else
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002501 goto error;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002502 }
2503 else {
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002504 s = PyUnicode_FromFormat(" name=%R", nameobj);
Antoine Pitrou716c4442009-05-23 19:04:03 +00002505 Py_DECREF(nameobj);
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002506 if (s == NULL)
2507 goto error;
2508 PyUnicode_AppendAndDel(&res, s);
2509 if (res == NULL)
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002510 goto error;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002511 }
Martin v. Löwis767046a2011-10-14 15:35:36 +02002512 modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode);
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002513 if (modeobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002514 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002515 PyErr_Clear();
2516 else
2517 goto error;
2518 }
2519 else {
2520 s = PyUnicode_FromFormat(" mode=%R", modeobj);
2521 Py_DECREF(modeobj);
2522 if (s == NULL)
2523 goto error;
2524 PyUnicode_AppendAndDel(&res, s);
2525 if (res == NULL)
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002526 goto error;
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002527 }
2528 s = PyUnicode_FromFormat("%U encoding=%R>",
2529 res, self->encoding);
2530 Py_DECREF(res);
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002531 if (status == 0) {
2532 Py_ReprLeave((PyObject *)self);
2533 }
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002534 return s;
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002535
2536 error:
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002537 Py_XDECREF(res);
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002538 if (status == 0) {
2539 Py_ReprLeave((PyObject *)self);
2540 }
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002541 return NULL;
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002542}
2543
2544
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002545/* Inquiries */
2546
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002547/*[clinic input]
2548_io.TextIOWrapper.fileno
2549[clinic start generated code]*/
2550
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002551static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002552_io_TextIOWrapper_fileno_impl(textio *self)
2553/*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002554{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002555 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002556 return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002557}
2558
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002559/*[clinic input]
2560_io.TextIOWrapper.seekable
2561[clinic start generated code]*/
2562
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002563static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002564_io_TextIOWrapper_seekable_impl(textio *self)
2565/*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002566{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002567 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002568 return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002569}
2570
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002571/*[clinic input]
2572_io.TextIOWrapper.readable
2573[clinic start generated code]*/
2574
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002575static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002576_io_TextIOWrapper_readable_impl(textio *self)
2577/*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002578{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002579 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002580 return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002581}
2582
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002583/*[clinic input]
2584_io.TextIOWrapper.writable
2585[clinic start generated code]*/
2586
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002587static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002588_io_TextIOWrapper_writable_impl(textio *self)
2589/*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002590{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002591 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002592 return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002593}
2594
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002595/*[clinic input]
2596_io.TextIOWrapper.isatty
2597[clinic start generated code]*/
2598
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002599static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002600_io_TextIOWrapper_isatty_impl(textio *self)
2601/*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002602{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002603 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002604 return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002605}
2606
2607static PyObject *
Antoine Pitrou243757e2010-11-05 21:15:39 +00002608textiowrapper_getstate(textio *self, PyObject *args)
2609{
2610 PyErr_Format(PyExc_TypeError,
2611 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
2612 return NULL;
2613}
2614
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002615/*[clinic input]
2616_io.TextIOWrapper.flush
2617[clinic start generated code]*/
2618
Antoine Pitrou243757e2010-11-05 21:15:39 +00002619static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002620_io_TextIOWrapper_flush_impl(textio *self)
2621/*[clinic end generated code: output=59de9165f9c2e4d2 input=928c60590694ab85]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002622{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002623 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002624 CHECK_CLOSED(self);
2625 self->telling = self->seekable;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002626 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002627 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002628 return _PyObject_CallMethodId(self->buffer, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629}
2630
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002631/*[clinic input]
2632_io.TextIOWrapper.close
2633[clinic start generated code]*/
2634
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002635static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002636_io_TextIOWrapper_close_impl(textio *self)
2637/*[clinic end generated code: output=056ccf8b4876e4f4 input=9c2114315eae1948]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002638{
2639 PyObject *res;
Antoine Pitrou6be88762010-05-03 16:48:20 +00002640 int r;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002641 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002642
Antoine Pitrou6be88762010-05-03 16:48:20 +00002643 res = textiowrapper_closed_get(self, NULL);
2644 if (res == NULL)
2645 return NULL;
2646 r = PyObject_IsTrue(res);
2647 Py_DECREF(res);
2648 if (r < 0)
2649 return NULL;
Victor Stinnerf6c57832010-05-19 01:17:01 +00002650
Antoine Pitrou6be88762010-05-03 16:48:20 +00002651 if (r > 0) {
2652 Py_RETURN_NONE; /* stream already closed */
2653 }
2654 else {
Benjamin Peterson68623612012-12-20 11:53:11 -06002655 PyObject *exc = NULL, *val, *tb;
Antoine Pitrou796564c2013-07-30 19:59:21 +02002656 if (self->finalizing) {
Victor Stinner61bdb0d2016-12-09 15:39:28 +01002657 res = _PyObject_CallMethodIdObjArgs(self->buffer,
2658 &PyId__dealloc_warn,
2659 self, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +00002660 if (res)
2661 Py_DECREF(res);
2662 else
2663 PyErr_Clear();
2664 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002665 res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
Benjamin Peterson68623612012-12-20 11:53:11 -06002666 if (res == NULL)
2667 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou6be88762010-05-03 16:48:20 +00002668 else
2669 Py_DECREF(res);
2670
Benjamin Peterson68623612012-12-20 11:53:11 -06002671 res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);
2672 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +03002673 _PyErr_ChainExceptions(exc, val, tb);
2674 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -06002675 }
2676 return res;
Antoine Pitrou6be88762010-05-03 16:48:20 +00002677 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002678}
2679
2680static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002681textiowrapper_iternext(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002682{
2683 PyObject *line;
2684
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002685 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002686
2687 self->telling = 0;
2688 if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
2689 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002690 line = _textiowrapper_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002691 }
2692 else {
2693 line = PyObject_CallMethodObjArgs((PyObject *)self,
2694 _PyIO_str_readline, NULL);
2695 if (line && !PyUnicode_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002696 PyErr_Format(PyExc_OSError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002697 "readline() should have returned a str object, "
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002698 "not '%.200s'", Py_TYPE(line)->tp_name);
2699 Py_DECREF(line);
2700 return NULL;
2701 }
2702 }
2703
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002704 if (line == NULL || PyUnicode_READY(line) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002705 return NULL;
2706
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002707 if (PyUnicode_GET_LENGTH(line) == 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002708 /* Reached EOF or would have blocked */
2709 Py_DECREF(line);
2710 Py_CLEAR(self->snapshot);
2711 self->telling = self->seekable;
2712 return NULL;
2713 }
2714
2715 return line;
2716}
2717
2718static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002719textiowrapper_name_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002720{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002721 CHECK_ATTACHED(self);
Martin v. Löwis767046a2011-10-14 15:35:36 +02002722 return _PyObject_GetAttrId(self->buffer, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002723}
2724
2725static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002726textiowrapper_closed_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002727{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002728 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002729 return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
2730}
2731
2732static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002733textiowrapper_newlines_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002734{
2735 PyObject *res;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002736 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002737 if (self->decoder == NULL)
2738 Py_RETURN_NONE;
2739 res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
2740 if (res == NULL) {
Benjamin Peterson2cfca792009-06-06 20:46:48 +00002741 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
2742 PyErr_Clear();
2743 Py_RETURN_NONE;
2744 }
2745 else {
2746 return NULL;
2747 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002748 }
2749 return res;
2750}
2751
2752static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002753textiowrapper_errors_get(textio *self, void *context)
Benjamin Peterson0926ad12009-06-06 18:02:12 +00002754{
2755 CHECK_INITIALIZED(self);
2756 return PyUnicode_FromString(PyBytes_AS_STRING(self->errors));
2757}
2758
2759static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002760textiowrapper_chunk_size_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002761{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002762 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002763 return PyLong_FromSsize_t(self->chunk_size);
2764}
2765
2766static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002767textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002768{
2769 Py_ssize_t n;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002770 CHECK_ATTACHED_INT(self);
Antoine Pitroucb4ae812011-07-13 21:07:49 +02002771 n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002772 if (n == -1 && PyErr_Occurred())
2773 return -1;
2774 if (n <= 0) {
2775 PyErr_SetString(PyExc_ValueError,
2776 "a strictly positive integer is required");
2777 return -1;
2778 }
2779 self->chunk_size = n;
2780 return 0;
2781}
2782
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002783#include "clinic/textio.c.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002784
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002785static PyMethodDef incrementalnewlinedecoder_methods[] = {
2786 _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF
2787 _IO_INCREMENTALNEWLINEDECODER_GETSTATE_METHODDEF
2788 _IO_INCREMENTALNEWLINEDECODER_SETSTATE_METHODDEF
2789 _IO_INCREMENTALNEWLINEDECODER_RESET_METHODDEF
2790 {NULL}
2791};
2792
2793static PyGetSetDef incrementalnewlinedecoder_getset[] = {
2794 {"newlines", (getter)incrementalnewlinedecoder_newlines_get, NULL, NULL},
2795 {NULL}
2796};
2797
2798PyTypeObject PyIncrementalNewlineDecoder_Type = {
2799 PyVarObject_HEAD_INIT(NULL, 0)
2800 "_io.IncrementalNewlineDecoder", /*tp_name*/
2801 sizeof(nldecoder_object), /*tp_basicsize*/
2802 0, /*tp_itemsize*/
2803 (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/
2804 0, /*tp_print*/
2805 0, /*tp_getattr*/
2806 0, /*tp_setattr*/
2807 0, /*tp_compare */
2808 0, /*tp_repr*/
2809 0, /*tp_as_number*/
2810 0, /*tp_as_sequence*/
2811 0, /*tp_as_mapping*/
2812 0, /*tp_hash */
2813 0, /*tp_call*/
2814 0, /*tp_str*/
2815 0, /*tp_getattro*/
2816 0, /*tp_setattro*/
2817 0, /*tp_as_buffer*/
2818 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
2819 _io_IncrementalNewlineDecoder___init____doc__, /* tp_doc */
2820 0, /* tp_traverse */
2821 0, /* tp_clear */
2822 0, /* tp_richcompare */
2823 0, /*tp_weaklistoffset*/
2824 0, /* tp_iter */
2825 0, /* tp_iternext */
2826 incrementalnewlinedecoder_methods, /* tp_methods */
2827 0, /* tp_members */
2828 incrementalnewlinedecoder_getset, /* tp_getset */
2829 0, /* tp_base */
2830 0, /* tp_dict */
2831 0, /* tp_descr_get */
2832 0, /* tp_descr_set */
2833 0, /* tp_dictoffset */
2834 _io_IncrementalNewlineDecoder___init__, /* tp_init */
2835 0, /* tp_alloc */
2836 PyType_GenericNew, /* tp_new */
2837};
2838
2839
2840static PyMethodDef textiowrapper_methods[] = {
2841 _IO_TEXTIOWRAPPER_DETACH_METHODDEF
2842 _IO_TEXTIOWRAPPER_WRITE_METHODDEF
2843 _IO_TEXTIOWRAPPER_READ_METHODDEF
2844 _IO_TEXTIOWRAPPER_READLINE_METHODDEF
2845 _IO_TEXTIOWRAPPER_FLUSH_METHODDEF
2846 _IO_TEXTIOWRAPPER_CLOSE_METHODDEF
2847
2848 _IO_TEXTIOWRAPPER_FILENO_METHODDEF
2849 _IO_TEXTIOWRAPPER_SEEKABLE_METHODDEF
2850 _IO_TEXTIOWRAPPER_READABLE_METHODDEF
2851 _IO_TEXTIOWRAPPER_WRITABLE_METHODDEF
2852 _IO_TEXTIOWRAPPER_ISATTY_METHODDEF
Antoine Pitrou243757e2010-11-05 21:15:39 +00002853 {"__getstate__", (PyCFunction)textiowrapper_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002854
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002855 _IO_TEXTIOWRAPPER_SEEK_METHODDEF
2856 _IO_TEXTIOWRAPPER_TELL_METHODDEF
2857 _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002858 {NULL, NULL}
2859};
2860
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002861static PyMemberDef textiowrapper_members[] = {
2862 {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY},
2863 {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY},
2864 {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002865 {"_finalizing", T_BOOL, offsetof(textio, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002866 {NULL}
2867};
2868
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002869static PyGetSetDef textiowrapper_getset[] = {
2870 {"name", (getter)textiowrapper_name_get, NULL, NULL},
2871 {"closed", (getter)textiowrapper_closed_get, NULL, NULL},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002872/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL},
2873*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002874 {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL},
2875 {"errors", (getter)textiowrapper_errors_get, NULL, NULL},
2876 {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get,
2877 (setter)textiowrapper_chunk_size_set, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002878 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002879};
2880
2881PyTypeObject PyTextIOWrapper_Type = {
2882 PyVarObject_HEAD_INIT(NULL, 0)
2883 "_io.TextIOWrapper", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002884 sizeof(textio), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002885 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002886 (destructor)textiowrapper_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002887 0, /*tp_print*/
2888 0, /*tp_getattr*/
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002889 0, /*tps_etattr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002890 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002891 (reprfunc)textiowrapper_repr,/*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002892 0, /*tp_as_number*/
2893 0, /*tp_as_sequence*/
2894 0, /*tp_as_mapping*/
2895 0, /*tp_hash */
2896 0, /*tp_call*/
2897 0, /*tp_str*/
2898 0, /*tp_getattro*/
2899 0, /*tp_setattro*/
2900 0, /*tp_as_buffer*/
2901 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002902 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002903 _io_TextIOWrapper___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002904 (traverseproc)textiowrapper_traverse, /* tp_traverse */
2905 (inquiry)textiowrapper_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002906 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002907 offsetof(textio, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002908 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002909 (iternextfunc)textiowrapper_iternext, /* tp_iternext */
2910 textiowrapper_methods, /* tp_methods */
2911 textiowrapper_members, /* tp_members */
2912 textiowrapper_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002913 0, /* tp_base */
2914 0, /* tp_dict */
2915 0, /* tp_descr_get */
2916 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002917 offsetof(textio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002918 _io_TextIOWrapper___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002919 0, /* tp_alloc */
2920 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002921 0, /* tp_free */
2922 0, /* tp_is_gc */
2923 0, /* tp_bases */
2924 0, /* tp_mro */
2925 0, /* tp_cache */
2926 0, /* tp_subclasses */
2927 0, /* tp_weaklist */
2928 0, /* tp_del */
2929 0, /* tp_version_tag */
2930 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002931};