Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1290)

Side by Side Diff: Modules/_io/_iomodule.c

Issue 12760: Add create mode to open()
Patch Set: Created 1 year, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 An implementation of the new I/O lib as defined by PEP 3116 - "New I/O" 2 An implementation of the new I/O lib as defined by PEP 3116 - "New I/O"
3 3
4 Classes defined here: UnsupportedOperation, BlockingIOError. 4 Classes defined here: UnsupportedOperation, BlockingIOError.
5 Functions defined here: open(). 5 Functions defined here: open().
6 6
7 Mostly written by Amaury Forgeot d'Arc 7 Mostly written by Amaury Forgeot d'Arc
8 */ 8 */
9 9
10 #define PY_SSIZE_T_CLEAN 10 #define PY_SSIZE_T_CLEAN
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 "Open file and return a stream. Raise IOError upon failure.\n" 183 "Open file and return a stream. Raise IOError upon failure.\n"
184 "\n" 184 "\n"
185 "file is either a text or byte string giving the name (and the path\n" 185 "file is either a text or byte string giving the name (and the path\n"
186 "if the file isn't in the current working directory) of the file to\n" 186 "if the file isn't in the current working directory) of the file to\n"
187 "be opened or an integer file descriptor of the file to be\n" 187 "be opened or an integer file descriptor of the file to be\n"
188 "wrapped. (If a file descriptor is given, it is closed when the\n" 188 "wrapped. (If a file descriptor is given, it is closed when the\n"
189 "returned I/O object is closed, unless closefd is set to False.)\n" 189 "returned I/O object is closed, unless closefd is set to False.)\n"
190 "\n" 190 "\n"
191 "mode is an optional string that specifies the mode in which the file\n" 191 "mode is an optional string that specifies the mode in which the file\n"
192 "is opened. It defaults to 'r' which means open for reading in text\n" 192 "is opened. It defaults to 'r' which means open for reading in text\n"
193 "mode. Other common values are 'w' for writing (truncating the file if\n" 193 "mode. Other common values are 'x' for creating and writing to a new \n"
194 "file, 'w' for writing (truncating the file if\n"
194 "it already exists), and 'a' for appending (which on some Unix systems,\n" 195 "it already exists), and 'a' for appending (which on some Unix systems,\n"
195 "means that all writes append to the end of the file regardless of the\n" 196 "means that all writes append to the end of the file regardless of the\n"
196 "current seek position). In text mode, if encoding is not specified the\n" 197 "current seek position). In text mode, if encoding is not specified the\n"
197 "encoding used is platform dependent. (For reading and writing raw\n" 198 "encoding used is platform dependent. (For reading and writing raw\n"
198 "bytes use binary mode and leave encoding unspecified.) The available\n" 199 "bytes use binary mode and leave encoding unspecified.) The available\n"
199 "modes are:\n" 200 "modes are:\n"
200 "\n" 201 "\n"
201 "========= ===============================================================\n" 202 "========= ===============================================================\n"
202 "Character Meaning\n" 203 "Character Meaning\n"
203 "--------- ---------------------------------------------------------------\n" 204 "--------- ---------------------------------------------------------------\n"
204 "'r' open for reading (default)\n" 205 "'r' open for reading (default)\n"
206 "'x' create a new file and open it for writing\n"
205 "'w' open for writing, truncating the file first\n" 207 "'w' open for writing, truncating the file first\n"
206 "'a' open for writing, appending to the end of the file if it exists\n" 208 "'a' open for writing, appending to the end of the file if it exists\n"
207 "'b' binary mode\n" 209 "'b' binary mode\n"
208 "'t' text mode (default)\n" 210 "'t' text mode (default)\n"
209 "'+' open a disk file for updating (reading and writing)\n" 211 "'+' open a disk file for updating (reading and writing)\n"
210 "'U' universal newline mode (for backwards compatibility; unneeded\n" 212 "'U' universal newline mode (for backwards compatibility; unneeded\n"
211 " for new code)\n" 213 " for new code)\n"
212 "========= ===============================================================\n" 214 "========= ===============================================================\n"
213 "\n" 215 "\n"
214 "The default mode is 'rt' (open for reading text). For binary random\n" 216 "The default mode is 'rt' (open for reading text). For binary random\n"
215 "access, the mode 'w+b' opens and truncates the file to 0 bytes, while\n" 217 "access, the mode 'w+b' opens and truncates the file to 0 bytes, while\n"
216 "'r+b' opens the file without truncation.\n" 218 "'r+b' opens the file without truncation. The 'x' mode implies 'w' and\n"
219 "raises an `IOError` if the file already exists.\n"
Benjamin Peterson 2012/01/08 16:16:10 OSError.
217 "\n" 220 "\n"
218 "Python distinguishes between files opened in binary and text modes,\n" 221 "Python distinguishes between files opened in binary and text modes,\n"
219 "even when the underlying operating system doesn't. Files opened in\n" 222 "even when the underlying operating system doesn't. Files opened in\n"
220 "binary mode (appending 'b' to the mode argument) return contents as\n" 223 "binary mode (appending 'b' to the mode argument) return contents as\n"
221 "bytes objects without any decoding. In text mode (the default, or when\n" 224 "bytes objects without any decoding. In text mode (the default, or when\n"
222 "'t' is appended to the mode argument), the contents of the file are\n" 225 "'t' is appended to the mode argument), the contents of the file are\n"
223 "returned as strings, the bytes having been first decoded using a\n" 226 "returned as strings, the bytes having been first decoded using a\n"
224 "platform-dependent encoding or using the specified encoding if given.\n" 227 "platform-dependent encoding or using the specified encoding if given.\n"
225 "\n" 228 "\n"
226 "buffering is an optional integer used to set the buffering policy.\n" 229 "buffering is an optional integer used to set the buffering policy.\n"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 { 296 {
294 char *kwlist[] = {"file", "mode", "buffering", 297 char *kwlist[] = {"file", "mode", "buffering",
295 "encoding", "errors", "newline", 298 "encoding", "errors", "newline",
296 "closefd", NULL}; 299 "closefd", NULL};
297 PyObject *file; 300 PyObject *file;
298 char *mode = "r"; 301 char *mode = "r";
299 int buffering = -1, closefd = 1; 302 int buffering = -1, closefd = 1;
300 char *encoding = NULL, *errors = NULL, *newline = NULL; 303 char *encoding = NULL, *errors = NULL, *newline = NULL;
301 unsigned i; 304 unsigned i;
302 305
303 int reading = 0, writing = 0, appending = 0, updating = 0; 306 int creating = 0, reading = 0, writing = 0, appending = 0, updating = 0;
304 int text = 0, binary = 0, universal = 0; 307 int text = 0, binary = 0, universal = 0;
305 308
306 char rawmode[5], *m; 309 char rawmode[5], *m;
307 int line_buffering, isatty; 310 int line_buffering, isatty;
308 311
309 PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL; 312 PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL;
310 313
311 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzzi:open", kwlist, 314 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzzi:open", kwlist,
312 &file, &mode, &buffering, 315 &file, &mode, &buffering,
313 &encoding, &errors, &newline, 316 &encoding, &errors, &newline,
314 &closefd)) { 317 &closefd)) {
315 return NULL; 318 return NULL;
316 } 319 }
317 320
318 if (!PyUnicode_Check(file) && 321 if (!PyUnicode_Check(file) &&
319 !PyBytes_Check(file) && 322 !PyBytes_Check(file) &&
320 !PyNumber_Check(file)) { 323 !PyNumber_Check(file)) {
321 PyErr_Format(PyExc_TypeError, "invalid file: %R", file); 324 PyErr_Format(PyExc_TypeError, "invalid file: %R", file);
322 return NULL; 325 return NULL;
323 } 326 }
324 327
325 /* Decode mode */ 328 /* Decode mode */
326 for (i = 0; i < strlen(mode); i++) { 329 for (i = 0; i < strlen(mode); i++) {
327 char c = mode[i]; 330 char c = mode[i];
328 331
329 switch (c) { 332 switch (c) {
333 case 'x':
334 creating = 1;
335 break;
Charles-François Natali 2011/12/30 12:49:33 The indentation level odesn't match.
330 case 'r': 336 case 'r':
331 reading = 1; 337 reading = 1;
332 break; 338 break;
333 case 'w': 339 case 'w':
334 writing = 1; 340 writing = 1;
335 break; 341 break;
336 case 'a': 342 case 'a':
337 appending = 1; 343 appending = 1;
338 break; 344 break;
339 case '+': 345 case '+':
(...skipping 16 matching lines...) Expand all
356 /* c must not be duplicated */ 362 /* c must not be duplicated */
357 if (strchr(mode+i+1, c)) { 363 if (strchr(mode+i+1, c)) {
358 invalid_mode: 364 invalid_mode:
359 PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode); 365 PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode);
360 return NULL; 366 return NULL;
361 } 367 }
362 368
363 } 369 }
364 370
365 m = rawmode; 371 m = rawmode;
372 if (creating) *(m++) = 'x';
366 if (reading) *(m++) = 'r'; 373 if (reading) *(m++) = 'r';
367 if (writing) *(m++) = 'w'; 374 if (writing) *(m++) = 'w';
368 if (appending) *(m++) = 'a'; 375 if (appending) *(m++) = 'a';
369 if (updating) *(m++) = '+'; 376 if (updating) *(m++) = '+';
370 *m = '\0'; 377 *m = '\0';
371 378
372 /* Parameters validation */ 379 /* Parameters validation */
373 if (universal) { 380 if (universal) {
374 if (writing || appending) { 381 if (writing || appending) {
375 PyErr_SetString(PyExc_ValueError, 382 PyErr_SetString(PyExc_ValueError,
376 "can't use U and writing mode at once"); 383 "can't use U and writing mode at once");
377 return NULL; 384 return NULL;
378 } 385 }
379 reading = 1; 386 reading = 1;
380 } 387 }
381 388
382 if (text && binary) { 389 if (text && binary) {
383 PyErr_SetString(PyExc_ValueError, 390 PyErr_SetString(PyExc_ValueError,
384 "can't have text and binary mode at once"); 391 "can't have text and binary mode at once");
385 return NULL; 392 return NULL;
386 } 393 }
387 394
388 if (reading + writing + appending > 1) { 395 if (creating + reading + writing + appending > 1) {
389 PyErr_SetString(PyExc_ValueError, 396 PyErr_SetString(PyExc_ValueError,
390 "must have exactly one of read/write/append mode"); 397 "must have exactly one of create/read/write/append mode" );
391 return NULL; 398 return NULL;
392 } 399 }
393 400
394 if (binary && encoding != NULL) { 401 if (binary && encoding != NULL) {
395 PyErr_SetString(PyExc_ValueError, 402 PyErr_SetString(PyExc_ValueError,
396 "binary mode doesn't take an encoding argument"); 403 "binary mode doesn't take an encoding argument");
397 return NULL; 404 return NULL;
398 } 405 }
399 406
400 if (binary && errors != NULL) { 407 if (binary && errors != NULL) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 Py_DECREF(modeobj); 481 Py_DECREF(modeobj);
475 return raw; 482 return raw;
476 } 483 }
477 484
478 /* wraps into a buffered file */ 485 /* wraps into a buffered file */
479 { 486 {
480 PyObject *Buffered_class; 487 PyObject *Buffered_class;
481 488
482 if (updating) 489 if (updating)
483 Buffered_class = (PyObject *)&PyBufferedRandom_Type; 490 Buffered_class = (PyObject *)&PyBufferedRandom_Type;
484 else if (writing || appending) 491 else if (creating || writing || appending)
485 Buffered_class = (PyObject *)&PyBufferedWriter_Type; 492 Buffered_class = (PyObject *)&PyBufferedWriter_Type;
486 else if (reading) 493 else if (reading)
487 Buffered_class = (PyObject *)&PyBufferedReader_Type; 494 Buffered_class = (PyObject *)&PyBufferedReader_Type;
488 else { 495 else {
489 PyErr_Format(PyExc_ValueError, 496 PyErr_Format(PyExc_ValueError,
490 "unknown mode: '%s'", mode); 497 "unknown mode: '%s'", mode);
491 goto error; 498 goto error;
492 } 499 }
493 500
494 buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering); 501 buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering);
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 state->initialized = 1; 808 state->initialized = 1;
802 809
803 return m; 810 return m;
804 811
805 fail: 812 fail:
806 Py_XDECREF(state->os_module); 813 Py_XDECREF(state->os_module);
807 Py_XDECREF(state->unsupported_operation); 814 Py_XDECREF(state->unsupported_operation);
808 Py_DECREF(m); 815 Py_DECREF(m);
809 return NULL; 816 return NULL;
810 } 817 }
OLDNEW

RSS Feeds Recent Issues | This issue
This is Rietveld cbc36f91f3f7