extmod/vfs_posix_file: Implement sys.std*.buffer objects.
Add the buffer attribute to sys.stdin, sys.stdout and sys.stderr. This provides raw access to underlying stdio streams for the unix port (and others that use VfsPosix). Signed-off-by: stephanelsmith <stephane.smith@titansensor.com>
This commit is contained in:
parent
1c047742a2
commit
db06041d59
@ -274,12 +274,58 @@ STATIC const mp_stream_p_t vfs_posix_textio_stream_p = {
|
|||||||
.is_text = true,
|
.is_text = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if MICROPY_PY_SYS_STDIO_BUFFER
|
||||||
|
|
||||||
|
const mp_obj_vfs_posix_file_t mp_sys_stdin_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDIN_FILENO};
|
||||||
|
const mp_obj_vfs_posix_file_t mp_sys_stdout_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDOUT_FILENO};
|
||||||
|
const mp_obj_vfs_posix_file_t mp_sys_stderr_buffer_obj = {{&mp_type_vfs_posix_fileio}, STDERR_FILENO};
|
||||||
|
|
||||||
|
// Forward declarations.
|
||||||
|
const mp_obj_vfs_posix_file_t mp_sys_stdin_obj;
|
||||||
|
const mp_obj_vfs_posix_file_t mp_sys_stdout_obj;
|
||||||
|
const mp_obj_vfs_posix_file_t mp_sys_stderr_obj;
|
||||||
|
|
||||||
|
STATIC void vfs_posix_textio_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||||
|
if (dest[0] != MP_OBJ_NULL) {
|
||||||
|
// These objects are read-only.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr == MP_QSTR_buffer) {
|
||||||
|
// Implement the `buffer` attribute only on std{in,out,err} instances.
|
||||||
|
if (MP_OBJ_TO_PTR(self_in) == &mp_sys_stdin_obj) {
|
||||||
|
dest[0] = MP_OBJ_FROM_PTR(&mp_sys_stdin_buffer_obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (MP_OBJ_TO_PTR(self_in) == &mp_sys_stdout_obj) {
|
||||||
|
dest[0] = MP_OBJ_FROM_PTR(&mp_sys_stdout_buffer_obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (MP_OBJ_TO_PTR(self_in) == &mp_sys_stderr_obj) {
|
||||||
|
dest[0] = MP_OBJ_FROM_PTR(&mp_sys_stderr_buffer_obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any other attribute - forward to locals dict.
|
||||||
|
dest[1] = MP_OBJ_SENTINEL;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VFS_POSIX_TEXTIO_TYPE_ATTR attr, vfs_posix_textio_attr,
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define VFS_POSIX_TEXTIO_TYPE_ATTR
|
||||||
|
|
||||||
|
#endif // MICROPY_PY_SYS_STDIO_BUFFER
|
||||||
|
|
||||||
MP_DEFINE_CONST_OBJ_TYPE(
|
MP_DEFINE_CONST_OBJ_TYPE(
|
||||||
mp_type_vfs_posix_textio,
|
mp_type_vfs_posix_textio,
|
||||||
MP_QSTR_TextIOWrapper,
|
MP_QSTR_TextIOWrapper,
|
||||||
MP_TYPE_FLAG_ITER_IS_STREAM,
|
MP_TYPE_FLAG_ITER_IS_STREAM,
|
||||||
print, vfs_posix_file_print,
|
print, vfs_posix_file_print,
|
||||||
protocol, &vfs_posix_textio_stream_p,
|
protocol, &vfs_posix_textio_stream_p,
|
||||||
|
VFS_POSIX_TEXTIO_TYPE_ATTR
|
||||||
locals_dict, &vfs_posix_rawfile_locals_dict
|
locals_dict, &vfs_posix_rawfile_locals_dict
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2,3 +2,4 @@ import sys
|
|||||||
|
|
||||||
print(sys.stdin.fileno())
|
print(sys.stdin.fileno())
|
||||||
print(sys.stdout.fileno())
|
print(sys.stdout.fileno())
|
||||||
|
print(sys.stderr.fileno())
|
||||||
|
65
tests/io/file_stdio2.py
Normal file
65
tests/io/file_stdio2.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# Test sys.std*.buffer objects.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
sys.stdout.buffer
|
||||||
|
sys.stdin.buffer
|
||||||
|
sys.stderr.buffer
|
||||||
|
except AttributeError:
|
||||||
|
print("SKIP")
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
|
|
||||||
|
# force cpython to flush after every print
|
||||||
|
# this is to sequence stdout and stderr
|
||||||
|
def print_flush(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
print(*args, **kwargs, flush=True)
|
||||||
|
except TypeError:
|
||||||
|
print(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
print_flush("==stdin==")
|
||||||
|
print_flush(sys.stdin.buffer.fileno())
|
||||||
|
|
||||||
|
|
||||||
|
print_flush("==stdout==")
|
||||||
|
print_flush(sys.stdout.buffer.fileno())
|
||||||
|
n_text = sys.stdout.write("The quick brown fox jumps over the lazy dog\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
n_binary = sys.stdout.buffer.write("The quick brown fox jumps over the lazy dog\n".encode("utf-8"))
|
||||||
|
sys.stdout.buffer.flush()
|
||||||
|
print_flush("n_text:{} n_binary:{}".format(n_text, n_binary))
|
||||||
|
|
||||||
|
# temporarily disabling unicode tests until future PR which fixes unicode write character count
|
||||||
|
# n_text = sys.stdout.write("🚀")
|
||||||
|
# sys.stdout.flush()
|
||||||
|
# n_binary = sys.stdout.buffer.write("🚀".encode("utf-8"))
|
||||||
|
# sys.stdout.buffer.flush()
|
||||||
|
# print_flush("")
|
||||||
|
# print_flush("n_text:{} n_binary:{}".format(n_text, n_binary))
|
||||||
|
# n_text = sys.stdout.write("1🚀2a3α4b5β6c7γ8d9δ0ぁ1🙐")
|
||||||
|
# sys.stdout.flush()
|
||||||
|
# n_binary = sys.stdout.buffer.write("1🚀2a3α4b5β6c7γ8d9δ0ぁ1🙐".encode("utf-8"))
|
||||||
|
# sys.stdout.buffer.flush()
|
||||||
|
# print_flush("")
|
||||||
|
# print_flush("n_text:{} n_binary:{}".format(n_text, n_binary))
|
||||||
|
|
||||||
|
|
||||||
|
print_flush("==stderr==")
|
||||||
|
print_flush(sys.stderr.buffer.fileno())
|
||||||
|
n_text = sys.stderr.write("The quick brown fox jumps over the lazy dog\n")
|
||||||
|
sys.stderr.flush()
|
||||||
|
n_binary = sys.stderr.buffer.write("The quick brown fox jumps over the lazy dog\n".encode("utf-8"))
|
||||||
|
sys.stderr.buffer.flush()
|
||||||
|
print_flush("n_text:{} n_binary:{}".format(n_text, n_binary))
|
||||||
|
|
||||||
|
# temporarily disabling unicode tests until future PR which fixes unicode write character count
|
||||||
|
# n_text = sys.stderr.write("🚀")
|
||||||
|
# sys.stderr.flush()
|
||||||
|
# n_binary = sys.stderr.buffer.write("🚀".encode("utf-8"))
|
||||||
|
# sys.stderr.buffer.flush()
|
||||||
|
# print_flush("")
|
||||||
|
# print_flush("n_text:{} n_binary:{}".format(n_text, n_binary))
|
||||||
|
# print_flush("")
|
Loading…
Reference in New Issue
Block a user