Coverage Report

Created: 2025-07-04 06:49

/src/cpython/Modules/_io/clinic/fileio.c.h
Line
Count
Source (jump to first uncovered line)
1
/*[clinic input]
2
preserve
3
[clinic start generated code]*/
4
5
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
6
#  include "pycore_gc.h"          // PyGC_Head
7
#  include "pycore_runtime.h"     // _Py_ID()
8
#endif
9
#include "pycore_abstract.h"      // _Py_convert_optional_to_ssize_t()
10
#include "pycore_modsupport.h"    // _PyArg_UnpackKeywords()
11
12
PyDoc_STRVAR(_io_FileIO_close__doc__,
13
"close($self, /)\n"
14
"--\n"
15
"\n"
16
"Close the file.\n"
17
"\n"
18
"A closed file cannot be used for further I/O operations.  close() may be\n"
19
"called more than once without error.");
20
21
#define _IO_FILEIO_CLOSE_METHODDEF    \
22
    {"close", _PyCFunction_CAST(_io_FileIO_close), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_close__doc__},
23
24
static PyObject *
25
_io_FileIO_close_impl(fileio *self, PyTypeObject *cls);
26
27
static PyObject *
28
_io_FileIO_close(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
29
1.16k
{
30
1.16k
    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
31
0
        PyErr_SetString(PyExc_TypeError, "close() takes no arguments");
32
0
        return NULL;
33
0
    }
34
1.16k
    return _io_FileIO_close_impl((fileio *)self, cls);
35
1.16k
}
36
37
PyDoc_STRVAR(_io_FileIO___init____doc__,
38
"FileIO(file, mode=\'r\', closefd=True, opener=None)\n"
39
"--\n"
40
"\n"
41
"Open a file.\n"
42
"\n"
43
"The mode can be \'r\' (default), \'w\', \'x\' or \'a\' for reading,\n"
44
"writing, exclusive creation or appending.  The file will be created if it\n"
45
"doesn\'t exist when opened for writing or appending; it will be truncated\n"
46
"when opened for writing.  A FileExistsError will be raised if it already\n"
47
"exists when opened for creating. Opening a file for creating implies\n"
48
"writing so this mode behaves in a similar way to \'w\'.Add a \'+\' to the mode\n"
49
"to allow simultaneous reading and writing. A custom opener can be used by\n"
50
"passing a callable as *opener*. The underlying file descriptor for the file\n"
51
"object is then obtained by calling opener with (*name*, *flags*).\n"
52
"*opener* must return an open file descriptor (passing os.open as *opener*\n"
53
"results in functionality similar to passing None).");
54
55
static int
56
_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
57
                         int closefd, PyObject *opener);
58
59
static int
60
_io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs)
61
1.20k
{
62
1.20k
    int return_value = -1;
63
1.20k
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
64
65
1.20k
    #define NUM_KEYWORDS 4
66
1.20k
    static struct {
67
1.20k
        PyGC_Head _this_is_not_used;
68
1.20k
        PyObject_VAR_HEAD
69
1.20k
        Py_hash_t ob_hash;
70
1.20k
        PyObject *ob_item[NUM_KEYWORDS];
71
1.20k
    } _kwtuple = {
72
1.20k
        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
73
1.20k
        .ob_hash = -1,
74
1.20k
        .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(closefd), &_Py_ID(opener), },
75
1.20k
    };
76
1.20k
    #undef NUM_KEYWORDS
77
1.20k
    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
78
79
    #else  // !Py_BUILD_CORE
80
    #  define KWTUPLE NULL
81
    #endif  // !Py_BUILD_CORE
82
83
1.20k
    static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL};
84
1.20k
    static _PyArg_Parser _parser = {
85
1.20k
        .keywords = _keywords,
86
1.20k
        .fname = "FileIO",
87
1.20k
        .kwtuple = KWTUPLE,
88
1.20k
    };
89
1.20k
    #undef KWTUPLE
90
1.20k
    PyObject *argsbuf[4];
91
1.20k
    PyObject * const *fastargs;
92
1.20k
    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
93
1.20k
    Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
94
1.20k
    PyObject *nameobj;
95
1.20k
    const char *mode = "r";
96
1.20k
    int closefd = 1;
