@@ -65,37 +65,33 @@ PyFile_Name(PyObject *f)
6565 return ((PyFileObject * )f )-> f_name ;
6666}
6767
68- PyObject *
69- PyFile_FromFile (FILE * fp , char * name , char * mode , int (* close )(FILE * ))
68+
69+ static PyObject *
70+ fill_file_fields (PyFileObject * f , FILE * fp , char * name , char * mode ,
71+ int (* close )(FILE * ))
7072{
71- PyFileObject * f = PyObject_NEW (PyFileObject , & PyFile_Type );
72- if (f == NULL )
73- return NULL ;
73+ assert (f != NULL );
74+ assert (PyFile_Check (f ));
7475 f -> f_fp = NULL ;
7576 f -> f_name = PyString_FromString (name );
7677 f -> f_mode = PyString_FromString (mode );
7778 f -> f_close = close ;
7879 f -> f_softspace = 0 ;
79- if (strchr (mode ,'b' ) != NULL )
80- f -> f_binary = 1 ;
81- else
82- f -> f_binary = 0 ;
83- if (f -> f_name == NULL || f -> f_mode == NULL ) {
84- Py_DECREF (f );
80+ f -> f_binary = strchr (mode ,'b' ) != NULL ;
81+ if (f -> f_name == NULL || f -> f_mode == NULL )
8582 return NULL ;
86- }
8783 f -> f_fp = fp ;
8884 return (PyObject * ) f ;
8985}
9086
91- PyObject *
92- PyFile_FromString ( char * name , char * mode )
87+ static PyObject *
88+ open_the_file ( PyFileObject * f , char * name , char * mode )
9389{
94- extern int fclose ( FILE * );
95- PyFileObject * f ;
96- f = ( PyFileObject * ) PyFile_FromFile (( FILE * ) NULL , name , mode , fclose );
97- if ( f == NULL )
98- return NULL ;
90+ assert ( f != NULL );
91+ assert ( PyFile_Check ( f )) ;
92+ assert ( name != NULL );
93+ assert ( mode != NULL );
94+
9995#ifdef HAVE_FOPENRF
10096 if (* mode == '*' ) {
10197 FILE * fopenRF ();
@@ -118,8 +114,36 @@ PyFile_FromString(char *name, char *mode)
118114 }
119115#endif
120116 PyErr_SetFromErrnoWithFilename (PyExc_IOError , name );
121- Py_DECREF (f );
122- return NULL ;
117+ f = NULL ;
118+ }
119+ return (PyObject * )f ;
120+ }
121+
122+ PyObject *
123+ PyFile_FromFile (FILE * fp , char * name , char * mode , int (* close )(FILE * ))
124+ {
125+ PyFileObject * f = PyObject_NEW (PyFileObject , & PyFile_Type );
126+ if (f != NULL ) {
127+ if (fill_file_fields (f , fp , name , mode , close ) == NULL ) {
128+ Py_DECREF (f );
129+ f = NULL ;
130+ }
131+ }
132+ return (PyObject * ) f ;
133+ }
134+
135+ PyObject *
136+ PyFile_FromString (char * name , char * mode )
137+ {
138+ extern int fclose (FILE * );
139+ PyFileObject * f ;
140+
141+ f = (PyFileObject * )PyFile_FromFile ((FILE * )NULL , name , mode , fclose );
142+ if (f != NULL ) {
143+ if (open_the_file (f , name , mode ) == NULL ) {
144+ Py_DECREF (f );
145+ f = NULL ;
146+ }
123147 }
124148 return (PyObject * )f ;
125149}
@@ -1293,6 +1317,52 @@ file_getiter(PyObject *f)
12931317 return PyObject_CallMethod (f , "xreadlines" , "" );
12941318}
12951319
1320+ static PyObject *
1321+ file_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
1322+ {
1323+ /* XXX As for all XXX_new functions, file_new is called
1324+ with kwds=NULL by type_call(), so the kwlist is impotent. */
1325+ static char * kwlist [] = {"name" , "mode" , "buffering" , 0 };
1326+ char * name = NULL ;
1327+ char * mode = "r" ;
1328+ int bufsize = -1 ;
1329+ PyObject * f ;
1330+ extern int fclose (FILE * );
1331+
1332+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "et|si:file" , kwlist ,
1333+ Py_FileSystemDefaultEncoding , & name ,
1334+ & mode , & bufsize ))
1335+ return NULL ;
1336+ f = PyType_GenericAlloc (type , 0 );
1337+ if (f != NULL ) {
1338+ PyFileObject * g = (PyFileObject * )f ;
1339+ if (fill_file_fields (g , NULL , name , mode , fclose ) == NULL ) {
1340+ Py_DECREF (f );
1341+ f = NULL ;
1342+ }
1343+ if (f != NULL && open_the_file (g , name , mode ) == NULL ) {
1344+ Py_DECREF (f );
1345+ f = NULL ;
1346+ }
1347+ if (f != NULL )
1348+ PyFile_SetBufSize (f , bufsize );
1349+ }
1350+ PyMem_Free (name ); /* free the encoded string */
1351+ return f ;
1352+ }
1353+
1354+ /* XXX Keep this in synch with open_doc in bltinmodule.c. */
1355+ static char file_doc [] =
1356+ "file(name[, mode[, buffering]]) -> file object\n"
1357+ "\n"
1358+ "Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n"
1359+ "writing or appending. The file will be created if it doesn't exist\n"
1360+ "when opened for writing or appending; it will be truncated when\n"
1361+ "opened for writing. Add a 'b' to the mode for binary files.\n"
1362+ "Add a '+' to the mode to allow simultaneous reading and writing.\n"
1363+ "If the buffering argument is given, 0 means unbuffered, 1 means line\n"
1364+ "buffered, and larger numbers specify the buffer size." ;
1365+
12961366PyTypeObject PyFile_Type = {
12971367 PyObject_HEAD_INIT (& PyType_Type )
12981368 0 ,
@@ -1314,8 +1384,9 @@ PyTypeObject PyFile_Type = {
13141384 PyObject_GenericGetAttr , /* tp_getattro */
13151385 0 , /* tp_setattro */
13161386 0 , /* tp_as_buffer */
1317- Py_TPFLAGS_DEFAULT , /* tp_flags */
1318- 0 , /* tp_doc */
1387+ Py_TPFLAGS_DEFAULT |
1388+ Py_TPFLAGS_BASETYPE , /* tp_flags */
1389+ file_doc , /* tp_doc */
13191390 0 , /* tp_traverse */
13201391 0 , /* tp_clear */
13211392 0 , /* tp_richcompare */
@@ -1327,6 +1398,12 @@ PyTypeObject PyFile_Type = {
13271398 file_getsetlist , /* tp_getset */
13281399 0 , /* tp_base */
13291400 0 , /* tp_dict */
1401+ 0 , /* tp_descr_get */
1402+ 0 , /* tp_descr_set */
1403+ 0 , /* tp_dictoffset */
1404+ 0 , /* tp_init */
1405+ 0 , /* tp_alloc */
1406+ file_new , /* tp_new */
13301407};
13311408
13321409/* Interface for the 'soft space' between print items. */
0 commit comments