/src/cpython/Modules/_io/clinic/_iomodule.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_modsupport.h" // _PyArg_UnpackKeywords() |
10 | | |
11 | | PyDoc_STRVAR(_io_open__doc__, |
12 | | "open($module, /, file, mode=\'r\', buffering=-1, encoding=None,\n" |
13 | | " errors=None, newline=None, closefd=True, opener=None)\n" |
14 | | "--\n" |
15 | | "\n" |
16 | | "Open file and return a stream. Raise OSError upon failure.\n" |
17 | | "\n" |
18 | | "file is either a text or byte string giving the name (and the path\n" |
19 | | "if the file isn\'t in the current working directory) of the file to\n" |
20 | | "be opened or an integer file descriptor of the file to be\n" |
21 | | "wrapped. (If a file descriptor is given, it is closed when the\n" |
22 | | "returned I/O object is closed, unless closefd is set to False.)\n" |
23 | | "\n" |
24 | | "mode is an optional string that specifies the mode in which the file\n" |
25 | | "is opened. It defaults to \'r\' which means open for reading in text\n" |
26 | | "mode. Other common values are \'w\' for writing (truncating the file if\n" |
27 | | "it already exists), \'x\' for creating and writing to a new file, and\n" |
28 | | "\'a\' for appending (which on some Unix systems, means that all writes\n" |
29 | | "append to the end of the file regardless of the current seek position).\n" |
30 | | "In text mode, if encoding is not specified the encoding used is platform\n" |
31 | | "dependent: locale.getencoding() is called to get the current locale encoding.\n" |
32 | | "(For reading and writing raw bytes use binary mode and leave encoding\n" |
33 | | "unspecified.) The available modes are:\n" |
34 | | "\n" |
35 | | "========= ===============================================================\n" |
36 | | "Character Meaning\n" |
37 | | "--------- ---------------------------------------------------------------\n" |
38 | | "\'r\' open for reading (default)\n" |
39 | | "\'w\' open for writing, truncating the file first\n" |
40 | | "\'x\' create a new file and open it for writing\n" |
41 | | "\'a\' open for writing, appending to the end of the file if it exists\n" |
42 | | "\'b\' binary mode\n" |
43 | | "\'t\' text mode (default)\n" |
44 | | "\'+\' open a disk file for updating (reading and writing)\n" |
45 | | "========= ===============================================================\n" |
46 | | "\n" |
47 | | "The default mode is \'rt\' (open for reading text). For binary random\n" |
48 | | "access, the mode \'w+b\' opens and truncates the file to 0 bytes, while\n" |
49 | | "\'r+b\' opens the file without truncation. The \'x\' mode implies \'w\' and\n" |
50 | | "raises an `FileExistsError` if the file already exists.\n" |
51 | | "\n" |
52 | | "Python distinguishes between files opened in binary and text modes,\n" |
53 | | "even when the underlying operating system doesn\'t. Files opened in\n" |
54 | | "binary mode (appending \'b\' to the mode argument) return contents as\n" |
55 | | "bytes objects without any decoding. In text mode (the default, or when\n" |
56 | | "\'t\' is appended to the mode argument), the contents of the file are\n" |
57 | | "returned as strings, the bytes having been first decoded using a\n" |
58 | | "platform-dependent encoding or using the specified encoding if given.\n" |
59 | | "\n" |
60 | | "buffering is an optional integer used to set the buffering policy.\n" |
61 | | "Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n" |
62 | | "line buffering (only usable in text mode), and an integer > 1 to indicate\n" |
63 | | "the size of a fixed-size chunk buffer. When no buffering argument is\n" |
64 | | "given, the default buffering policy works as follows:\n" |
65 | | "\n" |
66 | | "* Binary files are buffered in fixed-size chunks; the size of the buffer\n" |
67 | | " is max(min(blocksize, 8 MiB), DEFAULT_BUFFER_SIZE)\n" |
68 | | " when the device block size is available.\n" |
69 | | " On most systems, the buffer will typically be 128 kilobytes long.\n" |
70 | | "\n" |
71 | | "* \"Interactive\" text files (files for which isatty() returns True)\n" |
72 | | " use line buffering. Other text files use the policy described above\n" |
73 | | " for binary files.\n" |
74 | | "\n" |
75 | | "encoding is the name of the encoding used to decode or encode the\n" |
76 | | "file. This should only be used in text mode. The default encoding is\n" |
77 | | "platform dependent, but any encoding supported by Python can be\n" |
78 | | "passed. See the codecs module for the list of supported encodings.\n" |
79 | | "\n" |
80 | | "errors is an optional string that specifies how encoding errors are to\n" |
81 | | "be handled---this argument should not be used in binary mode. Pass\n" |
82 | | "\'strict\' to raise a ValueError exception if there is an encoding error\n" |
83 | | "(the default of None has the same effect), or pass \'ignore\' to ignore\n" |
84 | | "errors. (Note that ignoring encoding errors can lead to data loss.)\n" |
85 | | "See the documentation for codecs.register or run \'help(codecs.Codec)\'\n" |
86 | | "for a list of the permitted encoding error strings.\n" |
87 | | "\n" |
88 | | "newline controls how universal newlines works (it only applies to text\n" |
89 | | "mode). It can be None, \'\', \'\\n\', \'\\r\', and \'\\r\\n\'. It works as\n" |
90 | | "follows:\n" |
91 | | "\n" |
92 | | "* On input, if newline is None, universal newlines mode is\n" |
93 | | " enabled. Lines in the input can end in \'\\n\', \'\\r\', or \'\\r\\n\', and\n" |
94 | | " these are translated into \'\\n\' before being returned to the\n" |
95 | | " caller. If it is \'\', universal newline mode is enabled, but line\n" |
96 | | " endings are returned to the caller untranslated. If it has any of\n" |
97 | | " the other legal values, input lines are only terminated by the given\n" |
98 | | " string, and the line ending is returned to the caller untranslated.\n" |
99 | | "\n" |
100 | | "* On output, if newline is None, any \'\\n\' characters written are\n" |
101 | | " translated to the system default line separator, os.linesep. If\n" |
102 | | " newline is \'\' or \'\\n\', no translation takes place. If newline is any\n" |
103 | | " of the other legal values, any \'\\n\' characters written are translated\n" |
104 | | " to the given string.\n" |
105 | | "\n" |
106 | | "If closefd is False, the underlying file descriptor will be kept open\n" |
107 | | "when the file is closed. This does not work when a file name is given\n" |
108 | | "and must be True in that case.\n" |
109 | | "\n" |
110 | | "A custom opener can be used by passing a callable as *opener*. The\n" |
111 | | "underlying file descriptor for the file object is then obtained by\n" |
112 | | "calling *opener* with (*file*, *flags*). *opener* must return an open\n" |
113 | | "file descriptor (passing os.open as *opener* results in functionality\n" |
114 | | "similar to passing None).\n" |
115 | | "\n" |
116 | | "open() returns a file object whose type depends on the mode, and\n" |
117 | | "through which the standard file operations such as reading and writing\n" |
118 | | "are performed. When open() is used to open a file in a text mode (\'w\',\n" |
119 | | "\'r\', \'wt\', \'rt\', etc.), it returns a TextIOWrapper. When used to open\n" |
120 | | "a file in a binary mode, the returned class varies: in read binary\n" |
121 | | "mode, it returns a BufferedReader; in write binary and append binary\n" |
122 | | "modes, it returns a BufferedWriter, and in read/write mode, it returns\n" |
123 | | "a BufferedRandom.\n" |
124 | | "\n" |
125 | | "It is also possible to use a string or bytearray as a file for both\n" |
126 | | "reading and writing. For strings StringIO can be used like a file\n" |
127 | | "opened in a text mode, and for bytes a BytesIO can be used like a file\n" |
128 | | "opened in a binary mode."); |
129 | | |
130 | | #define _IO_OPEN_METHODDEF \ |
131 | | {"open", _PyCFunction_CAST(_io_open), METH_FASTCALL|METH_KEYWORDS, _io_open__doc__}, |
132 | | |
133 | | static PyObject * |
134 | | _io_open_impl(PyObject *module, PyObject *file, const char *mode, |
135 | | int buffering, const char *encoding, const char *errors, |
136 | | const char *newline, int closefd, PyObject *opener); |
137 | | |
138 | | static PyObject * |
139 | | _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) |
140 | 992 | { |
141 | 992 | PyObject *return_value = NULL; |
142 | 992 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
143 | | |
144 | 992 | #define NUM_KEYWORDS 8 |
145 | 992 | static struct { |
146 | 992 | PyGC_Head _this_is_not_used; |
147 | 992 | PyObject_VAR_HEAD |
148 | 992 | Py_hash_t ob_hash; |
149 | 992 | PyObject *ob_item[NUM_KEYWORDS]; |
150 | 992 | } _kwtuple = { |
151 | 992 | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
152 | 992 | .ob_hash = -1, |
153 | 992 | .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(buffering), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(closefd), &_Py_ID(opener), }, |
154 | 992 | }; |
155 | 992 | #undef NUM_KEYWORDS |
156 | 992 | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
157 | | |
158 | | #else // !Py_BUILD_CORE |
159 | | # define KWTUPLE NULL |
160 | | #endif // !Py_BUILD_CORE |
161 | | |
162 | 992 | static const char * const _keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; |
163 | 992 | static _PyArg_Parser _parser = { |
164 | 992 | .keywords = _keywords, |
165 | 992 | .fname = "open", |
166 | 992 | .kwtuple = KWTUPLE, |
167 | 992 | }; |
168 | 992 | #undef KWTUPLE |
169 | 992 | PyObject *argsbuf[8]; |
170 | 992 | Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; |
171 | 992 | PyObject *file; |
172 | 992 | const char *mode = "r"; |
173 | 992 | int buffering = -1; |
174 | 992 | const char *encoding = NULL; |
175 | 992 | const char *errors = NULL; |
176 | 992 | const char *newline = NULL; |
177 | 992 | int closefd = 1; |
178 | 992 | PyObject *opener = Py_None; |
179 | | |
180 | 992 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, |
181 | 992 | /*minpos*/ 1, /*maxpos*/ 8, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
182 | 992 | if (!args) { |
183 | 0 | goto exit; |
184 | 0 | } |
185 | 992 | file = args[0]; |
186 | 992 | if (!noptargs) { |
187 | 0 | goto skip_optional_pos; |
188 | 0 | } |
189 | 992 | if (args[1]) { |
190 | 992 | if (!PyUnicode_Check(args[1])) { |
191 | 0 | _PyArg_BadArgument("open", "argument 'mode'", "str", args[1]); |
192 | 0 | goto exit; |
193 | 0 | } |
194 | 992 | Py_ssize_t mode_length; |
195 | 992 | mode = PyUnicode_AsUTF8AndSize(args[1], &mode_length); |
196 | 992 | if (mode == NULL) { |
197 | 0 | goto exit; |
198 | 0 | } |
199 | 992 | if (strlen(mode) != (size_t)mode_length) { |
200 | 0 | PyErr_SetString(PyExc_ValueError, "embedded null character"); |
201 | 0 | goto exit; |
202 | 0 | } |
203 | 992 | if (!--noptargs) { |
204 | 944 | goto skip_optional_pos; |
205 | 944 | } |
206 | 992 | } |
207 | 48 | if (args[2]) { |
208 | 48 | buffering = PyLong_AsInt(args[2]); |
209 | 48 | if (buffering == -1 && PyErr_Occurred()) { |
210 | 0 | goto exit; |
211 | 0 | } |
212 | 48 | if (!--noptargs) { |
213 | 0 | goto skip_optional_pos; |
214 | 0 | } |
215 | 48 | } |
216 | 48 | if (args[3]) { |
217 | 48 | if (args[3] == Py_None) { |
218 | 48 | encoding = NULL; |
219 | 48 | } |
220 | 0 | else if (PyUnicode_Check(args[3])) { |
221 | 0 | Py_ssize_t encoding_length; |
222 | 0 | encoding = PyUnicode_AsUTF8AndSize(args[3], &encoding_length); |
223 | 0 | if (encoding == NULL) { |
224 | 0 | goto exit; |
225 | 0 | } |
226 | 0 | if (strlen(encoding) != (size_t)encoding_length) { |
227 | 0 | PyErr_SetString(PyExc_ValueError, "embedded null character"); |
228 | 0 | goto exit; |
229 | 0 | } |
230 | 0 | } |
231 | 0 | else { |
232 | 0 | _PyArg_BadArgument("open", "argument 'encoding'", "str or None", args[3]); |
233 | 0 | goto exit; |
234 | 0 | } |
235 | 48 | if (!--noptargs) { |
236 | 0 | goto skip_optional_pos; |
237 | 0 | } |
238 | 48 | } |
239 | 48 | if (args[4]) { |
240 | 48 | if (args[4] == Py_None) { |
241 | 48 | errors = NULL; |
242 | 48 | } |
243 | 0 | else if (PyUnicode_Check(args[4])) { |
244 | 0 | Py_ssize_t errors_length; |
245 | 0 | errors = PyUnicode_AsUTF8AndSize(args[4], &errors_length); |
246 | 0 | if (errors == NULL) { |
247 | 0 | goto exit; |
248 | 0 | } |
249 | 0 | if (strlen(errors) != (size_t)errors_length) { |
250 | 0 | PyErr_SetString(PyExc_ValueError, "embedded null character"); |
251 | 0 | goto exit; |
252 | 0 | } |
253 | 0 | } |
254 | 0 | else { |
255 | 0 | _PyArg_BadArgument("open", "argument 'errors'", "str or None", args[4]); |
256 | 0 | goto exit; |
257 | 0 | } |
258 | 48 | if (!--noptargs) { |
259 | 0 | goto skip_optional_pos; |
260 | 0 | } |
261 | 48 | } |
262 | 48 | if (args[5]) { |
263 | 48 | if (args[5] == Py_None) { |
264 | 48 | newline = NULL; |
265 | 48 | } |
266 | 0 | else if (PyUnicode_Check(args[5])) { |
267 | 0 | Py_ssize_t newline_length; |
268 | 0 | newline = PyUnicode_AsUTF8AndSize(args[5], &newline_length); |
269 | 0 | if (newline == NULL) { |
270 | 0 | goto exit; |
271 | 0 | } |
272 | 0 | if (strlen(newline) != (size_t)newline_length) { |
273 | 0 | PyErr_SetString(PyExc_ValueError, "embedded null character"); |
274 | 0 | goto exit; |
275 | 0 | } |
276 | 0 | } |
277 | 0 | else { |
278 | 0 | _PyArg_BadArgument("open", "argument 'newline'", "str or None", args[5]); |
279 | 0 | goto exit; |
280 | 0 | } |
281 | 48 | if (!--noptargs) { |
282 | 0 | goto skip_optional_pos; |
283 | 0 | } |
284 | 48 | } |
285 | 48 | if (args[6]) { |
286 | 48 | closefd = PyObject_IsTrue(args[6]); |
287 | 48 | if (closefd < 0) { |
288 | 0 | goto exit; |
289 | 0 | } |
290 | 48 | if (!--noptargs) { |
291 | 48 | goto skip_optional_pos; |
292 | 48 | } |
293 | 48 | } |
294 | 0 | opener = args[7]; |
295 | 992 | skip_optional_pos: |
296 | 992 | return_value = _io_open_impl(module, file, mode, buffering, encoding, errors, newline, closefd, opener); |
297 | | |
298 | 992 | exit: |
299 | 992 | return return_value; |
300 | 992 | } |
301 | | |
302 | | PyDoc_STRVAR(_io_text_encoding__doc__, |
303 | | "text_encoding($module, encoding, stacklevel=2, /)\n" |
304 | | "--\n" |
305 | | "\n" |
306 | | "A helper function to choose the text encoding.\n" |
307 | | "\n" |
308 | | "When encoding is not None, this function returns it.\n" |
309 | | "Otherwise, this function returns the default text encoding\n" |
310 | | "(i.e. \"locale\" or \"utf-8\" depends on UTF-8 mode).\n" |
311 | | "\n" |
312 | | "This function emits an EncodingWarning if encoding is None and\n" |
313 | | "sys.flags.warn_default_encoding is true.\n" |
314 | | "\n" |
315 | | "This can be used in APIs with an encoding=None parameter.\n" |
316 | | "However, please consider using encoding=\"utf-8\" for new APIs."); |
317 | | |
318 | | #define _IO_TEXT_ENCODING_METHODDEF \ |
319 | | {"text_encoding", _PyCFunction_CAST(_io_text_encoding), METH_FASTCALL, _io_text_encoding__doc__}, |
320 | | |
321 | | static PyObject * |
322 | | _io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel); |
323 | | |
324 | | static PyObject * |
325 | | _io_text_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs) |
326 | 0 | { |
327 | 0 | PyObject *return_value = NULL; |
328 | 0 | PyObject *encoding; |
329 | 0 | int stacklevel = 2; |
330 | |
|
331 | 0 | if (!_PyArg_CheckPositional("text_encoding", nargs, 1, 2)) { |
332 | 0 | goto exit; |
333 | 0 | } |
334 | 0 | encoding = args[0]; |
335 | 0 | if (nargs < 2) { |
336 | 0 | goto skip_optional; |
337 | 0 | } |
338 | 0 | stacklevel = PyLong_AsInt(args[1]); |
339 | 0 | if (stacklevel == -1 && PyErr_Occurred()) { |
340 | 0 | goto exit; |
341 | 0 | } |
342 | 0 | skip_optional: |
343 | 0 | return_value = _io_text_encoding_impl(module, encoding, stacklevel); |
344 | |
|
345 | 0 | exit: |
346 | 0 | return return_value; |
347 | 0 | } |
348 | | |
349 | | PyDoc_STRVAR(_io_open_code__doc__, |
350 | | "open_code($module, /, path)\n" |
351 | | "--\n" |
352 | | "\n" |
353 | | "Opens the provided file with the intent to import the contents.\n" |
354 | | "\n" |
355 | | "This may perform extra validation beyond open(), but is otherwise interchangeable\n" |
356 | | "with calling open(path, \'rb\')."); |
357 | | |
358 | | #define _IO_OPEN_CODE_METHODDEF \ |
359 | | {"open_code", _PyCFunction_CAST(_io_open_code), METH_FASTCALL|METH_KEYWORDS, _io_open_code__doc__}, |
360 | | |
361 | | static PyObject * |
362 | | _io_open_code_impl(PyObject *module, PyObject *path); |
363 | | |
364 | | static PyObject * |
365 | | _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) |
366 | 944 | { |
367 | 944 | PyObject *return_value = NULL; |
368 | 944 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
369 | | |
370 | 944 | #define NUM_KEYWORDS 1 |
371 | 944 | static struct { |
372 | 944 | PyGC_Head _this_is_not_used; |
373 | 944 | PyObject_VAR_HEAD |
374 | 944 | Py_hash_t ob_hash; |
375 | 944 | PyObject *ob_item[NUM_KEYWORDS]; |
376 | 944 | } _kwtuple = { |
377 | 944 | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
378 | 944 | .ob_hash = -1, |
379 | 944 | .ob_item = { &_Py_ID(path), }, |
380 | 944 | }; |
381 | 944 | #undef NUM_KEYWORDS |
382 | 944 | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
383 | | |
384 | | #else // !Py_BUILD_CORE |
385 | | # define KWTUPLE NULL |
386 | | #endif // !Py_BUILD_CORE |
387 | | |
388 | 944 | static const char * const _keywords[] = {"path", NULL}; |
389 | 944 | static _PyArg_Parser _parser = { |
390 | 944 | .keywords = _keywords, |
391 | 944 | .fname = "open_code", |
392 | 944 | .kwtuple = KWTUPLE, |
393 | 944 | }; |
394 | 944 | #undef KWTUPLE |
395 | 944 | PyObject *argsbuf[1]; |
396 | 944 | PyObject *path; |
397 | | |
398 | 944 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, |
399 | 944 | /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
400 | 944 | if (!args) { |
401 | 0 | goto exit; |
402 | 0 | } |
403 | 944 | if (!PyUnicode_Check(args[0])) { |
404 | 0 | _PyArg_BadArgument("open_code", "argument 'path'", "str", args[0]); |
405 | 0 | goto exit; |
406 | 0 | } |
407 | 944 | path = args[0]; |
408 | 944 | return_value = _io_open_code_impl(module, path); |
409 | | |
410 | 944 | exit: |
411 | 944 | return return_value; |
412 | 944 | } |
413 | | /*[clinic end generated code: output=7a8e032c0424bce2 input=a9049054013a1b77]*/ |