97
1.20k
    PyObject *opener = Py_None;
98
99
1.20k
    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
100
1.20k
            /*minpos*/ 1, /*maxpos*/ 4, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
101
1.20k
    if (!fastargs) {
102
0
        goto exit;
103
0
    }
104
1.20k
    nameobj = fastargs[0];
105
1.20k
    if (!noptargs) {
106
0
        goto skip_optional_pos;
107
0
    }
108
1.20k
    if (fastargs[1]) {
109
1.20k
        if (!PyUnicode_Check(fastargs[1])) {
110
0
            _PyArg_BadArgument("FileIO", "argument 'mode'", "str", fastargs[1]);
111
0
            goto exit;
112
0
        }
113
1.20k
        Py_ssize_t mode_length;
114
1.20k
        mode = PyUnicode_AsUTF8AndSize(fastargs[1], &mode_length);
115
1.20k
        if (mode == NULL) {
116
0
            goto exit;
117
0
        }
118
1.20k
        if (strlen(mode) != (size_t)mode_length) {
119
0
            PyErr_SetString(PyExc_ValueError, "embedded null character");
120
0
            goto exit;
121
0
        }
122
1.20k
        if (!--noptargs) {
123
216
            goto skip_optional_pos;
124
216
        }
125
1.20k
    }
126
992
    if (fastargs[2]) {
127
992
        closefd = PyObject_IsTrue(fastargs[2]);
128
992
        if (closefd < 0) {
129
0
            goto exit;
130
0
        }
131
992
        if (!--noptargs) {
132
0
            goto skip_optional_pos;
133
0
        }
134
992
    }
135
992
    opener = fastargs[3];
136
1.20k
skip_optional_pos:
137
1.20k
    return_value = _io_FileIO___init___impl((fileio *)self, nameobj, mode, closefd, opener);
138
139
1.20k
exit:
140
1.20k
    return return_value;
141
1.20k
}
142
143
PyDoc_STRVAR(_io_FileIO_fileno__doc__,
144
"fileno($self, /)\n"
145
"--\n"
146
"\n"
147
"Return the underlying file descriptor (an integer).");
148
149
#define _IO_FILEIO_FILENO_METHODDEF    \
150
    {"fileno", (PyCFunction)_io_FileIO_fileno, METH_NOARGS, _io_FileIO_fileno__doc__},
151
152
static PyObject *
153
_io_FileIO_fileno_impl(fileio *self);
154
155
static PyObject *
156
_io_FileIO_fileno(PyObject *self, PyObject *Py_UNUSED(ignored))
157
0
{
158
0
    return _io_FileIO_fileno_impl((fileio *)self);
159
0
}
160
161
PyDoc_STRVAR(_io_FileIO_readable__doc__,
162
"readable($self, /)\n"
163
"--\n"
164
"\n"
165
"True if file was opened in a read mode.");
166
167
#define _IO_FILEIO_READABLE_METHODDEF    \
168
    {"readable", (PyCFunction)_io_FileIO_readable, METH_NOARGS, _io_FileIO_readable__doc__},
169
170
static PyObject *
171
_io_FileIO_readable_impl(fileio *self);
172
173
static PyObject *
174
_io_FileIO_readable(PyObject *self, PyObject *Py_UNUSED(ignored))
175
976
{
176
976
    return _io_FileIO_readable_impl((fileio *)self);
177
976
}
178
179
PyDoc_STRVAR(_io_FileIO_writable__doc__,
180
"writable($self, /)\n"
181
"--\n"
182
"\n"
183
"True if file was opened in a write mode.");
184
185
#define _IO_FILEIO_WRITABLE_METHODDEF    \
186
    {"writable", (PyCFunction)_io_FileIO_writable, METH_NOARGS, _io_FileIO_writable__doc__},
187
188
static PyObject *
189
_io_FileIO_writable_impl(fileio *self);
190
191
static PyObject *
192
_io_FileIO_writable(PyObject *self, PyObject *Py_UNUSED(ignored))
193
64
{
194
64
    return _io_FileIO_writable_impl((fileio *)self);
195
64
}
196
197
PyDoc_STRVAR(_io_FileIO_seekable__doc__,
198
"seekable($self, /)\n"
199
"--\n"
200
"\n"
201
"True if file supports random-access.");
202
203
#define _IO_FILEIO_SEEKABLE_METHODDEF    \
204
    {"seekable", (PyCFunction)_io_FileIO_seekable, METH_NOARGS, _io_FileIO_seekable__doc__},
