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