Coverage Report

Created: 2026-10-17 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Modules/_io/_iomodule.h
Line
Count
Source
1
/*
2
 * Declarations shared between the different parts of the io module
3
 */
4
5
#include "exports.h"
6
7
#include "pycore_fileutils.h"     // Py_off_t
8
#include "pycore_moduleobject.h"  // _PyModule_GetState()
9
#include "pycore_typeobject.h"    // _PyType_GetModuleState()
10
#include "structmember.h"
11
12
/* Type specs */
13
extern PyType_Spec _Py_bufferediobase_spec;
14
extern PyType_Spec _Py_bufferedrandom_spec;
15
extern PyType_Spec _Py_bufferedreader_spec;
16
extern PyType_Spec _Py_bufferedrwpair_spec;
17
extern PyType_Spec _Py_bufferedwriter_spec;
18
extern PyType_Spec _Py_bytesio_spec;
19
extern PyType_Spec _Py_bytesiobuf_spec;
20
extern PyType_Spec _Py_fileio_spec;
21
extern PyType_Spec _Py_iobase_spec;
22
extern PyType_Spec _Py_nldecoder_spec;
23
extern PyType_Spec _Py_rawiobase_spec;
24
extern PyType_Spec _Py_stringio_spec;
25
extern PyType_Spec _Py_textiobase_spec;
26
extern PyType_Spec _Py_textiowrapper_spec;
27
28
#ifdef HAVE_WINDOWS_CONSOLE_IO
29
extern PyType_Spec _Py_winconsoleio_spec;
30
#endif
31
32
/* These functions are used as METH_NOARGS methods, are normally called
33
 * with args=NULL, and return a new reference.
34
 * BUT when args=Py_True is passed, they return a borrowed reference.
35
 */
36
typedef struct _io_state _PyIO_State;  // Forward decl.
37
extern PyObject* _PyIOBase_check_readable(_PyIO_State *state,
38
                                          PyObject *self, PyObject *args);
39
extern PyObject* _PyIOBase_check_writable(_PyIO_State *state,
40
                                          PyObject *self, PyObject *args);
41
extern PyObject* _PyIOBase_check_seekable(_PyIO_State *state,
42
                                          PyObject *self, PyObject *args);
43
extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args);
44
45
/* Helper for finalization.
46
   This function will revive an object ready to be deallocated and try to
47
   close() it. It returns 0 if the object can be destroyed, or -1 if it
48
   is alive again. */
49
extern int _PyIOBase_finalize(PyObject *self);
50
51
/* Returns true if the given FileIO object is closed.
52
   Doesn't check the argument type, so be careful! */
53
extern int _PyFileIO_closed(PyObject *self);
54
55
/* Shortcut to the core of the IncrementalNewlineDecoder.decode method */
56
extern PyObject *_PyIncrementalNewlineDecoder_decode(
57
    PyObject *self, PyObject *input, int final);
58
59
/* Finds the first line ending between `start` and `end`.
60
   If found, returns the index after the line ending and doesn't touch
61
   `*consumed`.
62
   If not found, returns -1 and sets `*consumed` to the number of characters
63
   which can be safely put aside until another search.
64
65
   NOTE: for performance reasons, `end` must point to a NUL character ('\0').
66
   Otherwise, the function will scan further and return garbage.
67
68
   There are three modes, in order of priority:
69
   * translated: Only find \n (assume newlines already translated)
70
   * universal: Use universal newlines algorithm
71
   * Otherwise, the line ending is specified by readnl, a str object */
72
extern Py_ssize_t _PyIO_find_line_ending(
73
    int translated, int universal, PyObject *readnl,
74
    int kind, const char *start, const char *end, Py_ssize_t *consumed);
75
76
/* Return 1 if an OSError with errno == EINTR is set (and then
77
   clears the error indicator), 0 otherwise.
78
   Should only be called when PyErr_Occurred() is true.
79
*/
80
extern int _PyIO_trap_eintr(void);
81
82
29.5k
#define DEFAULT_BUFFER_SIZE (128 * 1024)  /* bytes */
83
84
/*
85
 * Offset type for positioning.
86
 */