205
206
static PyObject *
207
_io_FileIO_seekable_impl(fileio *self);
208
209
static PyObject *
210
_io_FileIO_seekable(PyObject *self, PyObject *Py_UNUSED(ignored))
211
54
{
212
54
    return _io_FileIO_seekable_impl((fileio *)self);
213
54
}
214
215
PyDoc_STRVAR(_io_FileIO_readinto__doc__,
216
"readinto($self, buffer, /)\n"
217
"--\n"
218
"\n"
219
"Same as RawIOBase.readinto().");
220
221
#define _IO_FILEIO_READINTO_METHODDEF    \
222
    {"readinto", _PyCFunction_CAST(_io_FileIO_readinto), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_readinto__doc__},
223
224
static PyObject *
225
_io_FileIO_readinto_impl(fileio *self, PyTypeObject *cls, Py_buffer *buffer);
226
227
static PyObject *
228
_io_FileIO_readinto(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
229
4
{
230
4
    PyObject *return_value = NULL;
231
4
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
232
4
    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
233
    #else
234
    #  define KWTUPLE NULL
235
    #endif
236
237
4
    static const char * const _keywords[] = {"", NULL};
238
4
    static _PyArg_Parser _parser = {
239
4
        .keywords = _keywords,
240
4
        .fname = "readinto",
241
4
        .kwtuple = KWTUPLE,
242
4
    };
243
4
    #undef KWTUPLE
244
4
    PyObject *argsbuf[1];
245
4
    Py_buffer buffer = {NULL, NULL};
246
247
4
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
248
4
            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
249
4
    if (!args) {
250
0
        goto exit;
251
0
    }
252
4
    if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) {
253
0
        _PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]);
254
0
        goto exit;
255
0
    }
256
4
    return_value = _io_FileIO_readinto_impl((fileio *)self, cls, &buffer);
257
258
4
exit:
259
    /* Cleanup for buffer */
260
4
    if (buffer.obj) {
261
4
       PyBuffer_Release(&buffer);
262
4
    }
263
264
4
    return return_value;
265
4
}
266
267
PyDoc_STRVAR(_io_FileIO_readall__doc__,
268
"readall($self, /)\n"
269
"--\n"
270
"\n"
271
"Read all data from the file, returned as bytes.\n"
272
"\n"
273
"Reads until either there is an error or read() returns size 0 (indicates EOF).\n"
274
"If the file is already at EOF, returns an empty bytes object.\n"
275
"\n"
276
"In non-blocking mode, returns as much data as could be read before EAGAIN. If no\n"
277
"data is available (EAGAIN is returned before bytes are read) returns None.");
278
279
#define _IO_FILEIO_READALL_METHODDEF    \
280
    {"readall", (PyCFunction)_io_FileIO_readall, METH_NOARGS, _io_FileIO_readall__doc__},
