diff options
| author | Jim Mussared <jim.mussared@gmail.com> | 2022-07-22 13:53:13 +1000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2022-07-26 17:58:01 +1000 |
| commit | e65d1e69e88268145ff0e7e73240f028885915be (patch) | |
| tree | 3e4e19afc776fb319b535f6fdee3d4953bc39924 | |
| parent | c0fa903d6b2ed5131ae60f8faff2c6ad5276b3a2 (diff) | |
py/modio: Remove FileIO and TextIOWrapper from io module.
On ports with more than one filesystem, the type will be wrong, for example
if using LFS but FAT enabled, then the type will be FAT. So it's not
possible to use these classes to identify a file object type.
Furthermore, constructing an io.FileIO currently crashes on FAT, and
make_new isn't supported on LFS.
And the io.TextIOWrapper class does not match CPython at all.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
| -rw-r--r-- | extmod/vfs.c | 2 | ||||
| -rw-r--r-- | extmod/vfs_fat_file.c | 127 | ||||
| -rw-r--r-- | extmod/vfs_posix.c | 2 | ||||
| -rw-r--r-- | extmod/vfs_posix_file.c | 19 | ||||
| -rw-r--r-- | py/modio.c | 9 | ||||
| -rw-r--r-- | tests/extmod/vfs_posix.py | 4 |
6 files changed, 58 insertions, 105 deletions
diff --git a/extmod/vfs.c b/extmod/vfs.c index 2799622b3..be1a82d40 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 537101d00..ebf36fc39 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -151,72 +151,6 @@ 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) - -STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) { - int mode = 0; - const char *mode_s = mp_obj_str_get_str(args[1].u_obj); - // TODO make sure only one of r, w, x, a, and b, t are specified - while (*mode_s) { - switch (*mode_s++) { - case 'r': - mode |= FA_READ; - break; - case 'w': - mode |= FA_WRITE | FA_CREATE_ALWAYS; - break; - case 'x': - mode |= FA_WRITE | FA_CREATE_NEW; - break; - case 'a': - mode |= FA_WRITE | FA_OPEN_ALWAYS; - break; - case '+': - mode |= FA_READ | FA_WRITE; - break; - #if MICROPY_PY_IO_FILEIO - case 'b': - type = &mp_type_vfs_fat_fileio; - break; - #endif - case 't': - type = &mp_type_vfs_fat_textio; - break; - } - } - - 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); - if (res != FR_OK) { - m_del_obj(pyb_file_obj_t, o); - mp_raise_OSError(fresult_to_errno_table[res]); - } - - // for 'a' mode, we must begin at the end of the file - if ((mode & FA_OPEN_ALWAYS) != 0) { - f_lseek(&o->fp, f_size(&o->fp)); - } - - 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[] = { @@ -247,7 +181,6 @@ 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, @@ -266,7 +199,6 @@ 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, @@ -274,15 +206,58 @@ const mp_obj_type_t mp_type_vfs_fat_textio = { }; // 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 +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); - 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); + + const mp_obj_type_t *type = &mp_type_vfs_fat_textio; + int mode = 0; + 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++) { + case 'r': + mode |= FA_READ; + break; + case 'w': + mode |= FA_WRITE | FA_CREATE_ALWAYS; + break; + case 'x': + mode |= FA_WRITE | FA_CREATE_NEW; + break; + case 'a': + mode |= FA_WRITE | FA_OPEN_ALWAYS; + break; + case '+': + mode |= FA_READ | FA_WRITE; + break; + #if MICROPY_PY_IO_FILEIO + case 'b': + type = &mp_type_vfs_fat_fileio; + break; + #endif + case 't': + type = &mp_type_vfs_fat_textio; + break; + } + } + + 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(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]); + } + + // for 'a' mode, we must begin at the end of the file + if ((mode & FA_OPEN_ALWAYS) != 0) { + f_lseek(&o->fp, f_size(&o->fp)); + } + + return MP_OBJ_FROM_PTR(o); } -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 1ada596d1..9b0036581 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 837c5489b..795ad7bbd 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 50af0b6a4..d44c1948a 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 2a14fc207..d19323669 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 |
