diff --git a/py/obj.h b/py/obj.h
index e800addadef5214616476aa22ef31ffb29e57020..fc99055b6e6da31234847565ecb21b811a000915 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -229,7 +229,7 @@ struct _mp_obj_type_t {
     // in mp_obj_type_t at the expense of extra pointer and extra dereference
     // when actually used.
     mp_buffer_p_t buffer_p;
-    mp_stream_p_t stream_p;
+    const mp_stream_p_t *stream_p;
 
     // these are for dynamically created types (classes)
     mp_obj_t bases_tuple;
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index 2271941a056e79927fdea9006fdb80f5530780d1..85f69861b22fd941c2a40d8428bab6f75c1387d2 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -111,6 +111,7 @@ Q(max)
 Q(min)
 Q(namedtuple)
 Q(next)
+Q(open)
 Q(ord)
 Q(path)
 Q(pow)
diff --git a/py/stream.c b/py/stream.c
index 56f475a0c82d6f09894d1f2de55b1742e2c1dc6a..52e5f6d4b23baf609bb6c8d4def71a558bbb758a 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -14,7 +14,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in);
 
 STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
     struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)args[0];
-    if (o->type->stream_p.read == NULL) {
+    if (o->type->stream_p == NULL || o->type->stream_p->read == NULL) {
         // CPython: io.UnsupportedOperation, OSError subclass
         nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Operation not supported"));
     }
@@ -25,7 +25,7 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
     }
     byte *buf = m_new(byte, sz);
     int error;
