blob: b5d368a175c94cc0a4bd5dcabbc696e3dfec52d3 [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
Antoine Pitrou3c2817b2017-06-03 12:32:28 +02001098/* Return *default_value* if ob is None, 0 if ob is false, 1 if ob is true,
1099 * -1 on error.
1100 */
1101static int
1102convert_optional_bool(PyObject *obj, int default_value)
1103{
1104 long v;
1105 if (obj == Py_None) {
1106 v = default_value;
1107 }
1108 else {
1109 v = PyLong_AsLong(obj);
1110 if (v == -1 && PyErr_Occurred())
1111 return -1;
1112 }
1113 return v != 0;
1114}
1115
1116
1117/*[clinic input]
1118_io.TextIOWrapper.reconfigure
1119 *
1120 line_buffering as line_buffering_obj: object = None
1121 write_through as write_through_obj: object = None
1122
1123Reconfigure the text stream with new parameters.
1124
1125This also does an implicit stream flush.
1126
1127[clinic start generated code]*/
1128
1129static PyObject *
1130_io_TextIOWrapper_reconfigure_impl(textio *self,
1131 PyObject *line_buffering_obj,
1132 PyObject *write_through_obj)
1133/*[clinic end generated code: output=7cdf79e7001e2856 input=baade27ecb9db7bc]*/
1134{
1135 int line_buffering;
1136 int write_through;
1137 PyObject *res;
1138
1139 line_buffering = convert_optional_bool(line_buffering_obj,
1140 self->line_buffering);
1141 write_through = convert_optional_bool(write_through_obj,
1142 self->write_through);
1143 if (line_buffering < 0 || write_through < 0) {
1144 return NULL;
1145 }
1146 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL);
1147 Py_XDECREF(res);
1148 if (res == NULL) {
1149 return NULL;
1150 }
1151 self->line_buffering = line_buffering;
1152 self->write_through = write_through;
1153 Py_RETURN_NONE;
1154}
1155
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001156static int
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001157textiowrapper_clear(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001158{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001159 self->ok = 0;
1160 Py_CLEAR(self->buffer);
1161 Py_CLEAR(self->encoding);
1162 Py_CLEAR(self->encoder);
1163 Py_CLEAR(self->decoder);
1164 Py_CLEAR(self->readnl);
1165 Py_CLEAR(self->decoded_chars);
1166 Py_CLEAR(self->pending_bytes);
1167 Py_CLEAR(self->snapshot);
1168 Py_CLEAR(self->errors);
1169 Py_CLEAR(self->raw);
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001170
1171 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001172 return 0;
1173}
1174
1175static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001176textiowrapper_dealloc(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001177{
Antoine Pitrou796564c2013-07-30 19:59:21 +02001178 self->finalizing = 1;
1179 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001180 return;
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001181 self->ok = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001182 _PyObject_GC_UNTRACK(self);
1183 if (self->weakreflist != NULL)
1184 PyObject_ClearWeakRefs((PyObject *)self);
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001185 textiowrapper_clear(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001186 Py_TYPE(self)->tp_free((PyObject *)self);
1187}
1188
1189static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001190textiowrapper_traverse(textio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001191{
1192 Py_VISIT(self->buffer);
1193 Py_VISIT(self->encoding);
1194 Py_VISIT(self->encoder);
1195 Py_VISIT(self->decoder);
1196 Py_VISIT(self->readnl);
1197 Py_VISIT(self->decoded_chars);
1198 Py_VISIT(self->pending_bytes);
1199 Py_VISIT(self->snapshot);
1200 Py_VISIT(self->errors);
1201 Py_VISIT(self->raw);
1202
1203 Py_VISIT(self->dict);
1204 return 0;
1205}
1206
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001207static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001208textiowrapper_closed_get(textio *self, void *context);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001209
1210/* This macro takes some shortcuts to make the common case faster. */
1211#define CHECK_CLOSED(self) \
1212 do { \
1213 int r; \
1214 PyObject *_res; \
1215 if (Py_TYPE(self) == &PyTextIOWrapper_Type) { \
1216 if (self->raw != NULL) \
1217 r = _PyFileIO_closed(self->raw); \
1218 else { \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001219 _res = textiowrapper_closed_get(self, NULL); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001220 if (_res == NULL) \
1221 return NULL; \
1222 r = PyObject_IsTrue(_res); \
1223 Py_DECREF(_res); \
1224 if (r < 0) \
1225 return NULL; \
1226 } \
1227 if (r > 0) { \
1228 PyErr_SetString(PyExc_ValueError, \
1229 "I/O operation on closed file."); \
1230 return NULL; \
1231 } \
1232 } \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001233 else if (_PyIOBase_check_closed((PyObject *)self, Py_True) == NULL) \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001234 return NULL; \
1235 } while (0)
1236
1237#define CHECK_INITIALIZED(self) \
1238 if (self->ok <= 0) { \
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001239 PyErr_SetString(PyExc_ValueError, \
1240 "I/O operation on uninitialized object"); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001241 return NULL; \
1242 }
1243
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001244#define CHECK_ATTACHED(self) \
1245 CHECK_INITIALIZED(self); \
1246 if (self->detached) { \
1247 PyErr_SetString(PyExc_ValueError, \
1248 "underlying buffer has been detached"); \
1249 return NULL; \
1250 }
1251
1252#define CHECK_ATTACHED_INT(self) \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001253 if (self->ok <= 0) { \
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001254 PyErr_SetString(PyExc_ValueError, \
1255 "I/O operation on uninitialized object"); \
1256 return -1; \
1257 } else if (self->detached) { \
1258 PyErr_SetString(PyExc_ValueError, \
1259 "underlying buffer has been detached"); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001260 return -1; \
1261 }
1262
1263
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001264/*[clinic input]
1265_io.TextIOWrapper.detach
1266[clinic start generated code]*/
1267
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001268static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001269_io_TextIOWrapper_detach_impl(textio *self)
1270/*[clinic end generated code: output=7ba3715cd032d5f2 input=e5a71fbda9e1d9f9]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001271{
1272 PyObject *buffer, *res;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001273 CHECK_ATTACHED(self);
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001274 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
1275 if (res == NULL)
1276 return NULL;
1277 Py_DECREF(res);
1278 buffer = self->buffer;
1279 self->buffer = NULL;
1280 self->detached = 1;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001281 return buffer;
1282}
1283
Antoine Pitrou24f36292009-03-28 22:16:42 +00001284/* Flush the internal write buffer. This doesn't explicitly flush the
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001285 underlying buffered object, though. */
1286static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001287_textiowrapper_writeflush(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001288{
Amaury Forgeot d'Arcccd686a2009-08-29 23:00:38 +00001289 PyObject *pending, *b, *ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001290
1291 if (self->pending_bytes == NULL)
1292 return 0;
Amaury Forgeot d'Arcccd686a2009-08-29 23:00:38 +00001293
1294 pending = self->pending_bytes;
1295 Py_INCREF(pending);
1296 self->pending_bytes_count = 0;
1297 Py_CLEAR(self->pending_bytes);
1298
1299 b = _PyBytes_Join(_PyIO_empty_bytes, pending);
1300 Py_DECREF(pending);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001301 if (b == NULL)
1302 return -1;
Gregory P. Smithb9817b02013-02-01 13:03:39 -08001303 ret = NULL;
1304 do {
1305 ret = PyObject_CallMethodObjArgs(self->buffer,
1306 _PyIO_str_write, b, NULL);
1307 } while (ret == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001308 Py_DECREF(b);
1309 if (ret == NULL)
1310 return -1;
1311 Py_DECREF(ret);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001312 return 0;
1313}
1314
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001315/*[clinic input]
1316_io.TextIOWrapper.write
1317 text: unicode
1318 /
1319[clinic start generated code]*/
1320
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001321static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001322_io_TextIOWrapper_write_impl(textio *self, PyObject *text)
1323/*[clinic end generated code: output=d2deb0d50771fcec input=fdf19153584a0e44]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001324{
1325 PyObject *ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001326 PyObject *b;
1327 Py_ssize_t textlen;
1328 int haslf = 0;
Antoine Pitrouc644e7c2014-05-09 00:24:50 +02001329 int needflush = 0, text_needflush = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001330
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001331 if (PyUnicode_READY(text) == -1)
1332 return NULL;
1333
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001334 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001335 CHECK_CLOSED(self);
1336
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001337 if (self->encoder == NULL)
1338 return _unsupported("not writable");
Benjamin Peterson81971ea2009-05-14 22:01:31 +00001339
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001340 Py_INCREF(text);
1341
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001342 textlen = PyUnicode_GET_LENGTH(text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001343
1344 if ((self->writetranslate && self->writenl != NULL) || self->line_buffering)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001345 if (PyUnicode_FindChar(text, '\n', 0, PyUnicode_GET_LENGTH(text), 1) != -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001346 haslf = 1;
1347
1348 if (haslf && self->writetranslate && self->writenl != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001349 PyObject *newtext = _PyObject_CallMethodId(
1350 text, &PyId_replace, "ss", "\n", self->writenl);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001351 Py_DECREF(text);
1352 if (newtext == NULL)
1353 return NULL;
1354 text = newtext;
1355 }
1356
Antoine Pitroue96ec682011-07-23 21:46:35 +02001357 if (self->write_through)
Antoine Pitrouc644e7c2014-05-09 00:24:50 +02001358 text_needflush = 1;
1359 if (self->line_buffering &&
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001360 (haslf ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001361 PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001362 needflush = 1;
1363
1364 /* XXX What if we were just reading? */
Antoine Pitroue4501852009-05-14 18:55:55 +00001365 if (self->encodefunc != NULL) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001366 b = (*self->encodefunc)((PyObject *) self, text);
Antoine Pitroue4501852009-05-14 18:55:55 +00001367 self->encoding_start_of_stream = 0;
1368 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001369 else
1370 b = PyObject_CallMethodObjArgs(self->encoder,
1371 _PyIO_str_encode, text, NULL);
1372 Py_DECREF(text);
1373 if (b == NULL)
1374 return NULL;
1375
1376 if (self->pending_bytes == NULL) {
1377 self->pending_bytes = PyList_New(0);
1378 if (self->pending_bytes == NULL) {
1379 Py_DECREF(b);
1380 return NULL;
1381 }
1382 self->pending_bytes_count = 0;
1383 }
1384 if (PyList_Append(self->pending_bytes, b) < 0) {
1385 Py_DECREF(b);
1386 return NULL;
1387 }
1388 self->pending_bytes_count += PyBytes_GET_SIZE(b);
1389 Py_DECREF(b);
Antoine Pitrouc644e7c2014-05-09 00:24:50 +02001390 if (self->pending_bytes_count > self->chunk_size || needflush ||
1391 text_needflush) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001392 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001393 return NULL;
1394 }
Antoine Pitrou24f36292009-03-28 22:16:42 +00001395
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001396 if (needflush) {
1397 ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL);
1398 if (ret == NULL)
1399 return NULL;
1400 Py_DECREF(ret);
1401 }
1402
1403 Py_CLEAR(self->snapshot);
1404
1405 if (self->decoder) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001406 ret = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001407 if (ret == NULL)
1408 return NULL;
1409 Py_DECREF(ret);
1410 }
1411
1412 return PyLong_FromSsize_t(textlen);
1413}
1414
1415/* Steal a reference to chars and store it in the decoded_char buffer;
1416 */
1417static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001418textiowrapper_set_decoded_chars(textio *self, PyObject *chars)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001419{
Serhiy Storchaka48842712016-04-06 09:45:48 +03001420 Py_XSETREF(self->decoded_chars, chars);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001421 self->decoded_chars_used = 0;
1422}
1423
1424static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001425textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001426{
1427 PyObject *chars;
1428 Py_ssize_t avail;
1429
1430 if (self->decoded_chars == NULL)
1431 return PyUnicode_FromStringAndSize(NULL, 0);
1432
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001433 /* decoded_chars is guaranteed to be "ready". */
1434 avail = (PyUnicode_GET_LENGTH(self->decoded_chars)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001435 - self->decoded_chars_used);
1436
1437 assert(avail >= 0);
1438
1439 if (n < 0 || n > avail)
1440 n = avail;
1441
1442 if (self->decoded_chars_used > 0 || n < avail) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001443 chars = PyUnicode_Substring(self->decoded_chars,
1444 self->decoded_chars_used,
1445 self->decoded_chars_used + n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001446 if (chars == NULL)
1447 return NULL;
1448 }
1449 else {
1450 chars = self->decoded_chars;
1451 Py_INCREF(chars);
1452 }
1453
1454 self->decoded_chars_used += n;
1455 return chars;
1456}
1457
1458/* Read and decode the next chunk of data from the BufferedReader.
1459 */
1460static int
Antoine Pitroue5324562011-11-19 00:39:01 +01001461textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001462{
1463 PyObject *dec_buffer = NULL;
1464 PyObject *dec_flags = NULL;
1465 PyObject *input_chunk = NULL;
Antoine Pitroub8503892014-04-29 10:14:02 +02001466 Py_buffer input_chunk_buf;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001467 PyObject *decoded_chars, *chunk_size;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00001468 Py_ssize_t nbytes, nchars;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001469 int eof;
1470
1471 /* The return value is True unless EOF was reached. The decoded string is
1472 * placed in self._decoded_chars (replacing its previous value). The
1473 * entire input chunk is sent to the decoder, though some of it may remain
1474 * buffered in the decoder, yet to be converted.
1475 */
1476
1477 if (self->decoder == NULL) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001478 _unsupported("not readable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001479 return -1;
1480 }
1481
1482 if (self->telling) {
1483 /* To prepare for tell(), we need to snapshot a point in the file
1484 * where the decoder's input buffer is empty.
1485 */
1486
1487 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
1488 _PyIO_str_getstate, NULL);
1489 if (state == NULL)
1490 return -1;
1491 /* Given this, we know there was a valid snapshot point
1492 * len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
1493 */
Serhiy Storchakabb72c472015-04-19 20:38:19 +03001494 if (PyArg_ParseTuple(state, "OO", &dec_buffer, &dec_flags) < 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001495 Py_DECREF(state);
1496 return -1;
1497 }
Antoine Pitroub8503892014-04-29 10:14:02 +02001498
1499 if (!PyBytes_Check(dec_buffer)) {
1500 PyErr_Format(PyExc_TypeError,
1501 "decoder getstate() should have returned a bytes "
1502 "object, not '%.200s'",
1503 Py_TYPE(dec_buffer)->tp_name);
1504 Py_DECREF(state);
1505 return -1;
1506 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001507 Py_INCREF(dec_buffer);
1508 Py_INCREF(dec_flags);
1509 Py_DECREF(state);
1510 }
1511
1512 /* Read a chunk, decode it, and put the result in self._decoded_chars. */
Antoine Pitroue5324562011-11-19 00:39:01 +01001513 if (size_hint > 0) {
Victor Stinnerf8facac2011-11-22 02:30:47 +01001514 size_hint = (Py_ssize_t)(Py_MAX(self->b2cratio, 1.0) * size_hint);
Antoine Pitroue5324562011-11-19 00:39:01 +01001515 }
1516 chunk_size = PyLong_FromSsize_t(Py_MAX(self->chunk_size, size_hint));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001517 if (chunk_size == NULL)
1518 goto fail;
Antoine Pitroub8503892014-04-29 10:14:02 +02001519
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001520 input_chunk = PyObject_CallMethodObjArgs(self->buffer,
Antoine Pitroue96ec682011-07-23 21:46:35 +02001521 (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read),
1522 chunk_size, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001523 Py_DECREF(chunk_size);
1524 if (input_chunk == NULL)
1525 goto fail;
Antoine Pitroub8503892014-04-29 10:14:02 +02001526
1527 if (PyObject_GetBuffer(input_chunk, &input_chunk_buf, 0) != 0) {
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001528 PyErr_Format(PyExc_TypeError,
Antoine Pitroub8503892014-04-29 10:14:02 +02001529 "underlying %s() should have returned a bytes-like object, "
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001530 "not '%.200s'", (self->has_read1 ? "read1": "read"),
1531 Py_TYPE(input_chunk)->tp_name);
1532 goto fail;
1533 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001534
Antoine Pitroub8503892014-04-29 10:14:02 +02001535 nbytes = input_chunk_buf.len;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00001536 eof = (nbytes == 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001537 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) {
1538 decoded_chars = _PyIncrementalNewlineDecoder_decode(
1539 self->decoder, input_chunk, eof);
1540 }
1541 else {
1542 decoded_chars = PyObject_CallMethodObjArgs(self->decoder,
1543 _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL);
1544 }
Antoine Pitroub8503892014-04-29 10:14:02 +02001545 PyBuffer_Release(&input_chunk_buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001546
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001547 if (check_decoded(decoded_chars) < 0)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001548 goto fail;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001549 textiowrapper_set_decoded_chars(self, decoded_chars);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001550 nchars = PyUnicode_GET_LENGTH(decoded_chars);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00001551 if (nchars > 0)
1552 self->b2cratio = (double) nbytes / nchars;
1553 else
1554 self->b2cratio = 0.0;
1555 if (nchars > 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001556 eof = 0;
1557
1558 if (self->telling) {
1559 /* At the snapshot point, len(dec_buffer) bytes before the read, the
1560 * next input to be decoded is dec_buffer + input_chunk.
1561 */
Antoine Pitroub8503892014-04-29 10:14:02 +02001562 PyObject *next_input = dec_buffer;
1563 PyBytes_Concat(&next_input, input_chunk);
1564 if (next_input == NULL) {
1565 dec_buffer = NULL; /* Reference lost to PyBytes_Concat */
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001566 goto fail;
1567 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001568 Py_XSETREF(self->snapshot, Py_BuildValue("NN", dec_flags, next_input));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001569 }
1570 Py_DECREF(input_chunk);
1571
1572 return (eof == 0);
1573
1574 fail:
1575 Py_XDECREF(dec_buffer);
1576 Py_XDECREF(dec_flags);
1577 Py_XDECREF(input_chunk);
1578 return -1;
1579}
1580
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001581/*[clinic input]
1582_io.TextIOWrapper.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001583 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001584 /
1585[clinic start generated code]*/
1586
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001587static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001588_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001589/*[clinic end generated code: output=7e651ce6cc6a25a6 input=123eecbfe214aeb8]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001590{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001591 PyObject *result = NULL, *chunks = NULL;
1592
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001593 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001594 CHECK_CLOSED(self);
1595
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001596 if (self->decoder == NULL)
1597 return _unsupported("not readable");
Benjamin Petersona1b49012009-03-31 23:11:32 +00001598
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001599 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001600 return NULL;
1601
1602 if (n < 0) {
1603 /* Read everything */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001604 PyObject *bytes = _PyObject_CallMethodId(self->buffer, &PyId_read, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001605 PyObject *decoded;
1606 if (bytes == NULL)
1607 goto fail;
Victor Stinnerfd821132011-05-25 22:01:33 +02001608
1609 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type)
1610 decoded = _PyIncrementalNewlineDecoder_decode(self->decoder,
1611 bytes, 1);
1612 else
1613 decoded = PyObject_CallMethodObjArgs(
1614 self->decoder, _PyIO_str_decode, bytes, Py_True, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001615 Py_DECREF(bytes);
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001616 if (check_decoded(decoded) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001617 goto fail;
1618
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001619 result = textiowrapper_get_decoded_chars(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001620
1621 if (result == NULL) {
1622 Py_DECREF(decoded);
1623 return NULL;
1624 }
1625
1626 PyUnicode_AppendAndDel(&result, decoded);
1627 if (result == NULL)
1628 goto fail;
1629
1630 Py_CLEAR(self->snapshot);
1631 return result;
1632 }
1633 else {
1634 int res = 1;
1635 Py_ssize_t remaining = n;
1636
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001637 result = textiowrapper_get_decoded_chars(self, n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001638 if (result == NULL)
1639 goto fail;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001640 if (PyUnicode_READY(result) == -1)
1641 goto fail;
1642 remaining -= PyUnicode_GET_LENGTH(result);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001643
1644 /* Keep reading chunks until we have n characters to return */
1645 while (remaining > 0) {
Antoine Pitroue5324562011-11-19 00:39:01 +01001646 res = textiowrapper_read_chunk(self, remaining);
Gregory P. Smith51359922012-06-23 23:55:39 -07001647 if (res < 0) {
1648 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1649 when EINTR occurs so we needn't do it ourselves. */
1650 if (_PyIO_trap_eintr()) {
1651 continue;
1652 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001653 goto fail;
Gregory P. Smith51359922012-06-23 23:55:39 -07001654 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001655 if (res == 0) /* EOF */
1656 break;
1657 if (chunks == NULL) {
1658 chunks = PyList_New(0);
1659 if (chunks == NULL)
1660 goto fail;
1661 }
Antoine Pitroue5324562011-11-19 00:39:01 +01001662 if (PyUnicode_GET_LENGTH(result) > 0 &&
1663 PyList_Append(chunks, result) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001664 goto fail;
1665 Py_DECREF(result);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001666 result = textiowrapper_get_decoded_chars(self, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001667 if (result == NULL)
1668 goto fail;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001669 remaining -= PyUnicode_GET_LENGTH(result);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001670 }
1671 if (chunks != NULL) {
1672 if (result != NULL && PyList_Append(chunks, result) < 0)
1673 goto fail;
Serhiy Storchaka48842712016-04-06 09:45:48 +03001674 Py_XSETREF(result, PyUnicode_Join(_PyIO_empty_str, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001675 if (result == NULL)
1676 goto fail;
1677 Py_CLEAR(chunks);
1678 }
1679 return result;
1680 }
1681 fail:
1682 Py_XDECREF(result);
1683 Py_XDECREF(chunks);
1684 return NULL;
1685}
1686
1687
Victor Stinnerf7b8cb62011-09-29 03:28:17 +02001688/* NOTE: `end` must point to the real end of the Py_UCS4 storage,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001689 that is to the NUL character. Otherwise the function will produce
1690 incorrect results. */
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001691static const char *
1692find_control_char(int kind, const char *s, const char *end, Py_UCS4 ch)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001693{
Antoine Pitrouc28e2e52011-11-13 03:53:42 +01001694 if (kind == PyUnicode_1BYTE_KIND) {
1695 assert(ch < 256);
1696 return (char *) memchr((void *) s, (char) ch, end - s);
1697 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001698 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001699 while (PyUnicode_READ(kind, s, 0) > ch)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001700 s += kind;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001701 if (PyUnicode_READ(kind, s, 0) == ch)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001702 return s;
1703 if (s == end)
1704 return NULL;
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001705 s += kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001706 }
1707}
1708
1709Py_ssize_t
1710_PyIO_find_line_ending(
1711 int translated, int universal, PyObject *readnl,
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001712 int kind, const char *start, const char *end, Py_ssize_t *consumed)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001713{
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001714 Py_ssize_t len = ((char*)end - (char*)start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001715
1716 if (translated) {
1717 /* Newlines are already translated, only search for \n */
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001718 const char *pos = find_control_char(kind, start, end, '\n');
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001719 if (pos != NULL)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001720 return (pos - start)/kind + 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001721 else {
1722 *consumed = len;
1723 return -1;
1724 }
1725 }
1726 else if (universal) {
1727 /* Universal newline search. Find any of \r, \r\n, \n
1728 * The decoder ensures that \r\n are not split in two pieces
1729 */
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001730 const char *s = start;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001731 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001732 Py_UCS4 ch;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001733 /* Fast path for non-control chars. The loop always ends
Victor Stinnerf7b8cb62011-09-29 03:28:17 +02001734 since the Unicode string is NUL-terminated. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001735 while (PyUnicode_READ(kind, s, 0) > '\r')
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001736 s += kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001737 if (s >= end) {
1738 *consumed = len;
1739 return -1;
1740 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001741 ch = PyUnicode_READ(kind, s, 0);
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001742 s += kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001743 if (ch == '\n')
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001744 return (s - start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001745 if (ch == '\r') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001746 if (PyUnicode_READ(kind, s, 0) == '\n')
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001747 return (s - start)/kind + 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001748 else
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001749 return (s - start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001750 }
1751 }
1752 }
1753 else {
1754 /* Non-universal mode. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001755 Py_ssize_t readnl_len = PyUnicode_GET_LENGTH(readnl);
Victor Stinner706768c2014-08-16 01:03:39 +02001756 Py_UCS1 *nl = PyUnicode_1BYTE_DATA(readnl);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001757 /* Assume that readnl is an ASCII character. */
1758 assert(PyUnicode_KIND(readnl) == PyUnicode_1BYTE_KIND);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001759 if (readnl_len == 1) {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001760 const char *pos = find_control_char(kind, start, end, nl[0]);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001761 if (pos != NULL)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001762 return (pos - start)/kind + 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001763 *consumed = len;
1764 return -1;
1765 }
1766 else {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001767 const char *s = start;
1768 const char *e = end - (readnl_len - 1)*kind;
1769 const char *pos;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001770 if (e < s)
1771 e = s;
1772 while (s < e) {
1773 Py_ssize_t i;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001774 const char *pos = find_control_char(kind, s, end, nl[0]);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775 if (pos == NULL || pos >= e)
1776 break;
1777 for (i = 1; i < readnl_len; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001778 if (PyUnicode_READ(kind, pos, i) != nl[i])
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001779 break;
1780 }
1781 if (i == readnl_len)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001782 return (pos - start)/kind + readnl_len;
1783 s = pos + kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001784 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001785 pos = find_control_char(kind, e, end, nl[0]);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001786 if (pos == NULL)
1787 *consumed = len;
1788 else
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001789 *consumed = (pos - start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001790 return -1;
1791 }
1792 }
1793}
1794
1795static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001796_textiowrapper_readline(textio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001797{
1798 PyObject *line = NULL, *chunks = NULL, *remaining = NULL;
1799 Py_ssize_t start, endpos, chunked, offset_to_buffer;
1800 int res;
1801
1802 CHECK_CLOSED(self);
1803
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001804 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805 return NULL;
1806
1807 chunked = 0;
1808
1809 while (1) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001810 char *ptr;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001811 Py_ssize_t line_len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001812 int kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001813 Py_ssize_t consumed = 0;
1814
1815 /* First, get some data if necessary */
1816 res = 1;
1817 while (!self->decoded_chars ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001818 !PyUnicode_GET_LENGTH(self->decoded_chars)) {
Antoine Pitroue5324562011-11-19 00:39:01 +01001819 res = textiowrapper_read_chunk(self, 0);
Gregory P. Smith51359922012-06-23 23:55:39 -07001820 if (res < 0) {
1821 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1822 when EINTR occurs so we needn't do it ourselves. */
1823 if (_PyIO_trap_eintr()) {
1824 continue;
1825 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001826 goto error;
Gregory P. Smith51359922012-06-23 23:55:39 -07001827 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001828 if (res == 0)
1829 break;
1830 }
1831 if (res == 0) {
1832 /* end of file */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001833 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001834 Py_CLEAR(self->snapshot);
1835 start = endpos = offset_to_buffer = 0;
1836 break;
1837 }
1838
1839 if (remaining == NULL) {
1840 line = self->decoded_chars;
1841 start = self->decoded_chars_used;
1842 offset_to_buffer = 0;
1843 Py_INCREF(line);
1844 }
1845 else {
1846 assert(self->decoded_chars_used == 0);
1847 line = PyUnicode_Concat(remaining, self->decoded_chars);
1848 start = 0;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001849 offset_to_buffer = PyUnicode_GET_LENGTH(remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001850 Py_CLEAR(remaining);
1851 if (line == NULL)
1852 goto error;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001853 if (PyUnicode_READY(line) == -1)
1854 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001855 }
1856
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001857 ptr = PyUnicode_DATA(line);
1858 line_len = PyUnicode_GET_LENGTH(line);
1859 kind = PyUnicode_KIND(line);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001860
1861 endpos = _PyIO_find_line_ending(
1862 self->readtranslate, self->readuniversal, self->readnl,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001863 kind,
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001864 ptr + kind * start,
1865 ptr + kind * line_len,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001866 &consumed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001867 if (endpos >= 0) {
1868 endpos += start;
1869 if (limit >= 0 && (endpos - start) + chunked >= limit)
1870 endpos = start + limit - chunked;
1871 break;
1872 }
1873
1874 /* We can put aside up to `endpos` */
1875 endpos = consumed + start;
1876 if (limit >= 0 && (endpos - start) + chunked >= limit) {
1877 /* Didn't find line ending, but reached length limit */
1878 endpos = start + limit - chunked;
1879 break;
1880 }
1881
1882 if (endpos > start) {
1883 /* No line ending seen yet - put aside current data */
1884 PyObject *s;
1885 if (chunks == NULL) {
1886 chunks = PyList_New(0);
1887 if (chunks == NULL)
1888 goto error;
1889 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001890 s = PyUnicode_Substring(line, start, endpos);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001891 if (s == NULL)
1892 goto error;
1893 if (PyList_Append(chunks, s) < 0) {
1894 Py_DECREF(s);
1895 goto error;
1896 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001897 chunked += PyUnicode_GET_LENGTH(s);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001898 Py_DECREF(s);
1899 }
1900 /* There may be some remaining bytes we'll have to prepend to the
1901 next chunk of data */
1902 if (endpos < line_len) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001903 remaining = PyUnicode_Substring(line, endpos, line_len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001904 if (remaining == NULL)
1905 goto error;
1906 }
1907 Py_CLEAR(line);
1908 /* We have consumed the buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001909 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001910 }
1911
1912 if (line != NULL) {
1913 /* Our line ends in the current buffer */
1914 self->decoded_chars_used = endpos - offset_to_buffer;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001915 if (start > 0 || endpos < PyUnicode_GET_LENGTH(line)) {
1916 PyObject *s = PyUnicode_Substring(line, start, endpos);
1917 Py_CLEAR(line);
1918 if (s == NULL)
1919 goto error;
1920 line = s;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921 }
1922 }
1923 if (remaining != NULL) {
1924 if (chunks == NULL) {
1925 chunks = PyList_New(0);
1926 if (chunks == NULL)
1927 goto error;
1928 }
1929 if (PyList_Append(chunks, remaining) < 0)
1930 goto error;
1931 Py_CLEAR(remaining);
1932 }
1933 if (chunks != NULL) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001934 if (line != NULL) {
1935 if (PyList_Append(chunks, line) < 0)
1936 goto error;
1937 Py_DECREF(line);
1938 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001939 line = PyUnicode_Join(_PyIO_empty_str, chunks);
1940 if (line == NULL)
1941 goto error;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001942 Py_CLEAR(chunks);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001943 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001944 if (line == NULL) {
1945 Py_INCREF(_PyIO_empty_str);
1946 line = _PyIO_empty_str;
1947 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001948
1949 return line;
1950
1951 error:
1952 Py_XDECREF(chunks);
1953 Py_XDECREF(remaining);
1954 Py_XDECREF(line);
1955 return NULL;
1956}
1957
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001958/*[clinic input]
1959_io.TextIOWrapper.readline
1960 size: Py_ssize_t = -1
1961 /
1962[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001963
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001964static PyObject *
1965_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size)
1966/*[clinic end generated code: output=344afa98804e8b25 input=56c7172483b36db6]*/
1967{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001968 CHECK_ATTACHED(self);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001969 return _textiowrapper_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001970}
1971
1972/* Seek and Tell */
1973
1974typedef struct {
1975 Py_off_t start_pos;
1976 int dec_flags;
1977 int bytes_to_feed;
1978 int chars_to_skip;
1979 char need_eof;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001980} cookie_type;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001981
1982/*
1983 To speed up cookie packing/unpacking, we store the fields in a temporary
1984 string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.).
1985 The following macros define at which offsets in the intermediary byte
1986 string the various CookieStruct fields will be stored.
1987 */
1988
1989#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char))
1990
Christian Heimes743e0cd2012-10-17 23:52:17 +02001991#if PY_BIG_ENDIAN
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001992/* We want the least significant byte of start_pos to also be the least
1993 significant byte of the cookie, which means that in big-endian mode we
1994 must copy the fields in reverse order. */
1995
1996# define OFF_START_POS (sizeof(char) + 3 * sizeof(int))
1997# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int))
1998# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int))
1999# define OFF_CHARS_TO_SKIP (sizeof(char))
2000# define OFF_NEED_EOF 0
2001
2002#else
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002003/* Little-endian mode: the least significant byte of start_pos will
2004 naturally end up the least significant byte of the cookie. */
2005
2006# define OFF_START_POS 0
2007# define OFF_DEC_FLAGS (sizeof(Py_off_t))
2008# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int))
2009# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int))
2010# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int))
2011
2012#endif
2013
2014static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002015textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002016{
2017 unsigned char buffer[COOKIE_BUF_LEN];
2018 PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj);
2019 if (cookieLong == NULL)
2020 return -1;
2021
2022 if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
Christian Heimes743e0cd2012-10-17 23:52:17 +02002023 PY_LITTLE_ENDIAN, 0) < 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 Py_DECREF(cookieLong);
2025 return -1;
2026 }
2027 Py_DECREF(cookieLong);
2028
Antoine Pitrou2db74c22009-03-06 21:49:02 +00002029 memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos));
2030 memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags));
2031 memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed));
2032 memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip));
2033 memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002034
2035 return 0;
2036}
2037
2038static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002039textiowrapper_build_cookie(cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002040{
2041 unsigned char buffer[COOKIE_BUF_LEN];
2042
Antoine Pitrou2db74c22009-03-06 21:49:02 +00002043 memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos));
2044 memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags));
2045 memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed));
2046 memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip));
2047 memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002048
Christian Heimes743e0cd2012-10-17 23:52:17 +02002049 return _PyLong_FromByteArray(buffer, sizeof(buffer),
2050 PY_LITTLE_ENDIAN, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002051}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002052
2053static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002054_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002055{
2056 PyObject *res;
2057 /* When seeking to the start of the stream, we call decoder.reset()
2058 rather than decoder.getstate().
2059 This is for a few decoders such as utf-16 for which the state value
2060 at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of
2061 utf-16, that we are expecting a BOM).
2062 */
2063 if (cookie->start_pos == 0 && cookie->dec_flags == 0)
2064 res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
2065 else
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002066 res = _PyObject_CallMethodId(self->decoder, &PyId_setstate,
2067 "((yi))", "", cookie->dec_flags);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002068 if (res == NULL)
2069 return -1;
2070 Py_DECREF(res);
2071 return 0;
2072}
2073
Antoine Pitroue4501852009-05-14 18:55:55 +00002074static int
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002075_textiowrapper_encoder_reset(textio *self, int start_of_stream)
Antoine Pitroue4501852009-05-14 18:55:55 +00002076{
2077 PyObject *res;
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002078 if (start_of_stream) {
Antoine Pitroue4501852009-05-14 18:55:55 +00002079 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL);
2080 self->encoding_start_of_stream = 1;
2081 }
2082 else {
2083 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002084 _PyLong_Zero, NULL);
Antoine Pitroue4501852009-05-14 18:55:55 +00002085 self->encoding_start_of_stream = 0;
2086 }
2087 if (res == NULL)
2088 return -1;
2089 Py_DECREF(res);
2090 return 0;
2091}
2092
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002093static int
2094_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie)
2095{
2096 /* Same as _textiowrapper_decoder_setstate() above. */
2097 return _textiowrapper_encoder_reset(
2098 self, cookie->start_pos == 0 && cookie->dec_flags == 0);
2099}
2100
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002101/*[clinic input]
2102_io.TextIOWrapper.seek
2103 cookie as cookieObj: object
2104 whence: int = 0
2105 /
2106[clinic start generated code]*/
2107
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002108static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002109_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence)
2110/*[clinic end generated code: output=0a15679764e2d04d input=0458abeb3d7842be]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002111{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002112 PyObject *posobj;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002113 cookie_type cookie;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002114 PyObject *res;
2115 int cmp;
2116
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002117 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002118 CHECK_CLOSED(self);
2119
2120 Py_INCREF(cookieObj);
2121
2122 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002123 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002124 goto fail;
2125 }
2126
2127 if (whence == 1) {
2128 /* seek relative to current position */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002129 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002130 if (cmp < 0)
2131 goto fail;
2132
2133 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002134 _unsupported("can't do nonzero cur-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002135 goto fail;
2136 }
2137
2138 /* Seeking to the current position should attempt to
2139 * sync the underlying buffer with the current position.
2140 */
2141 Py_DECREF(cookieObj);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002142 cookieObj = _PyObject_CallMethodId((PyObject *)self, &PyId_tell, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002143 if (cookieObj == NULL)
2144 goto fail;
2145 }
2146 else if (whence == 2) {
2147 /* seek relative to end of file */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002148 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002149 if (cmp < 0)
2150 goto fail;
2151
2152 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002153 _unsupported("can't do nonzero end-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002154 goto fail;
2155 }
2156
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002157 res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002158 if (res == NULL)
2159 goto fail;
2160 Py_DECREF(res);
2161
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002162 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002163 Py_CLEAR(self->snapshot);
2164 if (self->decoder) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002165 res = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002166 if (res == NULL)
2167 goto fail;
2168 Py_DECREF(res);
2169 }
2170
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002171 res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2);
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002172 Py_CLEAR(cookieObj);
2173 if (res == NULL)
2174 goto fail;
2175 if (self->encoder) {
2176 /* If seek() == 0, we are at the start of stream, otherwise not */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002177 cmp = PyObject_RichCompareBool(res, _PyLong_Zero, Py_EQ);
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002178 if (cmp < 0 || _textiowrapper_encoder_reset(self, cmp)) {
2179 Py_DECREF(res);
2180 goto fail;
2181 }
2182 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002183 return res;
2184 }
2185 else if (whence != 0) {
2186 PyErr_Format(PyExc_ValueError,
2187 "invalid whence (%d, should be 0, 1 or 2)", whence);
2188 goto fail;
2189 }
2190
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002191 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_LT);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002192 if (cmp < 0)
2193 goto fail;
2194
2195 if (cmp == 1) {
2196 PyErr_Format(PyExc_ValueError,
2197 "negative seek position %R", cookieObj);
2198 goto fail;
2199 }
2200
2201 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
2202 if (res == NULL)
2203 goto fail;
2204 Py_DECREF(res);
2205
2206 /* The strategy of seek() is to go back to the safe start point
2207 * and replay the effect of read(chars_to_skip) from there.
2208 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002209 if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002210 goto fail;
2211
2212 /* Seek back to the safe start point. */
2213 posobj = PyLong_FromOff_t(cookie.start_pos);
2214 if (posobj == NULL)
2215 goto fail;
2216 res = PyObject_CallMethodObjArgs(self->buffer,
2217 _PyIO_str_seek, posobj, NULL);
2218 Py_DECREF(posobj);
2219 if (res == NULL)
2220 goto fail;
2221 Py_DECREF(res);
2222
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002223 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002224 Py_CLEAR(self->snapshot);
2225
2226 /* Restore the decoder to its state from the safe start point. */
2227 if (self->decoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002228 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002229 goto fail;
2230 }
2231
2232 if (cookie.chars_to_skip) {
2233 /* Just like _read_chunk, feed the decoder and save a snapshot. */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002234 PyObject *input_chunk = _PyObject_CallMethodId(
2235 self->buffer, &PyId_read, "i", cookie.bytes_to_feed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002236 PyObject *decoded;
2237
2238 if (input_chunk == NULL)
2239 goto fail;
2240
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02002241 if (!PyBytes_Check(input_chunk)) {
2242 PyErr_Format(PyExc_TypeError,
2243 "underlying read() should have returned a bytes "
2244 "object, not '%.200s'",
2245 Py_TYPE(input_chunk)->tp_name);
2246 Py_DECREF(input_chunk);
2247 goto fail;
2248 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002249
2250 self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
2251 if (self->snapshot == NULL) {
2252 Py_DECREF(input_chunk);
2253 goto fail;
2254 }
2255
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002256 decoded = _PyObject_CallMethodId(self->decoder, &PyId_decode,
2257 "Oi", input_chunk, (int)cookie.need_eof);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002258
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02002259 if (check_decoded(decoded) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002260 goto fail;
2261
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002262 textiowrapper_set_decoded_chars(self, decoded);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002263
2264 /* Skip chars_to_skip of the decoded characters. */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002265 if (PyUnicode_GetLength(self->decoded_chars) < cookie.chars_to_skip) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002266 PyErr_SetString(PyExc_OSError, "can't restore logical file position");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002267 goto fail;
2268 }
2269 self->decoded_chars_used = cookie.chars_to_skip;
2270 }
2271 else {
2272 self->snapshot = Py_BuildValue("iy", cookie.dec_flags, "");
2273 if (self->snapshot == NULL)
2274 goto fail;
2275 }
2276
Antoine Pitroue4501852009-05-14 18:55:55 +00002277 /* Finally, reset the encoder (merely useful for proper BOM handling) */
2278 if (self->encoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002279 if (_textiowrapper_encoder_setstate(self, &cookie) < 0)
Antoine Pitroue4501852009-05-14 18:55:55 +00002280 goto fail;
2281 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002282 return cookieObj;
2283 fail:
2284 Py_XDECREF(cookieObj);
2285 return NULL;
2286
2287}
2288
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002289/*[clinic input]
2290_io.TextIOWrapper.tell
2291[clinic start generated code]*/
2292
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002293static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002294_io_TextIOWrapper_tell_impl(textio *self)
2295/*[clinic end generated code: output=4f168c08bf34ad5f input=9a2caf88c24f9ddf]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002296{
2297 PyObject *res;
2298 PyObject *posobj = NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002299 cookie_type cookie = {0,0,0,0,0};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002300 PyObject *next_input;
2301 Py_ssize_t chars_to_skip, chars_decoded;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002302 Py_ssize_t skip_bytes, skip_back;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002303 PyObject *saved_state = NULL;
2304 char *input, *input_end;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002305 Py_ssize_t dec_buffer_len;
2306 int dec_flags;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002307
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002308 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002309 CHECK_CLOSED(self);
2310
2311 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002312 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002313 goto fail;
2314 }
2315 if (!self->telling) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002316 PyErr_SetString(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002317 "telling position disabled by next() call");
2318 goto fail;
2319 }
2320
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002321 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002322 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002323 res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002324 if (res == NULL)
2325 goto fail;
2326 Py_DECREF(res);
2327
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002328 posobj = _PyObject_CallMethodId(self->buffer, &PyId_tell, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002329 if (posobj == NULL)
2330 goto fail;
2331
2332 if (self->decoder == NULL || self->snapshot == NULL) {
Victor Stinner9e30aa52011-11-21 02:49:52 +01002333 assert (self->decoded_chars == NULL || PyUnicode_GetLength(self->decoded_chars) == 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002334 return posobj;
2335 }
2336
2337#if defined(HAVE_LARGEFILE_SUPPORT)
2338 cookie.start_pos = PyLong_AsLongLong(posobj);
2339#else
2340 cookie.start_pos = PyLong_AsLong(posobj);
2341#endif
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002342 Py_DECREF(posobj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002343 if (PyErr_Occurred())
2344 goto fail;
2345
2346 /* Skip backward to the snapshot point (see _read_chunk). */
Serhiy Storchakabb72c472015-04-19 20:38:19 +03002347 if (!PyArg_ParseTuple(self->snapshot, "iO", &cookie.dec_flags, &next_input))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002348 goto fail;
2349
2350 assert (PyBytes_Check(next_input));
2351
2352 cookie.start_pos -= PyBytes_GET_SIZE(next_input);
2353
2354 /* How many decoded characters have been used up since the snapshot? */
2355 if (self->decoded_chars_used == 0) {
2356 /* We haven't moved from the snapshot point. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002357 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002358 }
2359
2360 chars_to_skip = self->decoded_chars_used;
2361
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002362 /* Decoder state will be restored at the end */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002363 saved_state = PyObject_CallMethodObjArgs(self->decoder,
2364 _PyIO_str_getstate, NULL);
2365 if (saved_state == NULL)
2366 goto fail;
2367
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002368#define DECODER_GETSTATE() do { \
Serhiy Storchaka008d88b2015-05-06 09:53:07 +03002369 PyObject *dec_buffer; \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002370 PyObject *_state = PyObject_CallMethodObjArgs(self->decoder, \
2371 _PyIO_str_getstate, NULL); \
2372 if (_state == NULL) \
2373 goto fail; \
Serhiy Storchaka008d88b2015-05-06 09:53:07 +03002374 if (!PyArg_ParseTuple(_state, "Oi", &dec_buffer, &dec_flags)) { \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002375 Py_DECREF(_state); \
2376 goto fail; \
2377 } \
Serhiy Storchaka008d88b2015-05-06 09:53:07 +03002378 if (!PyBytes_Check(dec_buffer)) { \
2379 PyErr_Format(PyExc_TypeError, \
2380 "decoder getstate() should have returned a bytes " \
2381 "object, not '%.200s'", \
2382 Py_TYPE(dec_buffer)->tp_name); \
2383 Py_DECREF(_state); \
2384 goto fail; \
2385 } \
2386 dec_buffer_len = PyBytes_GET_SIZE(dec_buffer); \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002387 Py_DECREF(_state); \
2388 } while (0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002389
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002390#define DECODER_DECODE(start, len, res) do { \
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002391 PyObject *_decoded = _PyObject_CallMethodId( \
2392 self->decoder, &PyId_decode, "y#", start, len); \
Serhiy Storchakad03ce4a2013-02-03 17:07:32 +02002393 if (check_decoded(_decoded) < 0) \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002394 goto fail; \
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002395 res = PyUnicode_GET_LENGTH(_decoded); \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002396 Py_DECREF(_decoded); \
2397 } while (0)
2398
2399 /* Fast search for an acceptable start point, close to our
2400 current pos */
2401 skip_bytes = (Py_ssize_t) (self->b2cratio * chars_to_skip);
2402 skip_back = 1;
2403 assert(skip_back <= PyBytes_GET_SIZE(next_input));
2404 input = PyBytes_AS_STRING(next_input);
2405 while (skip_bytes > 0) {
2406 /* Decode up to temptative start point */
2407 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
2408 goto fail;
2409 DECODER_DECODE(input, skip_bytes, chars_decoded);
2410 if (chars_decoded <= chars_to_skip) {
2411 DECODER_GETSTATE();
2412 if (dec_buffer_len == 0) {
2413 /* Before pos and no bytes buffered in decoder => OK */
2414 cookie.dec_flags = dec_flags;
2415 chars_to_skip -= chars_decoded;
2416 break;
2417 }
2418 /* Skip back by buffered amount and reset heuristic */
2419 skip_bytes -= dec_buffer_len;
2420 skip_back = 1;
2421 }
2422 else {
2423 /* We're too far ahead, skip back a bit */
2424 skip_bytes -= skip_back;
2425 skip_back *= 2;
2426 }
2427 }
2428 if (skip_bytes <= 0) {
2429 skip_bytes = 0;
2430 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
2431 goto fail;
2432 }
2433
2434 /* Note our initial start point. */
2435 cookie.start_pos += skip_bytes;
Victor Stinner9a282972013-06-24 23:01:33 +02002436 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002437 if (chars_to_skip == 0)
2438 goto finally;
2439
2440 /* We should be close to the desired position. Now feed the decoder one
2441 * byte at a time until we reach the `chars_to_skip` target.
2442 * As we go, note the nearest "safe start point" before the current
2443 * location (a point where the decoder has nothing buffered, so seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002444 * can safely start from there and advance to this location).
2445 */
2446 chars_decoded = 0;
2447 input = PyBytes_AS_STRING(next_input);
2448 input_end = input + PyBytes_GET_SIZE(next_input);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002449 input += skip_bytes;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002450 while (input < input_end) {
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002451 Py_ssize_t n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002452
Serhiy Storchakaec67d182013-08-20 20:04:47 +03002453 DECODER_DECODE(input, (Py_ssize_t)1, n);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002454 /* We got n chars for 1 byte */
2455 chars_decoded += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002456 cookie.bytes_to_feed += 1;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002457 DECODER_GETSTATE();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002458
2459 if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) {
2460 /* Decoder buffer is empty, so this is a safe start point. */
2461 cookie.start_pos += cookie.bytes_to_feed;
2462 chars_to_skip -= chars_decoded;
2463 cookie.dec_flags = dec_flags;
2464 cookie.bytes_to_feed = 0;
2465 chars_decoded = 0;
2466 }
2467 if (chars_decoded >= chars_to_skip)
2468 break;
2469 input++;
2470 }
2471 if (input == input_end) {
2472 /* We didn't get enough decoded data; signal EOF to get more. */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002473 PyObject *decoded = _PyObject_CallMethodId(
2474 self->decoder, &PyId_decode, "yi", "", /* final = */ 1);
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02002475 if (check_decoded(decoded) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002476 goto fail;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002477 chars_decoded += PyUnicode_GET_LENGTH(decoded);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002478 Py_DECREF(decoded);
2479 cookie.need_eof = 1;
2480
2481 if (chars_decoded < chars_to_skip) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002482 PyErr_SetString(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002483 "can't reconstruct logical file position");
2484 goto fail;
2485 }
2486 }
2487
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002488finally:
Victor Stinner7e425412016-12-09 00:36:19 +01002489 res = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002490 Py_DECREF(saved_state);
2491 if (res == NULL)
2492 return NULL;
2493 Py_DECREF(res);
2494
2495 /* The returned cookie corresponds to the last safe start point. */
2496 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002497 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002498
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002499fail:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002500 if (saved_state) {
2501 PyObject *type, *value, *traceback;
2502 PyErr_Fetch(&type, &value, &traceback);
Victor Stinner7e425412016-12-09 00:36:19 +01002503 res = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL);
Serhiy Storchaka04d09eb2015-03-30 09:58:41 +03002504 _PyErr_ChainExceptions(type, value, traceback);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002505 Py_DECREF(saved_state);
Serhiy Storchaka04d09eb2015-03-30 09:58:41 +03002506 Py_XDECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002507 }
2508 return NULL;
2509}
2510
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002511/*[clinic input]
2512_io.TextIOWrapper.truncate
2513 pos: object = None
2514 /
2515[clinic start generated code]*/
2516
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002517static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002518_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos)
2519/*[clinic end generated code: output=90ec2afb9bb7745f input=56ec8baa65aea377]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002520{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002521 PyObject *res;
2522
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002523 CHECK_ATTACHED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002524
2525 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL);
2526 if (res == NULL)
2527 return NULL;
2528 Py_DECREF(res);
2529
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00002530 return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, pos, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002531}
2532
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002533static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002534textiowrapper_repr(textio *self)
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002535{
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002536 PyObject *nameobj, *modeobj, *res, *s;
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002537 int status;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002538
2539 CHECK_INITIALIZED(self);
2540
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002541 res = PyUnicode_FromString("<_io.TextIOWrapper");
2542 if (res == NULL)
2543 return NULL;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002544
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002545 status = Py_ReprEnter((PyObject *)self);
2546 if (status != 0) {
2547 if (status > 0) {
2548 PyErr_Format(PyExc_RuntimeError,
2549 "reentrant call inside %s.__repr__",
2550 Py_TYPE(self)->tp_name);
2551 }
2552 goto error;
2553 }
Martin v. Löwis767046a2011-10-14 15:35:36 +02002554 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00002555 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002556 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00002557 PyErr_Clear();
2558 else
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002559 goto error;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002560 }
2561 else {
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002562 s = PyUnicode_FromFormat(" name=%R", nameobj);
Antoine Pitrou716c4442009-05-23 19:04:03 +00002563 Py_DECREF(nameobj);
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002564 if (s == NULL)
2565 goto error;
2566 PyUnicode_AppendAndDel(&res, s);
2567 if (res == NULL)
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002568 goto error;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002569 }
Martin v. Löwis767046a2011-10-14 15:35:36 +02002570 modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode);
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002571 if (modeobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002572 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002573 PyErr_Clear();
2574 else
2575 goto error;
2576 }
2577 else {
2578 s = PyUnicode_FromFormat(" mode=%R", modeobj);
2579 Py_DECREF(modeobj);
2580 if (s == NULL)
2581 goto error;
2582 PyUnicode_AppendAndDel(&res, s);
2583 if (res == NULL)
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002584 goto error;
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002585 }
2586 s = PyUnicode_FromFormat("%U encoding=%R>",
2587 res, self->encoding);
2588 Py_DECREF(res);
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002589 if (status == 0) {
2590 Py_ReprLeave((PyObject *)self);
2591 }
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002592 return s;
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002593
2594 error:
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002595 Py_XDECREF(res);
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002596 if (status == 0) {
2597 Py_ReprLeave((PyObject *)self);
2598 }
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002599 return NULL;
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002600}
2601
2602
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002603/* Inquiries */
2604
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002605/*[clinic input]
2606_io.TextIOWrapper.fileno
2607[clinic start generated code]*/
2608
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002609static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002610_io_TextIOWrapper_fileno_impl(textio *self)
2611/*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002612{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002613 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002614 return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002615}
2616
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002617/*[clinic input]
2618_io.TextIOWrapper.seekable
2619[clinic start generated code]*/
2620
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002621static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002622_io_TextIOWrapper_seekable_impl(textio *self)
2623/*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002624{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002625 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002626 return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002627}
2628
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002629/*[clinic input]
2630_io.TextIOWrapper.readable
2631[clinic start generated code]*/
2632
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002633static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002634_io_TextIOWrapper_readable_impl(textio *self)
2635/*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002636{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002637 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002638 return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002639}
2640
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002641/*[clinic input]
2642_io.TextIOWrapper.writable
2643[clinic start generated code]*/
2644
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002645static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002646_io_TextIOWrapper_writable_impl(textio *self)
2647/*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002648{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002649 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002650 return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002651}
2652
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002653/*[clinic input]
2654_io.TextIOWrapper.isatty
2655[clinic start generated code]*/
2656
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002657static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002658_io_TextIOWrapper_isatty_impl(textio *self)
2659/*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002660{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002661 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002662 return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002663}
2664
2665static PyObject *
Antoine Pitrou243757e2010-11-05 21:15:39 +00002666textiowrapper_getstate(textio *self, PyObject *args)
2667{
2668 PyErr_Format(PyExc_TypeError,
2669 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
2670 return NULL;
2671}
2672
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002673/*[clinic input]
2674_io.TextIOWrapper.flush
2675[clinic start generated code]*/
2676
Antoine Pitrou243757e2010-11-05 21:15:39 +00002677static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002678_io_TextIOWrapper_flush_impl(textio *self)
2679/*[clinic end generated code: output=59de9165f9c2e4d2 input=928c60590694ab85]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002680{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002681 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002682 CHECK_CLOSED(self);
2683 self->telling = self->seekable;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002684 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002685 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002686 return _PyObject_CallMethodId(self->buffer, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002687}
2688
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002689/*[clinic input]
2690_io.TextIOWrapper.close
2691[clinic start generated code]*/
2692
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002693static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002694_io_TextIOWrapper_close_impl(textio *self)
2695/*[clinic end generated code: output=056ccf8b4876e4f4 input=9c2114315eae1948]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002696{
2697 PyObject *res;
Antoine Pitrou6be88762010-05-03 16:48:20 +00002698 int r;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002699 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002700
Antoine Pitrou6be88762010-05-03 16:48:20 +00002701 res = textiowrapper_closed_get(self, NULL);
2702 if (res == NULL)
2703 return NULL;
2704 r = PyObject_IsTrue(res);
2705 Py_DECREF(res);
2706 if (r < 0)
2707 return NULL;
Victor Stinnerf6c57832010-05-19 01:17:01 +00002708
Antoine Pitrou6be88762010-05-03 16:48:20 +00002709 if (r > 0) {
2710 Py_RETURN_NONE; /* stream already closed */
2711 }
2712 else {
Benjamin Peterson68623612012-12-20 11:53:11 -06002713 PyObject *exc = NULL, *val, *tb;
Antoine Pitrou796564c2013-07-30 19:59:21 +02002714 if (self->finalizing) {
Victor Stinner61bdb0d2016-12-09 15:39:28 +01002715 res = _PyObject_CallMethodIdObjArgs(self->buffer,
2716 &PyId__dealloc_warn,
2717 self, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +00002718 if (res)
2719 Py_DECREF(res);
2720 else
2721 PyErr_Clear();
2722 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002723 res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
Benjamin Peterson68623612012-12-20 11:53:11 -06002724 if (res == NULL)
2725 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou6be88762010-05-03 16:48:20 +00002726 else
2727 Py_DECREF(res);
2728
Benjamin Peterson68623612012-12-20 11:53:11 -06002729 res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);
2730 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +03002731 _PyErr_ChainExceptions(exc, val, tb);
2732 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -06002733 }
2734 return res;
Antoine Pitrou6be88762010-05-03 16:48:20 +00002735 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002736}
2737
2738static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002739textiowrapper_iternext(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002740{
2741 PyObject *line;
2742
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002743 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002744
2745 self->telling = 0;
2746 if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
2747 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002748 line = _textiowrapper_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002749 }
2750 else {
2751 line = PyObject_CallMethodObjArgs((PyObject *)self,
2752 _PyIO_str_readline, NULL);
2753 if (line && !PyUnicode_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002754 PyErr_Format(PyExc_OSError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002755 "readline() should have returned a str object, "
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002756 "not '%.200s'", Py_TYPE(line)->tp_name);
2757 Py_DECREF(line);
2758 return NULL;
2759 }
2760 }
2761
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002762 if (line == NULL || PyUnicode_READY(line) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002763 return NULL;
2764
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002765 if (PyUnicode_GET_LENGTH(line) == 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002766 /* Reached EOF or would have blocked */
2767 Py_DECREF(line);
2768 Py_CLEAR(self->snapshot);
2769 self->telling = self->seekable;
2770 return NULL;
2771 }
2772
2773 return line;
2774}
2775
2776static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002777textiowrapper_name_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002778{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002779 CHECK_ATTACHED(self);
Martin v. Löwis767046a2011-10-14 15:35:36 +02002780 return _PyObject_GetAttrId(self->buffer, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002781}
2782
2783static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002784textiowrapper_closed_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002785{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002786 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002787 return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
2788}
2789
2790static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002791textiowrapper_newlines_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002792{
2793 PyObject *res;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002794 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002795 if (self->decoder == NULL)
2796 Py_RETURN_NONE;
2797 res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
2798 if (res == NULL) {
Benjamin Peterson2cfca792009-06-06 20:46:48 +00002799 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
2800 PyErr_Clear();
2801 Py_RETURN_NONE;
2802 }
2803 else {
2804 return NULL;
2805 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002806 }
2807 return res;
2808}
2809
2810static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002811textiowrapper_errors_get(textio *self, void *context)
Benjamin Peterson0926ad12009-06-06 18:02:12 +00002812{
2813 CHECK_INITIALIZED(self);
2814 return PyUnicode_FromString(PyBytes_AS_STRING(self->errors));
2815}
2816
2817static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002818textiowrapper_chunk_size_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002819{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002820 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002821 return PyLong_FromSsize_t(self->chunk_size);
2822}
2823
2824static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002825textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002826{
2827 Py_ssize_t n;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002828 CHECK_ATTACHED_INT(self);
Antoine Pitroucb4ae812011-07-13 21:07:49 +02002829 n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002830 if (n == -1 && PyErr_Occurred())
2831 return -1;
2832 if (n <= 0) {
2833 PyErr_SetString(PyExc_ValueError,
2834 "a strictly positive integer is required");
2835 return -1;
2836 }
2837 self->chunk_size = n;
2838 return 0;
2839}
2840
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002841#include "clinic/textio.c.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002842
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002843static PyMethodDef incrementalnewlinedecoder_methods[] = {
2844 _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF
2845 _IO_INCREMENTALNEWLINEDECODER_GETSTATE_METHODDEF
2846 _IO_INCREMENTALNEWLINEDECODER_SETSTATE_METHODDEF
2847 _IO_INCREMENTALNEWLINEDECODER_RESET_METHODDEF
2848 {NULL}
2849};
2850
2851static PyGetSetDef incrementalnewlinedecoder_getset[] = {
2852 {"newlines", (getter)incrementalnewlinedecoder_newlines_get, NULL, NULL},
2853 {NULL}
2854};
2855
2856PyTypeObject PyIncrementalNewlineDecoder_Type = {
2857 PyVarObject_HEAD_INIT(NULL, 0)
2858 "_io.IncrementalNewlineDecoder", /*tp_name*/
2859 sizeof(nldecoder_object), /*tp_basicsize*/
2860 0, /*tp_itemsize*/
2861 (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/
2862 0, /*tp_print*/
2863 0, /*tp_getattr*/
2864 0, /*tp_setattr*/
2865 0, /*tp_compare */
2866 0, /*tp_repr*/
2867 0, /*tp_as_number*/
2868 0, /*tp_as_sequence*/
2869 0, /*tp_as_mapping*/
2870 0, /*tp_hash */
2871 0, /*tp_call*/
2872 0, /*tp_str*/
2873 0, /*tp_getattro*/
2874 0, /*tp_setattro*/
2875 0, /*tp_as_buffer*/
2876 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
2877 _io_IncrementalNewlineDecoder___init____doc__, /* tp_doc */
2878 0, /* tp_traverse */
2879 0, /* tp_clear */
2880 0, /* tp_richcompare */
2881 0, /*tp_weaklistoffset*/
2882 0, /* tp_iter */
2883 0, /* tp_iternext */
2884 incrementalnewlinedecoder_methods, /* tp_methods */
2885 0, /* tp_members */
2886 incrementalnewlinedecoder_getset, /* tp_getset */
2887 0, /* tp_base */
2888 0, /* tp_dict */
2889 0, /* tp_descr_get */
2890 0, /* tp_descr_set */
2891 0, /* tp_dictoffset */
2892 _io_IncrementalNewlineDecoder___init__, /* tp_init */
2893 0, /* tp_alloc */
2894 PyType_GenericNew, /* tp_new */
2895};
2896
2897
2898static PyMethodDef textiowrapper_methods[] = {
2899 _IO_TEXTIOWRAPPER_DETACH_METHODDEF
Antoine Pitrou3c2817b2017-06-03 12:32:28 +02002900 _IO_TEXTIOWRAPPER_RECONFIGURE_METHODDEF
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002901 _IO_TEXTIOWRAPPER_WRITE_METHODDEF
2902 _IO_TEXTIOWRAPPER_READ_METHODDEF
2903 _IO_TEXTIOWRAPPER_READLINE_METHODDEF
2904 _IO_TEXTIOWRAPPER_FLUSH_METHODDEF
2905 _IO_TEXTIOWRAPPER_CLOSE_METHODDEF
2906
2907 _IO_TEXTIOWRAPPER_FILENO_METHODDEF
2908 _IO_TEXTIOWRAPPER_SEEKABLE_METHODDEF
2909 _IO_TEXTIOWRAPPER_READABLE_METHODDEF
2910 _IO_TEXTIOWRAPPER_WRITABLE_METHODDEF
2911 _IO_TEXTIOWRAPPER_ISATTY_METHODDEF
Antoine Pitrou243757e2010-11-05 21:15:39 +00002912 {"__getstate__", (PyCFunction)textiowrapper_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002913
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002914 _IO_TEXTIOWRAPPER_SEEK_METHODDEF
2915 _IO_TEXTIOWRAPPER_TELL_METHODDEF
2916 _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002917 {NULL, NULL}
2918};
2919
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002920static PyMemberDef textiowrapper_members[] = {
2921 {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY},
2922 {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY},
2923 {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY},
Antoine Pitrou3c2817b2017-06-03 12:32:28 +02002924 {"write_through", T_BOOL, offsetof(textio, write_through), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002925 {"_finalizing", T_BOOL, offsetof(textio, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002926 {NULL}
2927};
2928
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002929static PyGetSetDef textiowrapper_getset[] = {
2930 {"name", (getter)textiowrapper_name_get, NULL, NULL},
2931 {"closed", (getter)textiowrapper_closed_get, NULL, NULL},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002932/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL},
2933*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002934 {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL},
2935 {"errors", (getter)textiowrapper_errors_get, NULL, NULL},
2936 {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get,
2937 (setter)textiowrapper_chunk_size_set, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002938 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002939};
2940
2941PyTypeObject PyTextIOWrapper_Type = {
2942 PyVarObject_HEAD_INIT(NULL, 0)
2943 "_io.TextIOWrapper", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002944 sizeof(textio), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002945 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002946 (destructor)textiowrapper_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002947 0, /*tp_print*/
2948 0, /*tp_getattr*/
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002949 0, /*tps_etattr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002950 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002951 (reprfunc)textiowrapper_repr,/*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002952 0, /*tp_as_number*/
2953 0, /*tp_as_sequence*/
2954 0, /*tp_as_mapping*/
2955 0, /*tp_hash */
2956 0, /*tp_call*/
2957 0, /*tp_str*/
2958 0, /*tp_getattro*/
2959 0, /*tp_setattro*/
2960 0, /*tp_as_buffer*/
2961 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02002962 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002963 _io_TextIOWrapper___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002964 (traverseproc)textiowrapper_traverse, /* tp_traverse */
2965 (inquiry)textiowrapper_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002966 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002967 offsetof(textio, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002968 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002969 (iternextfunc)textiowrapper_iternext, /* tp_iternext */
2970 textiowrapper_methods, /* tp_methods */
2971 textiowrapper_members, /* tp_members */
2972 textiowrapper_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002973 0, /* tp_base */
2974 0, /* tp_dict */
2975 0, /* tp_descr_get */
2976 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002977 offsetof(textio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002978 _io_TextIOWrapper___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002979 0, /* tp_alloc */
2980 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02002981 0, /* tp_free */
2982 0, /* tp_is_gc */
2983 0, /* tp_bases */
2984 0, /* tp_mro */
2985 0, /* tp_cache */
2986 0, /* tp_subclasses */
2987 0, /* tp_weaklist */
2988 0, /* tp_del */
2989 0, /* tp_version_tag */
2990 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002991};