@@ -160,49 +160,51 @@ mp_obj_t file_obj_tell(mp_obj_t self_in) {
160160}
161161STATIC MP_DEFINE_CONST_FUN_OBJ_1 (file_obj_tell_obj , file_obj_tell );
162162
163- STATIC mp_obj_t file_obj_make_new (mp_obj_t type , mp_uint_t n_args , mp_uint_t n_kw , const mp_obj_t * args ) {
164- mp_arg_check_num (n_args , n_kw , 1 , 2 , false);
165-
166- const char * fname = mp_obj_str_get_str (args [0 ]);
163+ // Note: encoding is ignored for now; it's also not a valid kwarg for CPython's FileIO,
164+ // but by adding it here we can use one single mp_arg_t array for open() and FileIO's constructor
165+ STATIC const mp_arg_t file_open_args [] = {
166+ { MP_QSTR_file , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = mp_const_none } },
167+ { MP_QSTR_mode , MP_ARG_OBJ , {.u_obj = MP_OBJ_NEW_QSTR (MP_QSTR_r )} },
168+ { MP_QSTR_encoding , MP_ARG_OBJ | MP_ARG_KW_ONLY , {.u_obj = mp_const_none } },
169+ };
170+ #define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
167171
172+ STATIC mp_obj_t file_open (mp_obj_t type , mp_arg_val_t * args ) {
168173 int mode = 0 ;
169- if (n_args == 1 ) {
170- mode = FA_READ ;
171- } else {
172- const char * mode_s = mp_obj_str_get_str (args [1 ]);
173- // TODO make sure only one of r, w, x, a, and b, t are specified
174- while (* mode_s ) {
175- switch (* mode_s ++ ) {
176- case 'r' :
177- mode |= FA_READ ;
178- break ;
179- case 'w' :
180- mode |= FA_WRITE | FA_CREATE_ALWAYS ;
181- break ;
182- case 'x' :
183- mode |= FA_WRITE | FA_CREATE_NEW ;
184- break ;
185- case 'a' :
186- mode |= FA_WRITE | FA_OPEN_ALWAYS ;
187- break ;
188- case '+' :
189- mode |= FA_READ | FA_WRITE ;
190- break ;
191- #if MICROPY_PY_IO_FILEIO
192- case 'b' :
193- type = (mp_obj_t )& mp_type_fileio ;
194- break ;
195- #endif
196- case 't' :
197- type = (mp_obj_t )& mp_type_textio ;
198- break ;
199- }
174+ const char * mode_s = mp_obj_str_get_str (args [1 ].u_obj );
175+ // TODO make sure only one of r, w, x, a, and b, t are specified
176+ while (* mode_s ) {
177+ switch (* mode_s ++ ) {
178+ case 'r' :
179+ mode |= FA_READ ;
180+ break ;
181+ case 'w' :
182+ mode |= FA_WRITE | FA_CREATE_ALWAYS ;
183+ break ;
184+ case 'x' :
185+ mode |= FA_WRITE | FA_CREATE_NEW ;
186+ break ;
187+ case 'a' :
188+ mode |= FA_WRITE | FA_OPEN_ALWAYS ;
189+ break ;
190+ case '+' :
191+ mode |= FA_READ | FA_WRITE ;
192+ break ;
193+ #if MICROPY_PY_IO_FILEIO
194+ case 'b' :
195+ type = (mp_obj_t )& mp_type_fileio ;
196+ break ;
197+ #endif
198+ case 't' :
199+ type = (mp_obj_t )& mp_type_textio ;
200+ break ;
200201 }
201202 }
202203
203204 pyb_file_obj_t * o = m_new_obj_with_finaliser (pyb_file_obj_t );
204205 o -> base .type = type ;
205206
207+ const char * fname = mp_obj_str_get_str (args [0 ].u_obj );
206208 FRESULT res = f_open (& o -> fp , fname , mode );
207209 if (res != FR_OK ) {
208210 m_del_obj (pyb_file_obj_t , o );
@@ -217,6 +219,12 @@ STATIC mp_obj_t file_obj_make_new(mp_obj_t type, mp_uint_t n_args, mp_uint_t n_k
217219 return o ;
218220}
219221
222+ STATIC mp_obj_t file_obj_make_new (mp_obj_t type_in , mp_uint_t n_args , mp_uint_t n_kw , const mp_obj_t * args ) {
223+ mp_arg_val_t arg_vals [FILE_OPEN_NUM_ARGS ];
224+ mp_arg_parse_all_kw_array (n_args , n_kw , args , FILE_OPEN_NUM_ARGS , file_open_args , arg_vals );
225+ return file_open (type_in , arg_vals );
226+ }
227+
220228// TODO gc hook to close the file if not already closed
221229
222230STATIC const mp_map_elem_t rawfile_locals_dict_table [] = {
@@ -273,9 +281,10 @@ const mp_obj_type_t mp_type_textio = {
273281};
274282
275283// Factory function for I/O stream classes
276- STATIC mp_obj_t pyb_io_open (mp_uint_t n_args , const mp_obj_t * args ) {
277- // TODO: analyze mode and buffering args and instantiate appropriate type
278- return file_obj_make_new ((mp_obj_t )& mp_type_textio , n_args , 0 , args );
284+ mp_obj_t mp_builtin_open (mp_uint_t n_args , const mp_obj_t * args , mp_map_t * kwargs ) {
285+ // TODO: analyze buffering args and instantiate appropriate type
286+ mp_arg_val_t arg_vals [FILE_OPEN_NUM_ARGS ];
287+ mp_arg_parse_all (n_args , args , kwargs , FILE_OPEN_NUM_ARGS , file_open_args , arg_vals );
288+ return file_open ((mp_obj_t )& mp_type_textio , arg_vals );
279289}
280-
281- MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (mp_builtin_open_obj , 1 , 2 , pyb_io_open );
290+ MP_DEFINE_CONST_FUN_OBJ_KW (mp_builtin_open_obj , 1 , mp_builtin_open );
0 commit comments