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

Side by Side Diff: Modules/_io/fileio.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
« Modules/_io/_iomodule.c ('K') | « Modules/_io/_iomodule.c ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Author: Daniel Stutzbach */ 1 /* Author: Daniel Stutzbach */
2 2
3 #define PY_SSIZE_T_CLEAN 3 #define PY_SSIZE_T_CLEAN
4 #include "Python.h" 4 #include "Python.h"
5 #include "structmember.h" 5 #include "structmember.h"
6 #ifdef HAVE_SYS_TYPES_H 6 #ifdef HAVE_SYS_TYPES_H
7 #include <sys/types.h> 7 #include <sys/types.h>
8 #endif 8 #endif
9 #ifdef HAVE_SYS_STAT_H 9 #ifdef HAVE_SYS_STAT_H
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 45
46 #if SIZEOF_INT < 4 46 #if SIZEOF_INT < 4
47 #define BIGCHUNK (512 * 32) 47 #define BIGCHUNK (512 * 32)
48 #else 48 #else
49 #define BIGCHUNK (512 * 1024) 49 #define BIGCHUNK (512 * 1024)
50 #endif 50 #endif
51 51
52 typedef struct { 52 typedef struct {
53 PyObject_HEAD 53 PyObject_HEAD
54 int fd; 54 int fd;
55 unsigned int created : 1;
55 unsigned int readable : 1; 56 unsigned int readable : 1;
56 unsigned int writable : 1; 57 unsigned int writable : 1;
57 signed int seekable : 2; /* -1 means unknown */ 58 signed int seekable : 2; /* -1 means unknown */
58 unsigned int closefd : 1; 59 unsigned int closefd : 1;
59 unsigned int deallocating: 1; 60 unsigned int deallocating: 1;
60 PyObject *weakreflist; 61 PyObject *weakreflist;
61 PyObject *dict; 62 PyObject *dict;
62 } fileio; 63 } fileio;
63 64
64 PyTypeObject PyFileIO_Type; 65 PyTypeObject PyFileIO_Type;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 static PyObject * 151 static PyObject *
151 fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 152 fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
152 { 153 {
153 fileio *self; 154 fileio *self;
154 155
155 assert(type != NULL && type->tp_alloc != NULL); 156 assert(type != NULL && type->tp_alloc != NULL);
156 157
157 self = (fileio *) type->tp_alloc(type, 0); 158 self = (fileio *) type->tp_alloc(type, 0);
158 if (self != NULL) { 159 if (self != NULL) {
159 self->fd = -1; 160 self->fd = -1;
161 self->created = 0;
160 self->readable = 0; 162 self->readable = 0;
161 self->writable = 0; 163 self->writable = 0;
162 self->seekable = -1; 164 self->seekable = -1;
163 self->closefd = 1; 165 self->closefd = 1;
164 self->weakreflist = NULL; 166 self->weakreflist = NULL;
165 } 167 }
166 168
167 return (PyObject *) self; 169 return (PyObject *) self;
168 } 170 }
169 171
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 "encoder failed to return bytes"); 287 "encoder failed to return bytes");
286 goto error; 288 goto error;
287 } 289 }
288 name = PyBytes_AS_STRING(stringobj); 290 name = PyBytes_AS_STRING(stringobj);
289 } 291 }
290 } 292 }
291 293
292 s = mode; 294 s = mode;
293 while (*s) { 295 while (*s) {
294 switch (*s++) { 296 switch (*s++) {
295 case 'r': 297 case 'x':
296 if (rwa) { 298 if (rwa) {
297 bad_mode: 299 bad_mode:
298 PyErr_SetString(PyExc_ValueError, 300 PyErr_SetString(PyExc_ValueError,
299 "Must have exactly one of read/write/append " 301 "Must have exactly one of create/read/write/appe nd "
300 "mode and at most one plus"); 302 "mode and at most one plus");
301 goto error; 303 goto error;
302 } 304 }
303 rwa = 1; 305 rwa = 1;
306 self->created = 1;
307 self->writable = 1;
308 flags |= O_EXCL | O_CREAT;
Benjamin Peterson 2012/01/08 16:16:10 Strange indentation again.
309 break;
310 case 'r':
311 if (rwa)
312 goto bad_mode;
313 rwa = 1;
304 self->readable = 1; 314 self->readable = 1;
305 break; 315 break;
306 case 'w': 316 case 'w':
307 if (rwa) 317 if (rwa)
308 goto bad_mode; 318 goto bad_mode;
309 rwa = 1; 319 rwa = 1;
310 self->writable = 1; 320 self->writable = 1;
311 flags |= O_CREAT | O_TRUNC; 321 flags |= O_CREAT | O_TRUNC;
312 break; 322 break;
313 case 'a': 323 case 'a':
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 "File not open for %s", action); 474 "File not open for %s", action);
465 return NULL; 475 return NULL;
466 } 476 }
467 477
468 static PyObject * 478 static PyObject *
469 fileio_fileno(fileio *self) 479 fileio_fileno(fileio *self)
470 { 480 {
471 if (self->fd < 0) 481 if (self->fd < 0)
472 return err_closed(); 482 return err_closed();
473 return PyLong_FromLong((long) self->fd); 483 return PyLong_FromLong((long) self->fd);
484 }
485
486 static PyObject *
487 fileio_created(fileio *self)
488 {
489 if (self->fd < 0)
490 return err_closed();
491 return PyBool_FromLong((long) self->created);
474 } 492 }
475 493
476 static PyObject * 494 static PyObject *
477 fileio_readable(fileio *self) 495 fileio_readable(fileio *self)
478 { 496 {
479 if (self->fd < 0) 497 if (self->fd < 0)
480 return err_closed(); 498 return err_closed();
481 return PyBool_FromLong((long) self->readable); 499 return PyBool_FromLong((long) self->readable);
482 } 500 }
483 501
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 return NULL; 974 return NULL;
957 } 975 }
958 976
959 return posobj; 977 return posobj;
960 } 978 }
961 #endif /* HAVE_FTRUNCATE */ 979 #endif /* HAVE_FTRUNCATE */
962 980
963 static char * 981 static char *
964 mode_string(fileio *self) 982 mode_string(fileio *self)
965 { 983 {
984 if (self->created) {
Charles-François Natali 2011/12/30 12:49:33 Indentation.
985 if (self->readable)
986 return "xb+";
987 else
988 return "xb";
989 }
966 if (self->readable) { 990 if (self->readable) {
967 if (self->writable) 991 if (self->writable)
968 return "rb+"; 992 return "rb+";
969 else 993 else
970 return "rb"; 994 return "rb";
971 } 995 }
972 else 996 else
973 return "wb"; 997 return "wb";
974 } 998 }
975 999
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 { 1040 {
1017 PyErr_Format(PyExc_TypeError, 1041 PyErr_Format(PyExc_TypeError,
1018 "cannot serialize '%s' object", Py_TYPE(self)->tp_name); 1042 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
1019 return NULL; 1043 return NULL;
1020 } 1044 }
1021 1045
1022 1046
1023 PyDoc_STRVAR(fileio_doc, 1047 PyDoc_STRVAR(fileio_doc,
1024 "file(name: str[, mode: str]) -> file IO object\n" 1048 "file(name: str[, mode: str]) -> file IO object\n"
1025 "\n" 1049 "\n"
1026 "Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n" 1050 "Open a file. The mode can be 'x', 'r', 'w' or 'a' for creating,\n"
1027 "writing or appending. The file will be created if it doesn't exist\n" 1051 "reading (default), writing or appending. The file will be created\n"
1028 "when opened for writing or appending; it will be truncated when\n" 1052 "if it doesn't exist when opened for writing or appending; it will be\n"
1029 "opened for writing. Add a '+' to the mode to allow simultaneous\n" 1053 "truncated when opened for writing. An IOError will be raise if it\n"
Benjamin Peterson 2012/01/08 16:16:10 OSError.
1030 "reading and writing."); 1054 "already exists when opened for creating. Opening a file for creating\n"
1055 "implies writing, so this mode behaves in a similar way to 'w'. Add a\n"
1056 "'+' to the mode to allow simultaneous reading and writing.");
1031 1057
1032 PyDoc_STRVAR(read_doc, 1058 PyDoc_STRVAR(read_doc,
1033 "read(size: int) -> bytes. read at most size bytes, returned as bytes.\n" 1059 "read(size: int) -> bytes. read at most size bytes, returned as bytes.\n"
1034 "\n" 1060 "\n"
1035 "Only makes one system call, so less data may be returned than requested\n" 1061 "Only makes one system call, so less data may be returned than requested\n"
1036 "In non-blocking mode, returns None if no data is available.\n" 1062 "In non-blocking mode, returns None if no data is available.\n"
1037 "On end-of-file, returns ''."); 1063 "On end-of-file, returns ''.");
1038 1064
1039 PyDoc_STRVAR(readall_doc, 1065 PyDoc_STRVAR(readall_doc,
1040 "readall() -> bytes. read all data from the file, returned as bytes.\n" 1066 "readall() -> bytes. read all data from the file, returned as bytes.\n"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 "close() -> None. Close the file.\n" 1108 "close() -> None. Close the file.\n"
1083 "\n" 1109 "\n"
1084 "A closed file cannot be used for further I/O operations. close() may be\n" 1110 "A closed file cannot be used for further I/O operations. close() may be\n"
1085 "called more than once without error. Changes the fileno to -1."); 1111 "called more than once without error. Changes the fileno to -1.");
1086 1112
1087 PyDoc_STRVAR(isatty_doc, 1113 PyDoc_STRVAR(isatty_doc,
1088 "isatty() -> bool. True if the file is connected to a tty device."); 1114 "isatty() -> bool. True if the file is connected to a tty device.");
1089 1115
1090 PyDoc_STRVAR(seekable_doc, 1116 PyDoc_STRVAR(seekable_doc,
1091 "seekable() -> bool. True if file supports random-access."); 1117 "seekable() -> bool. True if file supports random-access.");
1118
1119 PyDoc_STRVAR(created_doc,
1120 "created() -> bool. True if file was newly created when opened with 'x' mode");
Charles-François Natali 2011/12/30 12:49:33 Nit: missing space.
1092 1121
1093 PyDoc_STRVAR(readable_doc, 1122 PyDoc_STRVAR(readable_doc,
1094 "readable() -> bool. True if file was opened in a read mode."); 1123 "readable() -> bool. True if file was opened in a read mode.");
1095 1124
1096 PyDoc_STRVAR(writable_doc, 1125 PyDoc_STRVAR(writable_doc,
1097 "writable() -> bool. True if file was opened in a write mode."); 1126 "writable() -> bool. True if file was opened in a write mode.");
1098 1127
1099 static PyMethodDef fileio_methods[] = { 1128 static PyMethodDef fileio_methods[] = {
1100 {"read", (PyCFunction)fileio_read, METH_VARARGS, read_doc}, 1129 {"read", (PyCFunction)fileio_read, METH_VARARGS, read_doc},
1101 {"readall", (PyCFunction)fileio_readall, METH_NOARGS, readall_doc}, 1130 {"readall", (PyCFunction)fileio_readall, METH_NOARGS, readall_doc},
1102 {"readinto", (PyCFunction)fileio_readinto, METH_VARARGS, readinto_doc}, 1131 {"readinto", (PyCFunction)fileio_readinto, METH_VARARGS, readinto_doc},
1103 {"write", (PyCFunction)fileio_write, METH_VARARGS, write_doc}, 1132 {"write", (PyCFunction)fileio_write, METH_VARARGS, write_doc},
1104 {"seek", (PyCFunction)fileio_seek, METH_VARARGS, seek_doc}, 1133 {"seek", (PyCFunction)fileio_seek, METH_VARARGS, seek_doc},
1105 {"tell", (PyCFunction)fileio_tell, METH_VARARGS, tell_doc}, 1134 {"tell", (PyCFunction)fileio_tell, METH_VARARGS, tell_doc},
1106 #ifdef HAVE_FTRUNCATE 1135 #ifdef HAVE_FTRUNCATE
1107 {"truncate", (PyCFunction)fileio_truncate, METH_VARARGS, truncate_doc}, 1136 {"truncate", (PyCFunction)fileio_truncate, METH_VARARGS, truncate_doc},
1108 #endif 1137 #endif
1109 {"close", (PyCFunction)fileio_close, METH_NOARGS, close_doc}, 1138 {"close", (PyCFunction)fileio_close, METH_NOARGS, close_doc},
1110 {"seekable", (PyCFunction)fileio_seekable, METH_NOARGS, seekable_doc}, 1139 {"seekable", (PyCFunction)fileio_seekable, METH_NOARGS, seekable_doc},
1140 {"created", (PyCFunction)fileio_created, METH_NOARGS, created_doc},
1111 {"readable", (PyCFunction)fileio_readable, METH_NOARGS, readable_doc}, 1141 {"readable", (PyCFunction)fileio_readable, METH_NOARGS, readable_doc},
1112 {"writable", (PyCFunction)fileio_writable, METH_NOARGS, writable_doc}, 1142 {"writable", (PyCFunction)fileio_writable, METH_NOARGS, writable_doc},
1113 {"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc}, 1143 {"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc},
1114 {"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc}, 1144 {"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc},
1115 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL}, 1145 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
1116 {"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL}, 1146 {"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL},
1117 {NULL, NULL} /* sentinel */ 1147 {NULL, NULL} /* sentinel */
1118 }; 1148 };
1119 1149
1120 /* 'closed' and 'mode' are attributes for backwards compatibility reasons. */ 1150 /* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 0, /* tp_base */ 1210 0, /* tp_base */
1181 0, /* tp_dict */ 1211 0, /* tp_dict */
1182 0, /* tp_descr_get */ 1212 0, /* tp_descr_get */
1183 0, /* tp_descr_set */ 1213 0, /* tp_descr_set */
1184 offsetof(fileio, dict), /* tp_dictoffset */ 1214 offsetof(fileio, dict), /* tp_dictoffset */
1185 fileio_init, /* tp_init */ 1215 fileio_init, /* tp_init */
1186 PyType_GenericAlloc, /* tp_alloc */ 1216 PyType_GenericAlloc, /* tp_alloc */
1187 fileio_new, /* tp_new */ 1217 fileio_new, /* tp_new */
1188 PyObject_GC_Del, /* tp_free */ 1218 PyObject_GC_Del, /* tp_free */
1189 }; 1219 };
OLDNEW
« Modules/_io/_iomodule.c ('K') | « Modules/_io/_iomodule.c ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld cbc36f91f3f7