Coverage Report

Created: 2025-07-04 06:49

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