diff --git a/extmod/vfs.c b/extmod/vfs.c index 2799622b38..be1a82d404 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -312,7 +312,7 @@ mp_obj_t mp_vfs_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) #if MICROPY_VFS_POSIX // If the file is an integer then delegate straight to the POSIX handler if (mp_obj_is_small_int(args[ARG_file].u_obj)) { - return mp_vfs_posix_file_open(&mp_type_textio, args[ARG_file].u_obj, args[ARG_mode].u_obj); + return mp_vfs_posix_file_open(&mp_type_vfs_posix_textio, args[ARG_file].u_obj, args[ARG_mode].u_obj); } #endif diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index 537101d00f..ebf36fc397 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -151,18 +151,67 @@ STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, } } -// Note: encoding is ignored for now; it's also not a valid kwarg for CPython's FileIO, -// but by adding it here we can use one single mp_arg_t array for open() and FileIO's constructor -STATIC const mp_arg_t file_open_args[] = { - { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE} }, - { MP_QSTR_mode, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_QSTR(MP_QSTR_r)} }, - { MP_QSTR_encoding, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} }, -}; -#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args) +// TODO gc hook to close the file if not already closed -STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) { +STATIC const mp_rom_map_elem_t vfs_fat_rawfile_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, + { MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_seek), MP_ROM_PTR(&mp_stream_seek_obj) }, + { MP_ROM_QSTR(MP_QSTR_tell), MP_ROM_PTR(&mp_stream_tell_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&file_obj___exit___obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(vfs_fat_rawfile_locals_dict, vfs_fat_rawfile_locals_dict_table); + +#if MICROPY_PY_IO_FILEIO +STATIC const mp_stream_p_t vfs_fat_fileio_stream_p = { + .read = file_obj_read, + .write = file_obj_write, + .ioctl = file_obj_ioctl, +}; + +const mp_obj_type_t mp_type_vfs_fat_fileio = { + { &mp_type_type }, + .name = MP_QSTR_FileIO, + .print = file_obj_print, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &vfs_fat_fileio_stream_p, + .locals_dict = (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict, +}; +#endif + +STATIC const mp_stream_p_t vfs_fat_textio_stream_p = { + .read = file_obj_read, + .write = file_obj_write, + .ioctl = file_obj_ioctl, + .is_text = true, +}; + +const mp_obj_type_t mp_type_vfs_fat_textio = { + { &mp_type_type }, + .name = MP_QSTR_TextIOWrapper, + .print = file_obj_print, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &vfs_fat_textio_stream_p, + .locals_dict = (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict, +}; + +// Factory function for I/O stream classes +STATIC mp_obj_t fat_vfs_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_in) { + fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in); + + const mp_obj_type_t *type = &mp_type_vfs_fat_textio; int mode = 0; - const char *mode_s = mp_obj_str_get_str(args[1].u_obj); + const char *mode_s = mp_obj_str_get_str(mode_in); // TODO make sure only one of r, w, x, a, and b, t are specified while (*mode_s) { switch (*mode_s++) { @@ -195,9 +244,8 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t); o->base.type = type; - const char *fname = mp_obj_str_get_str(args[0].u_obj); - assert(vfs != NULL); - FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode); + const char *fname = mp_obj_str_get_str(path_in); + FRESULT res = f_open(&self->fatfs, &o->fp, fname, mode); if (res != FR_OK) { m_del_obj(pyb_file_obj_t, o); mp_raise_OSError(fresult_to_errno_table[res]); @@ -210,79 +258,6 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar return MP_OBJ_FROM_PTR(o); } - -STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals); - return file_open(NULL, type, arg_vals); -} - -// TODO gc hook to close the file if not already closed - -STATIC const mp_rom_map_elem_t vfs_fat_rawfile_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, - { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, - { MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, - { MP_ROM_QSTR(MP_QSTR_seek), MP_ROM_PTR(&mp_stream_seek_obj) }, - { MP_ROM_QSTR(MP_QSTR_tell), MP_ROM_PTR(&mp_stream_tell_obj) }, - { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&file_obj___exit___obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(vfs_fat_rawfile_locals_dict, vfs_fat_rawfile_locals_dict_table); - -#if MICROPY_PY_IO_FILEIO -STATIC const mp_stream_p_t vfs_fat_fileio_stream_p = { - .read = file_obj_read, - .write = file_obj_write, - .ioctl = file_obj_ioctl, -}; - -const mp_obj_type_t mp_type_vfs_fat_fileio = { - { &mp_type_type }, - .name = MP_QSTR_FileIO, - .print = file_obj_print, - .make_new = file_obj_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &vfs_fat_fileio_stream_p, - .locals_dict = (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict, -}; -#endif - -STATIC const mp_stream_p_t vfs_fat_textio_stream_p = { - .read = file_obj_read, - .write = file_obj_write, - .ioctl = file_obj_ioctl, - .is_text = true, -}; - -const mp_obj_type_t mp_type_vfs_fat_textio = { - { &mp_type_type }, - .name = MP_QSTR_TextIOWrapper, - .print = file_obj_print, - .make_new = file_obj_make_new, - .getiter = mp_identity_getiter, - .iternext = mp_stream_unbuffered_iter, - .protocol = &vfs_fat_textio_stream_p, - .locals_dict = (mp_obj_dict_t *)&vfs_fat_rawfile_locals_dict, -}; - -// Factory function for I/O stream classes -STATIC mp_obj_t fatfs_builtin_open_self(mp_obj_t self_in, mp_obj_t path, mp_obj_t mode) { - // TODO: analyze buffering args and instantiate appropriate type - fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in); - mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS]; - arg_vals[0].u_obj = path; - arg_vals[1].u_obj = mode; - arg_vals[2].u_obj = mp_const_none; - return file_open(self, &mp_type_vfs_fat_textio, arg_vals); -} -MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_open_obj, fatfs_builtin_open_self); +MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_open_obj, fat_vfs_open); #endif // MICROPY_VFS && MICROPY_VFS_FAT diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 1ada596d13..9b00365817 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -138,7 +138,7 @@ STATIC mp_obj_t vfs_posix_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode if (!mp_obj_is_small_int(path_in)) { path_in = vfs_posix_get_path_obj(self, path_in); } - return mp_vfs_posix_file_open(&mp_type_textio, path_in, mode_in); + return mp_vfs_posix_file_open(&mp_type_vfs_posix_textio, path_in, mode_in); } STATIC MP_DEFINE_CONST_FUN_OBJ_3(vfs_posix_open_obj, vfs_posix_open); diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 837c5489b0..795ad7bbd9 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -111,17 +111,6 @@ mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_ return MP_OBJ_FROM_PTR(o); } -STATIC mp_obj_t vfs_posix_file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - static const mp_arg_t allowed_args[] = { - { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE} }, - { MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_r)} }, - }; - - mp_arg_val_t arg_vals[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, arg_vals); - return mp_vfs_posix_file_open(type, arg_vals[0].u_obj, arg_vals[1].u_obj); -} - STATIC mp_obj_t vfs_posix_file_fileno(mp_obj_t self_in) { mp_obj_vfs_posix_file_t *self = MP_OBJ_TO_PTR(self_in); check_fd_is_open(self); @@ -268,7 +257,6 @@ const mp_obj_type_t mp_type_vfs_posix_fileio = { { &mp_type_type }, .name = MP_QSTR_FileIO, .print = vfs_posix_file_print, - .make_new = vfs_posix_file_make_new, .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &vfs_posix_fileio_stream_p, @@ -287,15 +275,14 @@ const mp_obj_type_t mp_type_vfs_posix_textio = { { &mp_type_type }, .name = MP_QSTR_TextIOWrapper, .print = vfs_posix_file_print, - .make_new = vfs_posix_file_make_new, .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &vfs_posix_textio_stream_p, .locals_dict = (mp_obj_dict_t *)&vfs_posix_rawfile_locals_dict, }; -const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_textio}, STDIN_FILENO}; -const mp_obj_vfs_posix_file_t mp_sys_stdout_obj = {{&mp_type_textio}, STDOUT_FILENO}; -const mp_obj_vfs_posix_file_t mp_sys_stderr_obj = {{&mp_type_textio}, STDERR_FILENO}; +const mp_obj_vfs_posix_file_t mp_sys_stdin_obj = {{&mp_type_vfs_posix_textio}, STDIN_FILENO}; +const mp_obj_vfs_posix_file_t mp_sys_stdout_obj = {{&mp_type_vfs_posix_textio}, STDOUT_FILENO}; +const mp_obj_vfs_posix_file_t mp_sys_stderr_obj = {{&mp_type_vfs_posix_textio}, STDERR_FILENO}; #endif // MICROPY_VFS_POSIX || MICROPY_VFS_POSIX_FILE diff --git a/py/modio.c b/py/modio.c index 50af0b6a47..d44c1948ab 100644 --- a/py/modio.c +++ b/py/modio.c @@ -37,9 +37,6 @@ #if MICROPY_PY_IO -extern const mp_obj_type_t mp_type_fileio; -extern const mp_obj_type_t mp_type_textio; - #if MICROPY_PY_IO_IOBASE STATIC const mp_obj_type_t mp_type_iobase; @@ -211,12 +208,6 @@ STATIC const mp_rom_map_elem_t mp_module_io_globals_table[] = { #if MICROPY_PY_IO_IOBASE { MP_ROM_QSTR(MP_QSTR_IOBase), MP_ROM_PTR(&mp_type_iobase) }, #endif - #if MICROPY_PY_IO_FILEIO - { MP_ROM_QSTR(MP_QSTR_FileIO), MP_ROM_PTR(&mp_type_fileio) }, - #if MICROPY_CPYTHON_COMPAT - { MP_ROM_QSTR(MP_QSTR_TextIOWrapper), MP_ROM_PTR(&mp_type_textio) }, - #endif - #endif { MP_ROM_QSTR(MP_QSTR_StringIO), MP_ROM_PTR(&mp_type_stringio) }, #if MICROPY_PY_IO_BYTESIO { MP_ROM_QSTR(MP_QSTR_BytesIO), MP_ROM_PTR(&mp_type_bytesio) }, diff --git a/tests/extmod/vfs_posix.py b/tests/extmod/vfs_posix.py index 2a14fc2076..d193236696 100644 --- a/tests/extmod/vfs_posix.py +++ b/tests/extmod/vfs_posix.py @@ -42,8 +42,8 @@ f.close() # close on a closed file should succeed f.close() -# construct a file object using the type constructor, with a raw fileno -f = type(f)(2) +# construct a file object with a raw fileno +f = open(2) print(f) # file read