87
88
/* Printing a variable of type off_t (with e.g., PyUnicode_FromFormat)
89
   correctly and without producing compiler warnings is surprisingly painful.
90
   We identify an integer type whose size matches off_t and then: (1) cast the
91
   off_t to that integer type and (2) use the appropriate conversion
92
   specification.  The cast is necessary: gcc complains about formatting a
93
   long with "%lld" even when both long and long long have the same
94
   precision. */
95
96
#ifdef MS_WINDOWS
97
98
# define PyLong_AsOff_t     PyLong_AsLongLong
99
# define PyLong_FromOff_t   PyLong_FromLongLong
100
# define PY_OFF_T_MAX       LLONG_MAX
101
# define PY_OFF_T_MIN       LLONG_MIN
102
# define PY_OFF_T_COMPAT    long long    /* type compatible with off_t */
103
# define PY_PRIdOFF         "lld"        /* format to use for that type */
104
105
#else
106
107
/* Other platforms use off_t */
108
#if (SIZEOF_OFF_T == SIZEOF_SIZE_T)
109
1.41M
# define PyLong_AsOff_t     PyLong_AsSsize_t
110
1.38M
# define PyLong_FromOff_t   PyLong_FromSsize_t
111
0
# define PY_OFF_T_MAX       PY_SSIZE_T_MAX
112
0
# define PY_OFF_T_MIN       PY_SSIZE_T_MIN
113
# define PY_OFF_T_COMPAT    Py_ssize_t
114
0
# define PY_PRIdOFF         "zd"
115
#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG)
116
# define PyLong_AsOff_t     PyLong_AsLongLong
117
# define PyLong_FromOff_t   PyLong_FromLongLong
118
# define PY_OFF_T_MAX       LLONG_MAX
119
# define PY_OFF_T_MIN       LLONG_MIN
120
# define PY_OFF_T_COMPAT    long long
121
# define PY_PRIdOFF         "lld"
122
#elif (SIZEOF_OFF_T == SIZEOF_LONG)
123
# define PyLong_AsOff_t     PyLong_AsLong
124
# define PyLong_FromOff_t   PyLong_FromLong
125
# define PY_OFF_T_MAX       LONG_MAX
126
# define PY_OFF_T_MIN       LONG_MIN
127
# define PY_OFF_T_COMPAT    long
128
# define PY_PRIdOFF         "ld"
129
#else
130
# error off_t does not match either size_t, long, or long long!
131
#endif
132
133
#endif
134
135
extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err);
136
137
/* Implementation details */
138
139
/* IO module structure */
140
141
extern PyModuleDef _PyIO_Module;
142
143
struct _io_state {
144
    int initialized;
145
    PyObject *unsupported_operation;
146
147
    /* Types */
148
    PyTypeObject *PyIOBase_Type;
149
    PyTypeObject *PyIncrementalNewlineDecoder_Type;
150
    PyTypeObject *PyRawIOBase_Type;
151
    PyTypeObject *PyBufferedIOBase_Type;
152
    PyTypeObject *PyBufferedRWPair_Type;
153
    PyTypeObject *PyBufferedRandom_Type;
154
    PyTypeObject *PyBufferedReader_Type;
155
    PyTypeObject *PyBufferedWriter_Type;
156
    PyTypeObject *PyBytesIOBuffer_Type;
157
    PyTypeObject *PyBytesIO_Type;
158
    PyTypeObject *PyFileIO_Type;
159
    PyTypeObject *PyStringIO_Type;
160
    PyTypeObject *PyTextIOBase_Type;
161
    PyTypeObject *PyTextIOWrapper_Type;
162
#ifdef HAVE_WINDOWS_CONSOLE_IO
163
    PyTypeObject *PyWindowsConsoleIO_Type;
164
#endif
165
};
166
167
static inline _PyIO_State *
168
get_io_state(PyObject *module)
169
1.46M
{
170
1.46M
    void *state = _PyModule_GetState(module);
171
1.46M
    assert(state != NULL);
172
1.46M
    return (_PyIO_State *)state;
173
1.46M
}
_iomodule.c:get_io_state
Line
Count
Source
169
26.3k
{
170
26.3k
    void *state = _PyModule_GetState(module);
171
    assert(state != NULL);
172
26.3k
    return (_PyIO_State *)state;
173
26.3k
}
Unexecuted instantiation: iobase.c:get_io_state
Unexecuted instantiation: fileio.c:get_io_state
Unexecuted instantiation: bytesio.c:get_io_state
bufferedio.c:get_io_state
Line
Count
Source
169
1.40M
{
170
1.40M
    void *state = _PyModule_GetState(module);
171
    assert(state != NULL);
172
1.40M
    return (_PyIO_State *)state;
173
1.40M
}
textio.c:get_io_state
Line
Count
Source
169
130
{
170
130
    void *state = _PyModule_GetState(module);
171
    assert(state != NULL);
172
130
    return (_PyIO_State *)state;
173
130
}
stringio.c:get_io_state
Line
Count
Source
169
37.7k
{
170
37.7k
    void *state = _PyModule_GetState(module);
171
    assert(state != NULL);
172
37.7k
    return (_PyIO_State *)state;
173
37.7k
}
174
175
static inline _PyIO_State *
176
get_io_state_by_cls(PyTypeObject *cls)
177
24.5k
{
178
24.5k
    void *state = _PyType_GetModuleState(cls);
179
24.5k
    assert(state != NULL);
180
24.5k
    return (_PyIO_State *)state;
181
24.5k
}
Unexecuted instantiation: _iomodule.c:get_io_state_by_cls
iobase.c:get_io_state_by_cls
Line
Count
Source
177
5
{
178
5
    void *state = _PyType_GetModuleState(cls);
179
    assert(state != NULL);
180
5
    return (_PyIO_State *)state;
181
5
}
fileio.c:get_io_state_by_cls
Line
Count
Source
177
24.5k
{
178
24.5k
    void *state = _PyType_GetModuleState(cls);
179
    assert(state != NULL);
180
24.5k
    return (_PyIO_State *)state;
181
24.5k
}
Unexecuted instantiation: bytesio.c:get_io_state_by_cls
Unexecuted instantiation: bufferedio.c:get_io_state_by_cls
Unexecuted instantiation: textio.c:get_io_state_by_cls
Unexecuted instantiation: stringio.c:get_io_state_by_cls
182
183
static inline _PyIO_State *
184
find_io_state_by_def(PyTypeObject *type)
185
1.43M
{
186
1.43M
    PyObject *mod = PyType_GetModuleByDef(type, &_PyIO_Module);
187
    assert(mod != NULL);
188
1.43M
    return get_io_state(mod);
189
1.43M
}
Unexecuted instantiation: _iomodule.c:find_io_state_by_def
Unexecuted instantiation: iobase.c:find_io_state_by_def
Unexecuted instantiation: fileio.c:find_io_state_by_def
Unexecuted instantiation: bytesio.c:find_io_state_by_def
bufferedio.c:find_io_state_by_def
Line
Count
Source
185
1.40M
{
186
1.40M
    PyObject *mod = PyType_GetModuleByDef(type, &_PyIO_Module);
187
    assert(mod != NULL);
188
1.40M
    return get_io_state(mod);
189
1.40M
}
textio.c:find_io_state_by_def
Line
Count
Source
185
130
{
186
130
    PyObject *mod = PyType_GetModuleByDef(type, &_PyIO_Module);
187
    assert(mod != NULL);
188
130
    return get_io_state(mod);
189
130
}
stringio.c:find_io_state_by_def
Line
Count
Source
185
37.7k
{
186
37.7k
    PyObject *mod = PyType_GetModuleByDef(type, &_PyIO_Module);
187
    assert(mod != NULL);
188
37.7k
    return get_io_state(mod);
189
37.7k
}
190
191
extern PyObject *_PyIOBase_cannot_pickle(PyObject *self, PyObject *args);
192
193
#ifdef HAVE_WINDOWS_CONSOLE_IO
194
extern char _PyIO_get_console_type(PyObject *);
195
#endif