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