281
282
static PyObject *
283
_io_FileIO_readall_impl(fileio *self);
284
285
static PyObject *
286
_io_FileIO_readall(PyObject *self, PyObject *Py_UNUSED(ignored))
287
942
{
288
942
    return _io_FileIO_readall_impl((fileio *)self);
289
942
}
290
291
PyDoc_STRVAR(_io_FileIO_read__doc__,
292
"read($self, size=-1, /)\n"
293
"--\n"
294
"\n"
295
"Read at most size bytes, returned as bytes.\n"
296
"\n"
297
"If size is less than 0, read all bytes in the file making multiple read calls.\n"
298
"See ``FileIO.readall``.\n"
299
"\n"
300
"Attempts to make only one system call, retrying only per PEP 475 (EINTR). This\n"
301
"means less data may be returned than requested.\n"
302
"\n"
303
"In non-blocking mode, returns None if no data is available. Return an empty\n"
304
"bytes object at EOF.");
305
306
#define _IO_FILEIO_READ_METHODDEF    \
307
    {"read", _PyCFunction_CAST(_io_FileIO_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_read__doc__},
308
309
static PyObject *
310
_io_FileIO_read_impl(fileio *self, PyTypeObject *cls, Py_ssize_t size);
311
312
static PyObject *
313
_io_FileIO_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
314
0
{
315
0
    PyObject *return_value = NULL;
316
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
317
0
    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
318
    #else
319
    #  define KWTUPLE NULL
320
    #endif
321
322
0
    static const char * const _keywords[] = {"", NULL};
323
0
    static _PyArg_Parser _parser = {
324
0
        .keywords = _keywords,
325
0
        .fname = "read",
326
0
        .kwtuple = KWTUPLE,
327
0
    };
328
0
    #undef KWTUPLE
329
0
    PyObject *argsbuf[1];
330
0
    Py_ssize_t size = -1;
331
332
0
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
333
0
            /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
334
0
    if (!args) {
335
0
        goto exit;
336
0
    }
337
0
    if (nargs < 1) {
338
0
        goto skip_optional_posonly;
339
0
    }
340
0
    if (!_Py_convert_optional_to_ssize_t(args[0], &size)) {
341
0
        goto exit;
342
0
    }
343
0
skip_optional_posonly:
344
0
    return_value = _io_FileIO_read_impl((fileio *)self, cls, size);
345
346
0
exit:
347
0
    return return_value;
348
0
}
349
350
PyDoc_STRVAR(_io_FileIO_write__doc__,
351
"write($self, b, /)\n"
352
"--\n"
353
"\n"
354
"Write buffer b to file, return number of bytes written.\n"
355
"\n"
356
"Only makes one system call, so not all of the data may be written.\n"
357
"The number of bytes actually written is returned.  In non-blocking mode,\n"
358
"returns None if the write would block.");
359
360
#define _IO_FILEIO_WRITE_METHODDEF    \
361
    {"write", _PyCFunction_CAST(_io_FileIO_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_write__doc__},
362
363
static PyObject *
364
_io_FileIO_write_impl(fileio *self, PyTypeObject *cls, Py_buffer *b);
365
366
static PyObject *
367
_io_FileIO_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
368
216
{
369
216
    PyObject *return_value = NULL;
370
216
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
371
216
    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
372
    #else
373
    #  define KWTUPLE NULL
374
    #endif
375
376
216
    static const char * const _keywords[] = {"", NULL};
377
216
    static _PyArg_Parser _parser = {
378
216
        .keywords = _keywords,
379
216
        .fname = "write",
380
216
        .kwtuple = KWTUPLE,
381
216
    };
382
216
    #undef KWTUPLE
383
216
    PyObject *argsbuf[1];
384
216
    Py_buffer b = {NULL, NULL};
385
386
216
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
387
216
            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
388
216
    if (!args) {
389
0
        goto exit;
390
0
    }
391
216
    if (PyObject_GetBuffer(args[0], &b, PyBUF_SIMPLE) != 0) {
392
0
        goto exit;
393
0
    }
394
216
    return_value = _io_FileIO_write_impl((fileio *)self, cls, &b);
395
396
216
exit:
397
    /* Cleanup for b */
398
216
    if (b.obj) {
399
216
       PyBuffer_Release(&b);
400
216
    }
401
402
216
    return return_value;
403
216
}
404
405
PyDoc_STRVAR(_io_FileIO_seek__doc__,
406
"seek($self, pos, whence=0, /)\n"
407
"--\n"
408
"\n"
409
"Move to new file position and return the file position.\n"
410
"\n"
411
"Argument offset is a byte count.  Optional argument whence defaults to\n"
412
"SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values\n"
413
"are SEEK_CUR or 1 (move relative to current position, positive or negative),\n"
414
"and SEEK_END or 2 (move relative to end of file, usually negative, although\n"
415
"many platforms allow seeking beyond the end of a file).\n"
416
"\n"
417
"Note that not all file objects are seekable.");
418
419
#define _IO_FILEIO_SEEK_METHODDEF    \
420
    {"seek", _PyCFunction_CAST(_io_FileIO_seek), METH_FASTCALL, _io_FileIO_seek__doc__},
421
422
static PyObject *
423
_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence);
424
425
static PyObject *
426
_io_FileIO_seek(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
427
6
{
428
6
    PyObject *return_value = NULL;
429
6
    PyObject *pos;
430
6
    int whence = 0;
431
432
6
    if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) {
433
0
        goto exit;
434
0
    }
435
6
    pos = args[0];
436
6
    if (nargs < 2) {
437
0
        goto skip_optional;
438
0
    }
439
6
    whence = PyLong_AsInt(args[1]);
440
6
    if (whence == -1 && PyErr_Occurred()) {
441
0
        goto exit;
442
0
    }
443
6
skip_optional:
444
6
    return_value = _io_FileIO_seek_impl((fileio *)self, pos, whence);
445
446
6
exit:
447
6
    return return_value;
448
6
}
449
450
PyDoc_STRVAR(_io_FileIO_tell__doc__,
451
"tell($self, /)\n"
452
"--\n"
453
"\n"
454
"Current file position.\n"
455
"\n"
456
"Can raise OSError for non seekable files.");
457
458
#define _IO_FILEIO_TELL_METHODDEF    \
459
    {"tell", (PyCFunction)_io_FileIO_tell, METH_NOARGS, _io_FileIO_tell__doc__},
460
461
static PyObject *
462
_io_FileIO_tell_impl(fileio *self);
463
464
static PyObject *
465
_io_FileIO_tell(PyObject *self, PyObject *Py_UNUSED(ignored))
466
1.02k
{
467
1.02k
    return _io_FileIO_tell_impl((fileio *)self);
468
1.02k
}
469
470
#if defined(HAVE_FTRUNCATE)
471
472
PyDoc_STRVAR(_io_FileIO_truncate__doc__,
473
"truncate($self, size=None, /)\n"
474
"--\n"
475
"\n"
476
"Truncate the file to at most size bytes and return the truncated size.\n"
477
"\n"
478
"Size defaults to the current file position, as returned by tell().\n"
479
"The current file position is changed to the value of size.");
480
481
#define _IO_FILEIO_TRUNCATE_METHODDEF    \
482
    {"truncate", _PyCFunction_CAST(_io_FileIO_truncate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_truncate__doc__},
483
484
static PyObject *
485
_io_FileIO_truncate_impl(fileio *self, PyTypeObject *cls, PyObject *posobj);
486
487
static PyObject *
488
_io_FileIO_truncate(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
489
0
{
490
0
    PyObject *return_value = NULL;
491
0
    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
492
0
    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
493
    #else
494
    #  define KWTUPLE NULL
495
    #endif
496
497
0
    static const char * const _keywords[] = {"", NULL};
498
0
    static _PyArg_Parser _parser = {
499
0
        .keywords = _keywords,
500
0
        .fname = "truncate",
501
0
        .kwtuple = KWTUPLE,
502
0
    };
503
0
    #undef KWTUPLE
504
0
    PyObject *argsbuf[1];
505
0
    PyObject *posobj = Py_None;
506
507
0
    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
508
0
            /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
509
0
    if (!args) {
510
0
        goto exit;
511
0
    }
512
0
    if (nargs < 1) {
513
0
        goto skip_optional_posonly;
514
0
    }
515
0
    posobj = args[0];
516
0
skip_optional_posonly:
517
0
    return_value = _io_FileIO_truncate_impl((fileio *)self, cls, posobj);
518
519
0
exit:
520
0
    return return_value;
521
0
}
522
523
#endif /* defined(HAVE_FTRUNCATE) */
524
525
PyDoc_STRVAR(_io_FileIO_isatty__doc__,
526
"isatty($self, /)\n"
527
"--\n"
528
"\n"
529
"True if the file is connected to a TTY device.");
530
531
#define _IO_FILEIO_ISATTY_METHODDEF    \
532
    {"isatty", (PyCFunction)_io_FileIO_isatty, METH_NOARGS, _io_FileIO_isatty__doc__},
533
534
static PyObject *
535
_io_FileIO_isatty_impl(fileio *self);
536
537
static PyObject *
538
_io_FileIO_isatty(PyObject *self, PyObject *Py_UNUSED(ignored))
539
48
{
540
48
    return _io_FileIO_isatty_impl((fileio *)self);
541
48
}
542
543
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF
544
    #define _IO_FILEIO_TRUNCATE_METHODDEF
545
#endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */
546
/*[clinic end generated code: output=1902fac9e39358aa input=a9049054013a1b77]*/