-    machine_int_t out_sz = o->type->stream_p.read(o, buf, sz, &error);
+    machine_int_t out_sz = o->type->stream_p->read(o, buf, sz, &error);
     if (out_sz == -1) {
         nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
     } else {
@@ -37,7 +37,7 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
 
 STATIC mp_obj_t stream_write(mp_obj_t self_in, mp_obj_t arg) {
     struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)self_in;
-    if (o->type->stream_p.write == NULL) {
+    if (o->type->stream_p == NULL || o->type->stream_p->write == NULL) {
         // CPython: io.UnsupportedOperation, OSError subclass
         nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Operation not supported"));
     }
@@ -45,7 +45,7 @@ STATIC mp_obj_t stream_write(mp_obj_t self_in, mp_obj_t arg) {
     uint sz;
     const char *buf = mp_obj_str_get_data(arg, &sz);
     int error;
-    machine_int_t out_sz = o->type->stream_p.write(self_in, buf, sz, &error);
+    machine_int_t out_sz = o->type->stream_p->write(self_in, buf, sz, &error);
     if (out_sz == -1) {
         nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
     } else {
@@ -60,7 +60,7 @@ STATIC mp_obj_t stream_write(mp_obj_t self_in, mp_obj_t arg) {
 #define READ_SIZE 256
 STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
     struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)self_in;
-    if (o->type->stream_p.read == NULL) {
+    if (o->type->stream_p == NULL || o->type->stream_p->read == NULL) {
         // CPython: io.UnsupportedOperation, OSError subclass
         nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Operation not supported"));
     }
@@ -72,7 +72,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
     int error;
     int current_read = READ_SIZE;
     while (true) {
-        machine_int_t out_sz = o->type->stream_p.read(self_in, p, current_read, &error);
+        machine_int_t out_sz = o->type->stream_p->read(self_in, p, current_read, &error);
         if (out_sz == -1) {
             nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
         }
@@ -101,7 +101,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
 // Unbuffered, inefficient implementation of readline() for raw I/O files.
 STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
     struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)args[0];
-    if (o->type->stream_p.read == NULL) {
+    if (o->type->stream_p == NULL || o->type->stream_p->read == NULL) {
         // CPython: io.UnsupportedOperation, OSError subclass
         nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Operation not supported"));
     }
@@ -126,7 +126,7 @@ STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
             nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError/*&mp_type_RuntimeError*/, "Out of memory"));
         }
 
-        machine_int_t out_sz = o->type->stream_p.read(o, p, 1, &error);
+        machine_int_t out_sz = o->type->stream_p->read(o, p, 1, &error);
         if (out_sz == -1) {
             nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
         }
diff --git a/stm/qstrdefsport.h b/stm/qstrdefsport.h
index ea2681f18e0192e6789d3c0603d856d0d8d94777..5fba03eb9fc9d87e6d2ba587eda60d4e1573f501 100644
--- a/stm/qstrdefsport.h
+++ b/stm/qstrdefsport.h
@@ -36,7 +36,6 @@ Q(Usart)
 Q(ADC)
 Q(ADC_all)
 Q(Audio)
-Q(open)
 Q(File)
 // Entries for sys.path
 Q(0:/)
diff --git a/stmhal/file.c b/stmhal/file.c
index a78c58d4f980e0fcedf8efdd8eb110bb37ec7644..6d743a0c8cc9288150cc146c1e5de231e2858c58 100644
--- a/stmhal/file.c
+++ b/stmhal/file.c
@@ -61,17 +61,20 @@ STATIC const mp_map_elem_t file_locals_dict_table[] = {
 STATIC MP_DEFINE_CONST_DICT(file_locals_dict, file_locals_dict_table);
 
 STATIC mp_obj_t file_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args);
-static const mp_obj_type_t file_obj_type = {
+
+STATIC const mp_stream_p_t file_obj_stream_p = {
+    .read = file_read,
+    .write = file_write,
+};
+
+STATIC const mp_obj_type_t file_obj_type = {
     { &mp_type_type },
     .name = MP_QSTR_File,
     .make_new = file_obj_make_new,
     .print = file_obj_print,
     .getiter = mp_identity,
     .iternext = mp_stream_unbuffered_iter,
-    .stream_p = {
-        .read = file_read,
-        .write = file_write,
-    },
+    .stream_p = &file_obj_stream_p,
     .locals_dict = (mp_obj_t)&file_locals_dict,
 };
 
diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h
index 3212de85b38ab50688105d542e954f3c8b6f2171..c846adc1985f0baa56bd675f402dbbcc791bcd54 100644
--- a/stmhal/qstrdefsport.h
+++ b/stmhal/qstrdefsport.h
@@ -33,7 +33,6 @@ Q(SDcard)
 Q(gpio)
 Q(gpio_in)
 Q(gpio_out)
-Q(open)
 Q(File)
 // Entries for sys.path
 Q(0:/)
diff --git a/unix/file.c b/unix/file.c
index 780e84718d1d608e24753172562d260c4fd79b5f..2cc17dfd346c3349dc543fb9eeaf43e59cec4d86 100644
--- a/unix/file.c
+++ b/unix/file.c
@@ -123,6 +123,11 @@ STATIC const mp_map_elem_t rawfile_locals_dict_table[] = {
 
 STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
 
+STATIC const mp_stream_p_t rawfile_stream_p = {
+    .read = fdfile_read,
+    .write = fdfile_write,
+};
+
 STATIC const mp_obj_type_t rawfile_type = {
     { &mp_type_type },
     .name = MP_QSTR_io_dot_FileIO,
@@ -130,10 +135,7 @@ STATIC const mp_obj_type_t rawfile_type = {
     .make_new = fdfile_make_new,
     .getiter = mp_identity,
     .iternext = mp_stream_unbuffered_iter,
-    .stream_p = {
-        .read = fdfile_read,
-        .write = fdfile_write,
-    },
+    .stream_p = &rawfile_stream_p,
     .locals_dict = (mp_obj_t)&rawfile_locals_dict,
 };
 
diff --git a/unix/modsocket.c b/unix/modsocket.c
index 6bdbc889d6e575ea3ad5cf989e1d69306e597d89..62f10300f8e618ba074589b3fa0ecb5646874810 100644
--- a/unix/modsocket.c
+++ b/unix/modsocket.c
@@ -240,6 +240,11 @@ STATIC const mp_map_elem_t microsocket_locals_dict_table[] = {
 
 STATIC MP_DEFINE_CONST_DICT(microsocket_locals_dict, microsocket_locals_dict_table);
 
+STATIC const mp_stream_p_t microsocket_stream_p = {
+    .read = socket_read,
+    .write = socket_write,
+};
+
 STATIC const mp_obj_type_t microsocket_type = {
     { &mp_type_type },
     .name = MP_QSTR_socket,
@@ -247,10 +252,7 @@ STATIC const mp_obj_type_t microsocket_type = {
     .make_new = socket_make_new,
     .getiter = NULL,
     .iternext = NULL,
-    .stream_p = {
-        .read = socket_read,
-        .write = socket_write,
-    },
+    .stream_p = &microsocket_stream_p,
     .locals_dict = (mp_obj_t)&microsocket_locals_dict,
 };
 
diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h
index 3798f88b5835af6c8ed04ccf99b33e06843c4bdc..e2f2a69e113a58e1a64baea6dbf3622e6721376d 100644
--- a/unix/mpconfigport.h
+++ b/unix/mpconfigport.h
@@ -31,7 +31,6 @@ typedef unsigned int machine_uint_t; // must be pointer size
 typedef void *machine_ptr_t; // must be of pointer size
 typedef const void *machine_const_ptr_t; // must be of pointer size
 
-struct _mp_obj_fun_native_t;
 extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
 #define MICROPY_EXTRA_BUILTINS \
     { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
diff --git a/unix/qstrdefsport.h b/unix/qstrdefsport.h
index bfef9eb0da9a015fb3fbd88dd2a08e95c51f6000..fd259f327cb34376d3d3502536c6801f116ffd6e 100644
--- a/unix/qstrdefsport.h
+++ b/unix/qstrdefsport.h
@@ -3,7 +3,6 @@
 Q(Test)
 
 Q(argv)
-Q(open)
 Q(stdin)
 Q(stdout)
 Q(stderr)