summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--examples/natmod/btree/btree_c.c14
-rw-r--r--extmod/modbtree.c10
-rw-r--r--extmod/moduasyncio.c10
-rw-r--r--extmod/moduselect.c5
-rw-r--r--extmod/modussl_axtls.c2
-rw-r--r--extmod/modussl_mbedtls.c2
-rw-r--r--extmod/vfs_fat_file.c8
-rw-r--r--extmod/vfs_lfsx_file.c8
-rw-r--r--extmod/vfs_posix_file.c8
-rw-r--r--ports/cc3200/mods/modussl.c3
-rw-r--r--ports/cc3200/mods/pybuart.c4
-rw-r--r--ports/esp32/machine_i2s.c4
-rw-r--r--ports/esp32/machine_uart.c4
-rw-r--r--ports/esp8266/machine_uart.c4
-rw-r--r--ports/mimxrt/machine_i2s.c4
-rw-r--r--ports/mimxrt/machine_uart.c4
-rw-r--r--ports/nrf/boards/microbit/modules/iters.c5
-rw-r--r--ports/nrf/boards/microbit/modules/microbitimage.c20
-rw-r--r--ports/nrf/modules/machine/uart.c4
-rw-r--r--ports/renesas-ra/machine_uart.c4
-rw-r--r--ports/rp2/machine_i2s.c4
-rw-r--r--ports/rp2/machine_uart.c4
-rw-r--r--ports/stm32/machine_i2s.c4
-rw-r--r--ports/stm32/machine_uart.c4
-rw-r--r--ports/stm32/usb.c4
-rw-r--r--ports/unix/modjni.c4
-rw-r--r--ports/unix/moduselect.c5
-rw-r--r--ports/unix/modusocket.c2
-rw-r--r--ports/zephyr/machine_uart.c4
-rw-r--r--py/obj.c8
-rw-r--r--py/obj.h56
-rw-r--r--py/objarray.c17
-rw-r--r--py/objattrtuple.c4
-rw-r--r--py/objdict.c17
-rw-r--r--py/objenumerate.c5
-rw-r--r--py/objfilter.c5
-rw-r--r--py/objgenerator.c5
-rw-r--r--py/objgetitemiter.c5
-rw-r--r--py/objlist.c4
-rw-r--r--py/objmap.c5
-rw-r--r--py/objnamedtuple.c2
-rw-r--r--py/objpolyiter.c10
-rw-r--r--py/objrange.c7
-rw-r--r--py/objreversed.c5
-rw-r--r--py/objset.c8
-rw-r--r--py/objstr.c4
-rw-r--r--py/objstringio.c8
-rw-r--r--py/objstrunicode.c4
-rw-r--r--py/objtuple.c8
-rw-r--r--py/objtype.c23
-rw-r--r--py/objzip.c5
-rw-r--r--py/runtime.c52
-rw-r--r--shared/runtime/sys_stdio_mphal.c8
-rw-r--r--tests/basics/io_stringio_base.py24
54 files changed, 234 insertions, 227 deletions
diff --git a/examples/natmod/btree/btree_c.c b/examples/natmod/btree/btree_c.c
index af7535a68f..c897f2e9a3 100644
--- a/examples/natmod/btree/btree_c.c
+++ b/examples/natmod/btree/btree_c.c
@@ -95,6 +95,7 @@ int mp_stream_posix_fsync(void *stream) {
}
mp_obj_full_type_t btree_type;
+mp_getiter_iternext_custom_t btree_getiter_iternext;
#include "extmod/modbtree.c"
@@ -122,13 +123,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_open_obj, 5, 5, btree_open);
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
MP_DYNRUNTIME_INIT_ENTRY
+ btree_getiter_iternext.getiter = btree_getiter;
+ btree_getiter_iternext.iternext = btree_iternext;
+
btree_type.base.type = (void*)&mp_fun_table.type_type;
+ btree_type.flags = MP_TYPE_FLAG_ITER_IS_CUSTOM;
btree_type.name = MP_QSTR_btree;
MP_OBJ_TYPE_SET_SLOT(&btree_type, print, btree_print, 0);
- MP_OBJ_TYPE_SET_SLOT(&btree_type, getiter, btree_getiter, 1);
- MP_OBJ_TYPE_SET_SLOT(&btree_type, iternext, btree_iternext, 2);
- MP_OBJ_TYPE_SET_SLOT(&btree_type, binary_op, btree_binary_op, 3);
- MP_OBJ_TYPE_SET_SLOT(&btree_type, subscr, btree_subscr, 4);
+ MP_OBJ_TYPE_SET_SLOT(&btree_type, iter, &btree_getiter_iternext, 1);
+ MP_OBJ_TYPE_SET_SLOT(&btree_type, binary_op, btree_binary_op, 2);
+ MP_OBJ_TYPE_SET_SLOT(&btree_type, subscr, btree_subscr, 3);
btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) };
btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) };
btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) };
@@ -137,7 +141,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) };
btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) };
btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) };
- MP_OBJ_TYPE_SET_SLOT(&btree_type, locals_dict, (void*)&btree_locals_dict, 5);
+ MP_OBJ_TYPE_SET_SLOT(&btree_type, locals_dict, (void*)&btree_locals_dict, 4);
mp_store_global(MP_QSTR__open, MP_OBJ_FROM_PTR(&btree_open_obj));
mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL));
diff --git a/extmod/modbtree.c b/extmod/modbtree.c
index 60c6885e6b..f21fe3ff94 100644
--- a/extmod/modbtree.c
+++ b/extmod/modbtree.c
@@ -319,15 +319,19 @@ STATIC const mp_rom_map_elem_t btree_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table);
+STATIC const mp_getiter_iternext_custom_t btree_getiter_iternext = {
+ .getiter = btree_getiter,
+ .iternext = btree_iternext,
+};
+
STATIC MP_DEFINE_CONST_OBJ_TYPE(
btree_type,
MP_QSTR_btree,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_CUSTOM,
MP_TYPE_NULL_MAKE_NEW,
// Save on qstr's, reuse same as for module
print, btree_print,
- getiter, btree_getiter,
- iternext, btree_iternext,
+ iter, &btree_getiter_iternext,
binary_op, btree_binary_op,
subscr, btree_subscr,
locals_dict, &btree_locals_dict
diff --git a/extmod/moduasyncio.c b/extmod/moduasyncio.c
index 5467642096..b0eb8b6509 100644
--- a/extmod/moduasyncio.c
+++ b/extmod/moduasyncio.c
@@ -287,14 +287,18 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
return mp_const_none;
}
+STATIC const mp_getiter_iternext_custom_t task_getiter_iternext = {
+ .getiter = task_getiter,
+ .iternext = task_iternext,
+};
+
STATIC MP_DEFINE_CONST_OBJ_TYPE(
task_type,
MP_QSTR_Task,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_CUSTOM,
task_make_new,
attr, task_attr,
- getiter, task_getiter,
- iternext, task_iternext
+ iter, &task_getiter_iternext
);
/******************************************************************************/
diff --git a/extmod/moduselect.c b/extmod/moduselect.c
index 352b15d983..58bd1169a9 100644
--- a/extmod/moduselect.c
+++ b/extmod/moduselect.c
@@ -339,10 +339,9 @@ STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_poll,
MP_QSTR_poll,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, poll_iternext,
+ iter, poll_iternext,
locals_dict, &poll_locals_dict
);
diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c
index 78470ea6df..a6d606d560 100644
--- a/extmod/modussl_axtls.c
+++ b/extmod/modussl_axtls.c
@@ -321,8 +321,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(
MP_TYPE_NULL_MAKE_NEW,
// Save on qstr's, reuse same as for module
print, ussl_socket_print,
- getiter, NULL,
- iternext, NULL,
protocol, &ussl_socket_stream_p,
locals_dict, &ussl_socket_locals_dict
);
diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c
index 76ca3ac719..50712980ba 100644
--- a/extmod/modussl_mbedtls.c
+++ b/extmod/modussl_mbedtls.c
@@ -399,8 +399,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(
MP_TYPE_NULL_MAKE_NEW,
// Save on qstr's, reuse same as for module
print, socket_print,
- getiter, NULL,
- iternext, NULL,
protocol, &ussl_socket_stream_p,
locals_dict, &ussl_socket_locals_dict
);
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index 00980459db..ca2e2b446f 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -179,11 +179,9 @@ STATIC const mp_stream_p_t vfs_fat_fileio_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_vfs_fat_fileio,
MP_QSTR_FileIO,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
MP_TYPE_NULL_MAKE_NEW,
print, file_obj_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &vfs_fat_fileio_stream_p,
locals_dict, &vfs_fat_rawfile_locals_dict
);
@@ -198,11 +196,9 @@ STATIC const mp_stream_p_t vfs_fat_textio_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_vfs_fat_textio,
MP_QSTR_TextIOWrapper,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
MP_TYPE_NULL_MAKE_NEW,
print, file_obj_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &vfs_fat_textio_stream_p,
locals_dict, &vfs_fat_rawfile_locals_dict
);
diff --git a/extmod/vfs_lfsx_file.c b/extmod/vfs_lfsx_file.c
index fda1b97b2a..f97641b7b9 100644
--- a/extmod/vfs_lfsx_file.c
+++ b/extmod/vfs_lfsx_file.c
@@ -223,11 +223,9 @@ STATIC const mp_stream_p_t MP_VFS_LFSx(fileio_stream_p) = {
MP_DEFINE_CONST_OBJ_TYPE(
MP_TYPE_VFS_LFSx_(_fileio),
MP_QSTR_FileIO,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
MP_TYPE_NULL_MAKE_NEW,
print, MP_VFS_LFSx(file_print),
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &MP_VFS_LFSx(fileio_stream_p),
locals_dict, &MP_VFS_LFSx(file_locals_dict)
);
@@ -242,11 +240,9 @@ STATIC const mp_stream_p_t MP_VFS_LFSx(textio_stream_p) = {
MP_DEFINE_CONST_OBJ_TYPE(
MP_TYPE_VFS_LFSx_(_textio),
MP_QSTR_TextIOWrapper,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
MP_TYPE_NULL_MAKE_NEW,
print, MP_VFS_LFSx(file_print),
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &MP_VFS_LFSx(textio_stream_p),
locals_dict, &MP_VFS_LFSx(file_locals_dict)
);
diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c
index f0b5436fe1..729d914d3a 100644
--- a/extmod/vfs_posix_file.c
+++ b/extmod/vfs_posix_file.c
@@ -252,11 +252,9 @@ STATIC const mp_stream_p_t vfs_posix_fileio_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_vfs_posix_fileio,
MP_QSTR_FileIO,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
MP_TYPE_NULL_MAKE_NEW,
print, vfs_posix_file_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &vfs_posix_fileio_stream_p,
locals_dict, &vfs_posix_rawfile_locals_dict
);
@@ -271,11 +269,9 @@ STATIC const mp_stream_p_t vfs_posix_textio_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_vfs_posix_textio,
MP_QSTR_TextIOWrapper,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
MP_TYPE_NULL_MAKE_NEW,
print, vfs_posix_file_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &vfs_posix_textio_stream_p,
locals_dict, &vfs_posix_rawfile_locals_dict
);
diff --git a/ports/cc3200/mods/modussl.c b/ports/cc3200/mods/modussl.c
index abc9917c81..118cbd06f8 100644
--- a/ports/cc3200/mods/modussl.c
+++ b/ports/cc3200/mods/modussl.c
@@ -64,9 +64,6 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(
ssl_socket_type,
MP_QSTR_ussl,
MP_TYPE_FLAG_NONE,
- MP_TYPE_NULL_MAKE_NEW,
- getiter, NULL,
- iternext, NULL,
protocol, &socket_stream_p,
locals_dict, &socket_locals_dict
);
diff --git a/ports/cc3200/mods/pybuart.c b/ports/cc3200/mods/pybuart.c
index e7896c4ca5..f92f544732 100644
--- a/ports/cc3200/mods/pybuart.c
+++ b/ports/cc3200/mods/pybuart.c
@@ -688,11 +688,9 @@ STATIC const mp_irq_methods_t uart_irq_methods = {
MP_DEFINE_CONST_OBJ_TYPE(
pyb_uart_type,
MP_QSTR_UART,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
pyb_uart_make_new,
print, pyb_uart_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &uart_stream_p,
locals_dict, &pyb_uart_locals_dict
);
diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c
index b853f418ad..6e18394cc5 100644
--- a/ports/esp32/machine_i2s.c
+++ b/ports/esp32/machine_i2s.c
@@ -832,11 +832,9 @@ STATIC const mp_stream_p_t i2s_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_i2s_type,
MP_QSTR_I2S,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_i2s_make_new,
print, machine_i2s_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &i2s_stream_p,
locals_dict, &machine_i2s_locals_dict
);
diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c
index 6e091b8838..1f404154fc 100644
--- a/ports/esp32/machine_uart.c
+++ b/ports/esp32/machine_uart.c
@@ -533,11 +533,9 @@ STATIC const mp_stream_p_t uart_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_uart_type,
MP_QSTR_UART,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_uart_make_new,
print, machine_uart_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &uart_stream_p,
locals_dict, &machine_uart_locals_dict
);
diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c
index c737f854c3..af6231c219 100644
--- a/ports/esp8266/machine_uart.c
+++ b/ports/esp8266/machine_uart.c
@@ -346,11 +346,9 @@ STATIC const mp_stream_p_t uart_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
pyb_uart_type,
MP_QSTR_UART,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
pyb_uart_make_new,
print, pyb_uart_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &uart_stream_p,
locals_dict, &pyb_uart_locals_dict
);
diff --git a/ports/mimxrt/machine_i2s.c b/ports/mimxrt/machine_i2s.c
index 13380b4ee6..b6c630138b 100644
--- a/ports/mimxrt/machine_i2s.c
+++ b/ports/mimxrt/machine_i2s.c
@@ -1216,11 +1216,9 @@ STATIC const mp_stream_p_t i2s_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_i2s_type,
MP_QSTR_I2S,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_i2s_make_new,
print, machine_i2s_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &i2s_stream_p,
locals_dict, &machine_i2s_locals_dict
);
diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c
index 9d4873274a..e93d2478f3 100644
--- a/ports/mimxrt/machine_uart.c
+++ b/ports/mimxrt/machine_uart.c
@@ -472,11 +472,9 @@ STATIC const mp_stream_p_t uart_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_uart_type,
MP_QSTR_UART,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_uart_make_new,
print, machine_uart_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &uart_stream_p,
locals_dict, &machine_uart_locals_dict
);
diff --git a/ports/nrf/boards/microbit/modules/iters.c b/ports/nrf/boards/microbit/modules/iters.c
index 296fc1f51c..2fe1486691 100644
--- a/ports/nrf/boards/microbit/modules/iters.c
+++ b/ports/nrf/boards/microbit/modules/iters.c
@@ -46,10 +46,9 @@ static mp_obj_t microbit_repeat_iter_next(mp_obj_t iter_in) {
MP_DEFINE_CONST_OBJ_TYPE(
microbit_repeat_iterator_type,
MP_QSTR_iterator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, microbit_repeat_iter_next
+ iter, microbit_repeat_iter_next
);
mp_obj_t microbit_repeat_iterator(mp_obj_t iterable) {
diff --git a/ports/nrf/boards/microbit/modules/microbitimage.c b/ports/nrf/boards/microbit/modules/microbitimage.c
index 4870b6738f..b22c2e29ac 100644
--- a/ports/nrf/boards/microbit/modules/microbitimage.c
+++ b/ports/nrf/boards/microbit/modules/microbitimage.c
@@ -824,18 +824,16 @@ STATIC mp_obj_t microbit_scrolling_string_iter_next(mp_obj_t o_in) {
MP_DEFINE_CONST_OBJ_TYPE(
microbit_scrolling_string_type,
MP_QSTR_ScrollingString,
- MP_TYPE_FLAG_NONE,
- MP_TYPE_NULL_MAKE_NEW,
- getiter, get_microbit_scrolling_string_iter
+ MP_TYPE_FLAG_ITER_IS_GETITER,
+ iter, get_microbit_scrolling_string_iter
);
MP_DEFINE_CONST_OBJ_TYPE(
microbit_scrolling_string_iterator_type,
MP_QSTR_iterator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, microbit_scrolling_string_iter_next
+ iter, microbit_scrolling_string_iter_next
);
/** Facade types to present a string as a sequence of images.
@@ -877,11 +875,10 @@ static mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t
MP_DEFINE_CONST_OBJ_TYPE(
string_image_facade_type,
MP_QSTR_Facade,
- MP_TYPE_FLAG_NONE,
- MP_TYPE_NULL_MAKE_NEW,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
unary_op, facade_unary_op,
subscr, string_image_facade_subscr,
- getiter, microbit_facade_iterator
+ iter, microbit_facade_iterator
);
@@ -914,10 +911,9 @@ static mp_obj_t microbit_facade_iter_next(mp_obj_t iter_in) {
MP_DEFINE_CONST_OBJ_TYPE(
microbit_facade_iterator_type,
MP_QSTR_iterator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, microbit_facade_iter_next
+ iter, microbit_facade_iter_next
);
mp_obj_t microbit_facade_iterator(mp_obj_t iterable_in, mp_obj_iter_buf_t *iter_buf) {
diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c
index fc0bd682b4..ca0fcf859a 100644
--- a/ports/nrf/modules/machine/uart.c
+++ b/ports/nrf/modules/machine/uart.c
@@ -373,11 +373,9 @@ STATIC const mp_stream_p_t uart_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_hard_uart_type,
MP_QSTR_UART,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_hard_uart_make_new,
print, machine_hard_uart_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &uart_stream_p,
locals_dict, &machine_hard_uart_locals_dict
);
diff --git a/ports/renesas-ra/machine_uart.c b/ports/renesas-ra/machine_uart.c
index 11f5d6825e..6fa84ca821 100644
--- a/ports/renesas-ra/machine_uart.c
+++ b/ports/renesas-ra/machine_uart.c
@@ -574,12 +574,10 @@ STATIC const mp_stream_p_t uart_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_uart_type,
MP_QSTR_UART,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_uart_make_new,
locals_dict, &machine_uart_locals_dict,
print, machine_uart_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &uart_stream_p
);
diff --git a/ports/rp2/machine_i2s.c b/ports/rp2/machine_i2s.c
index 9d70a476f3..53ff7417d7 100644
--- a/ports/rp2/machine_i2s.c
+++ b/ports/rp2/machine_i2s.c
@@ -1140,11 +1140,9 @@ STATIC const mp_stream_p_t i2s_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_i2s_type,
MP_QSTR_I2S,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_i2s_make_new,
print, machine_i2s_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &i2s_stream_p,
locals_dict, &machine_i2s_locals_dict
);
diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c
index bb8bf51be6..06f7e9aaac 100644
--- a/ports/rp2/machine_uart.c
+++ b/ports/rp2/machine_uart.c
@@ -582,11 +582,9 @@ STATIC const mp_stream_p_t uart_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_uart_type,
MP_QSTR_UART,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_uart_make_new,
print, machine_uart_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &uart_stream_p,
locals_dict, &machine_uart_locals_dict
);
diff --git a/ports/stm32/machine_i2s.c b/ports/stm32/machine_i2s.c
index 93a465d07c..d68648bc34 100644
--- a/ports/stm32/machine_i2s.c
+++ b/ports/stm32/machine_i2s.c
@@ -1117,11 +1117,9 @@ STATIC const mp_stream_p_t i2s_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_i2s_type,
MP_QSTR_I2S,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_i2s_make_new,
print, machine_i2s_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &i2s_stream_p,
locals_dict, &machine_i2s_locals_dict
);
diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c
index 5851d8cf35..4ccff8c136 100644
--- a/ports/stm32/machine_uart.c
+++ b/ports/stm32/machine_uart.c
@@ -663,11 +663,9 @@ STATIC const mp_stream_p_t uart_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
pyb_uart_type,
MP_QSTR_UART,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
pyb_uart_make_new,
print, pyb_uart_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &uart_stream_p,
locals_dict, &pyb_uart_locals_dict
);
diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c
index df755fe984..e389ef68f2 100644
--- a/ports/stm32/usb.c
+++ b/ports/stm32/usb.c
@@ -939,11 +939,9 @@ STATIC const mp_stream_p_t pyb_usb_vcp_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
pyb_usb_vcp_type,
MP_QSTR_USB_VCP,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
pyb_usb_vcp_make_new,
print, pyb_usb_vcp_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &pyb_usb_vcp_stream_p,
locals_dict, &pyb_usb_vcp_locals_dict
);
diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c
index 02368e4537..e6b874b235 100644
--- a/ports/unix/modjni.c
+++ b/ports/unix/modjni.c
@@ -325,13 +325,13 @@ STATIC mp_obj_t subscr_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
STATIC MP_DEFINE_CONST_OBJ_TYPE(
jobject_type,
MP_QSTR_jobject,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
MP_TYPE_NULL_MAKE_NEW,
print, jobject_print,
unary_op, jobject_unary_op,
attr, jobject_attr,
subscr, jobject_subscr,
- getiter, subscr_getiter,
+ iter, subscr_getiter,
// .locals_dict = &jobject_locals_dict,
);
diff --git a/ports/unix/moduselect.c b/ports/unix/moduselect.c
index baed88761c..674841bf18 100644
--- a/ports/unix/moduselect.c
+++ b/ports/unix/moduselect.c
@@ -314,10 +314,9 @@ STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_poll,
MP_QSTR_poll,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, poll_iternext,
+ iter, poll_iternext,
locals_dict, &poll_locals_dict
);
diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c
index 21260f0b2a..dfbf15cd3e 100644
--- a/ports/unix/modusocket.c
+++ b/ports/unix/modusocket.c
@@ -522,8 +522,6 @@ MP_DEFINE_CONST_OBJ_TYPE(
MP_TYPE_FLAG_NONE,
socket_make_new,
print, socket_print,
- getiter, NULL,
- iternext, NULL,
protocol, &usocket_stream_p,
locals_dict, &usocket_locals_dict
);
diff --git a/ports/zephyr/machine_uart.c b/ports/zephyr/machine_uart.c
index 9580d37907..867c5ae886 100644
--- a/ports/zephyr/machine_uart.c
+++ b/ports/zephyr/machine_uart.c
@@ -157,11 +157,9 @@ STATIC const mp_stream_p_t uart_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
machine_uart_type,
MP_QSTR_UART,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
machine_uart_make_new,
print, machine_uart_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &uart_stream_p,
locals_dict, &machine_uart_locals_dict
);
diff --git a/py/obj.c b/py/obj.c
index 359c73b9c2..eb17308fed 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -572,10 +572,10 @@ mp_obj_t mp_identity(mp_obj_t self) {
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity);
-mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) {
- (void)iter_buf;
- return self;
-}
+// mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) {
+// (void)iter_buf;
+// return self;
+// }
bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
const mp_obj_type_t *type = mp_obj_get_type(obj);
diff --git a/py/obj.h b/py/obj.h
index 878fa67348..b1d722080c 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -507,12 +507,20 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *);
// Flags for type behaviour (mp_obj_type_t.flags)
// If MP_TYPE_FLAG_EQ_NOT_REFLEXIVE is clear then __eq__ is reflexive (A==A returns True).
// If MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE is clear then the type can't be equal to an
-// instance of any different class that also clears this flag. If this flag is set
-// then the type may check for equality against a different type.
+// instance of any different class that also clears this flag. If this flag is set
+// then the type may check for equality against a different type.
// If MP_TYPE_FLAG_EQ_HAS_NEQ_TEST is clear then the type only implements the __eq__
-// operator and not the __ne__ operator. If it's set then __ne__ may be implemented.
+// operator and not the __ne__ operator. If it's set then __ne__ may be implemented.
// If MP_TYPE_FLAG_BINDS_SELF is set then the type as a method binds self as the first arg.
// If MP_TYPE_FLAG_BUILTIN_FUN is set then the type is a built-in function type.
+// MP_TYPE_FLAG_ITER_IS_GETITER is a no-op flag that means the default behaviour for the
+// iter slot and it's the getiter function.
+// If MP_TYPE_FLAG_ITER_IS_ITERNEXT is set then the "iter" slot is the iternext
+// function and getiter will be automatically implemented as "return self".
+// If MP_TYPE_FLAG_ITER_IS_CUSTOM is set then the "iter" slot is a pointer to a
+// mp_getiter_iternext_custom_t struct instance (with both .getiter and .iternext set).
+// If MP_TYPE_FLAG_ITER_IS_STREAM is set then the type implicitly gets a "return self"
+// getiter, and mp_stream_unbuffered_iter for iternext.
#define MP_TYPE_FLAG_NONE (0x0000)
#define MP_TYPE_FLAG_IS_SUBCLASSED (0x0001)
#define MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS (0x0002)
@@ -521,6 +529,10 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *);
#define MP_TYPE_FLAG_EQ_HAS_NEQ_TEST (0x0010)
#define MP_TYPE_FLAG_BINDS_SELF (0x0020)
#define MP_TYPE_FLAG_BUILTIN_FUN (0x0040)
+#define MP_TYPE_FLAG_ITER_IS_GETITER (0x0000)
+#define MP_TYPE_FLAG_ITER_IS_ITERNEXT (0x0080)
+#define MP_TYPE_FLAG_ITER_IS_CUSTOM (0x0100)
+#define MP_TYPE_FLAG_ITER_IS_STREAM (MP_TYPE_FLAG_ITER_IS_ITERNEXT | MP_TYPE_FLAG_ITER_IS_CUSTOM)
typedef enum {
PRINT_STR = 0,
@@ -548,6 +560,13 @@ typedef mp_obj_t (*mp_binary_op_fun_t)(mp_binary_op_t op, mp_obj_t, mp_obj_t);
typedef void (*mp_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest);
typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
typedef mp_obj_t (*mp_getiter_fun_t)(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf);
+typedef mp_fun_1_t mp_iternext_fun_t;
+
+// For MP_TYPE_FLAG_ITER_IS_CUSTOM, the "getiter" slot points to an instance of this type.
+typedef struct _mp_getiter_iternext_custom_t {
+ mp_getiter_fun_t getiter;
+ mp_iternext_fun_t iternext;
+} mp_getiter_iternext_custom_t;
// Buffer protocol
typedef struct _mp_buffer_info_t {
@@ -616,14 +635,17 @@ struct _mp_obj_type_t {
// Can return MP_OBJ_NULL if operation not supported.
uint8_t slot_index_subscr;
- // Corresponds to __iter__ special method.
- // Can use the given mp_obj_iter_buf_t to store iterator object,
- // otherwise can return a pointer to an object on the heap.
- uint8_t slot_index_getiter;
-
- // Corresponds to __next__ special method. May return MP_OBJ_STOP_ITERATION
- // as an optimisation instead of raising StopIteration() with no args.
- uint8_t slot_index_iternext;
+ // This slot's behaviour depends on the MP_TYPE_FLAG_ITER_IS_* flags above.
+ // - If MP_TYPE_FLAG_ITER_IS_GETITER flag is set, then this corresponds to the __iter__
+ // special method (of type mp_getiter_fun_t). Can use the given mp_obj_iter_buf_t
+ // to store the iterator object, otherwise can return a pointer to an object on the heap.
+ // - If MP_TYPE_FLAG_ITER_IS_ITERNEXT is set, then this corresponds to __next__ special method.
+ // May return MP_OBJ_STOP_ITERATION as an optimisation instead of raising StopIteration()
+ // with no args. The type will implicitly implement getiter as "return self".
+ // - If MP_TYPE_FLAG_ITER_IS_CUSTOM is set, then this slot must point to an
+ // mp_getiter_iternext_custom_t instance with both the getiter and iternext fields set.
+ // - If MP_TYPE_FLAG_ITER_IS_STREAM is set, this this slot should be unset.
+ uint8_t slot_index_iter;
// Implements the buffer protocol if supported by this type.
uint8_t slot_index_buffer;
@@ -659,8 +681,7 @@ typedef struct _mp_obj_empty_type_t {
uint8_t slot_index_binary_op;
uint8_t slot_index_attr;
uint8_t slot_index_subscr;
- uint8_t slot_index_getiter;
- uint8_t slot_index_iternext;
+ uint8_t slot_index_iter;
uint8_t slot_index_buffer;
uint8_t slot_index_protocol;
uint8_t slot_index_parent;
@@ -681,15 +702,14 @@ typedef struct _mp_obj_full_type_t {
uint8_t slot_index_binary_op;
uint8_t slot_index_attr;
uint8_t slot_index_subscr;
- uint8_t slot_index_getiter;
- uint8_t slot_index_iternext;
+ uint8_t slot_index_iter;
uint8_t slot_index_buffer;
uint8_t slot_index_protocol;
uint8_t slot_index_parent;
uint8_t slot_index_locals_dict;
// Explicitly add 12 slots.
- const void *slots[12];
+ const void *slots[11];
} mp_obj_full_type_t;
#define MP_TYPE_NULL_MAKE_NEW (NULL)
@@ -700,8 +720,7 @@ typedef struct _mp_obj_full_type_t {
#define _MP_OBJ_TYPE_SLOT_TYPE_binary_op (mp_binary_op_fun_t)
#define _MP_OBJ_TYPE_SLOT_TYPE_attr (mp_attr_fun_t)
#define _MP_OBJ_TYPE_SLOT_TYPE_subscr (mp_subscr_fun_t)
-#define _MP_OBJ_TYPE_SLOT_TYPE_getiter (mp_getiter_fun_t)
-#define _MP_OBJ_TYPE_SLOT_TYPE_iternext (mp_fun_1_t)
+#define _MP_OBJ_TYPE_SLOT_TYPE_iter (const void *)
#define _MP_OBJ_TYPE_SLOT_TYPE_buffer (mp_buffer_fun_t)
#define _MP_OBJ_TYPE_SLOT_TYPE_protocol (const void *)
#define _MP_OBJ_TYPE_SLOT_TYPE_parent (const void *)
@@ -1162,7 +1181,6 @@ qstr mp_obj_fun_get_name(mp_const_obj_t fun);
mp_obj_t mp_identity(mp_obj_t self);
MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj);
-mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf);
// module
typedef struct _mp_obj_module_t {
diff --git a/py/objarray.c b/py/objarray.c
index 762a4105c5..0d1032929f 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -574,10 +574,10 @@ STATIC mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_ui
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_array,
MP_QSTR_array,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
array_make_new,
print, array_print,
- getiter, array_iterator_new,
+ iter, array_iterator_new,
unary_op, array_unary_op,
binary_op, array_binary_op,
subscr, array_subscr,
@@ -590,10 +590,10 @@ MP_DEFINE_CONST_OBJ_TYPE(
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_bytearray,
MP_QSTR_bytearray,
- MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE,
+ MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER,
bytearray_make_new,
print, array_print,
- getiter, array_iterator_new,
+ iter, array_iterator_new,
unary_op, array_unary_op,
binary_op, array_binary_op,
subscr, array_subscr,
@@ -618,9 +618,9 @@ MP_DEFINE_CONST_OBJ_TYPE(
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_memoryview,
MP_QSTR_memoryview,
- MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE,
+ MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER,
memoryview_make_new,
- getiter, array_iterator_new,
+ iter, array_iterator_new,
unary_op, array_unary_op,
binary_op, array_binary_op,
MEMORYVIEW_TYPE_LOCALS_DICT
@@ -676,10 +676,9 @@ STATIC mp_obj_t array_it_iternext(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_array_it,
MP_QSTR_iterator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, array_it_iternext
+ iter, array_it_iternext
);
STATIC mp_obj_t array_iterator_new(mp_obj_t array_in, mp_obj_iter_buf_t *iter_buf) {
diff --git a/py/objattrtuple.c b/py/objattrtuple.c
index 0d41ee5235..2e207f4cf0 100644
--- a/py/objattrtuple.c
+++ b/py/objattrtuple.c
@@ -83,7 +83,7 @@ mp_obj_t mp_obj_new_attrtuple(const qstr *fields, size_t n, const mp_obj_t *item
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_attrtuple,
MP_QSTR_tuple,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
MP_TYPE_NULL_MAKE_NEW,
// reuse tuple to save on a qstr
print, mp_obj_attrtuple_print,
@@ -91,7 +91,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
binary_op, mp_obj_tuple_binary_op,
attr, mp_obj_attrtuple_attr,
subscr, mp_obj_tuple_subscr,
- getiter, mp_obj_tuple_getiter
+ iter, mp_obj_tuple_getiter
);
#endif // MICROPY_PY_ATTRTUPLE
diff --git a/py/objdict.c b/py/objdict.c
index c65b14caad..7755d7b786 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -464,10 +464,9 @@ STATIC mp_obj_t dict_view_it_iternext(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_dict_view_it,
MP_QSTR_iterator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, dict_view_it_iternext
+ iter, dict_view_it_iternext
);
STATIC mp_obj_t dict_view_getiter(mp_obj_t view_in, mp_obj_iter_buf_t *iter_buf) {
@@ -517,11 +516,11 @@ STATIC mp_obj_t dict_view_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_dict_view,
MP_QSTR_dict_view,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
MP_TYPE_NULL_MAKE_NEW,
print, dict_view_print,
binary_op, dict_view_binary_op,
- getiter, dict_view_getiter
+ iter, dict_view_getiter
);
STATIC mp_obj_t mp_obj_new_dict_view(mp_obj_t dict, mp_dict_view_kind_t kind) {
@@ -592,13 +591,13 @@ STATIC MP_DEFINE_CONST_DICT(dict_locals_dict, dict_locals_dict_table);
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_dict,
MP_QSTR_dict,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
mp_obj_dict_make_new,
print, dict_print,
unary_op, dict_unary_op,
binary_op, dict_binary_op,
subscr, dict_subscr,
- getiter, dict_getiter,
+ iter, dict_getiter,
locals_dict, &dict_locals_dict
);
@@ -606,13 +605,13 @@ MP_DEFINE_CONST_OBJ_TYPE(
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_ordereddict,
MP_QSTR_OrderedDict,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
mp_obj_dict_make_new,
print, dict_print,
unary_op, dict_unary_op,
binary_op, dict_binary_op,
subscr, dict_subscr,
- getiter, dict_getiter,
+ iter, dict_getiter,
parent, &mp_type_dict,
locals_dict, &dict_locals_dict
);
diff --git a/py/objenumerate.c b/py/objenumerate.c
index f4f4ff6ae1..eea9e3e381 100644
--- a/py/objenumerate.c
+++ b/py/objenumerate.c
@@ -70,10 +70,9 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_enumerate,
MP_QSTR_enumerate,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
enumerate_make_new,
- iternext, enumerate_iternext,
- getiter, mp_identity_getiter
+ iter, enumerate_iternext
);
STATIC mp_obj_t enumerate_iternext(mp_obj_t self_in) {
diff --git a/py/objfilter.c b/py/objfilter.c
index 2b57300af3..bfe651f40d 100644
--- a/py/objfilter.c
+++ b/py/objfilter.c
@@ -63,10 +63,9 @@ STATIC mp_obj_t filter_iternext(mp_obj_t self_in) {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_filter,
MP_QSTR_filter,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
filter_make_new,
- getiter, mp_identity_getiter,
- iternext, filter_iternext
+ iter, filter_iternext
);
#endif // MICROPY_PY_BUILTINS_FILTER
diff --git a/py/objgenerator.c b/py/objgenerator.c
index a960c23700..d8515c13ce 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -370,11 +370,10 @@ STATIC MP_DEFINE_CONST_DICT(gen_instance_locals_dict, gen_instance_locals_dict_t
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_gen_instance,
MP_QSTR_generator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
print, gen_instance_print,
unary_op, mp_generic_unary_op,
- getiter, mp_identity_getiter,
- iternext, gen_instance_iternext,
+ iter, gen_instance_iternext,
locals_dict, &gen_instance_locals_dict
);
diff --git a/py/objgetitemiter.c b/py/objgetitemiter.c
index ed2dfbbe1f..134cbcd629 100644
--- a/py/objgetitemiter.c
+++ b/py/objgetitemiter.c
@@ -59,10 +59,9 @@ STATIC mp_obj_t it_iternext(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_it,
MP_QSTR_iterator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, it_iternext
+ iter, it_iternext
);
// args are those returned from mp_load_method_maybe (ie either an attribute or a method)
diff --git a/py/objlist.c b/py/objlist.c
index 5f9e99cc79..8d18344ea8 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -455,13 +455,13 @@ STATIC MP_DEFINE_CONST_DICT(list_locals_dict, list_locals_dict_table);
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_list,
MP_QSTR_list,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
list_make_new,
print, list_print,
unary_op, list_unary_op,
binary_op, list_binary_op,
subscr, list_subscr,
- getiter, list_getiter,
+ iter, list_getiter,
locals_dict, &list_locals_dict
);
diff --git a/py/objmap.c b/py/objmap.c
index dc305e21b5..115832e387 100644
--- a/py/objmap.c
+++ b/py/objmap.c
@@ -66,8 +66,7 @@ STATIC mp_obj_t map_iternext(mp_obj_t self_in) {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_map,
MP_QSTR_map,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
map_make_new,
- getiter, mp_identity_getiter,
- iternext, map_iternext
+ iter, map_iternext
);
diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c
index 52536be8b4..3b45d8f76f 100644
--- a/py/objnamedtuple.c
+++ b/py/objnamedtuple.c
@@ -163,7 +163,7 @@ STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t
MP_OBJ_TYPE_SET_SLOT(type, binary_op, mp_obj_tuple_binary_op, 2);
MP_OBJ_TYPE_SET_SLOT(type, attr, namedtuple_attr, 3);
MP_OBJ_TYPE_SET_SLOT(type, subscr, mp_obj_tuple_subscr, 4);
- MP_OBJ_TYPE_SET_SLOT(type, getiter, mp_obj_tuple_getiter, 5);
+ MP_OBJ_TYPE_SET_SLOT(type, iter, mp_obj_tuple_getiter, 5);
MP_OBJ_TYPE_SET_SLOT(type, parent, &mp_type_tuple, 6);
return MP_OBJ_FROM_PTR(o);
}
diff --git a/py/objpolyiter.c b/py/objpolyiter.c
index 5bc397f6ec..7a45b6b73f 100644
--- a/py/objpolyiter.c
+++ b/py/objpolyiter.c
@@ -48,10 +48,9 @@ STATIC mp_obj_t polymorph_it_iternext(mp_obj_t self_in) {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_polymorph_iter,
MP_QSTR_iterator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, polymorph_it_iternext
+ iter, polymorph_it_iternext
);
#if MICROPY_ENABLE_FINALISER
@@ -81,10 +80,9 @@ STATIC MP_DEFINE_CONST_DICT(mp_obj_polymorph_iter_locals_dict, mp_obj_polymorph_
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_polymorph_iter_with_finaliser,
MP_QSTR_iterator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, polymorph_it_iternext,
+ iter, polymorph_it_iternext,
locals_dict, &mp_obj_polymorph_iter_locals_dict
);
#endif
diff --git a/py/objrange.c b/py/objrange.c
index 3140504b2b..1ad8f6031f 100644
--- a/py/objrange.c
+++ b/py/objrange.c
@@ -53,10 +53,9 @@ STATIC mp_obj_t range_it_iternext(mp_obj_t o_in) {
STATIC MP_DEFINE_CONST_OBJ_TYPE(
mp_type_range_it,
MP_QSTR_iterator,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
MP_TYPE_NULL_MAKE_NEW,
- getiter, mp_identity_getiter,
- iternext, range_it_iternext
+ iter, range_it_iternext
);
STATIC mp_obj_t mp_obj_new_range_iterator(mp_int_t cur, mp_int_t stop, mp_int_t step, mp_obj_iter_buf_t *iter_buf) {
@@ -232,5 +231,5 @@ MP_DEFINE_CONST_OBJ_TYPE(
print, range_print,
unary_op, range_unary_op,
subscr, range_subscr,
- getiter, range_getiter
+ iter, range_getiter
);
diff --git a/py/objreversed.c b/py/objreversed.c
index bc1f07ddec..e265266d3f 100644
--- a/py/objreversed.c
+++ b/py/objreversed.c
@@ -71,10 +71,9 @@ STATIC mp_obj_t reversed_iternext(mp_obj_t self_in) {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_reversed,
MP_QSTR_reversed,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
reversed_make_new,
- getiter, mp_identity_getiter,
- iternext, reversed_iternext
+ iter, reversed_iternext
);
#endif // MICROPY_PY_BUILTINS_REVERSED
diff --git a/py/objset.c b/py/objset.c
index 6f21bf15df..b827f49f40 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -542,12 +542,12 @@ STATIC MP_DEFINE_CONST_DICT(set_locals_dict, set_locals_dict_table);
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_set,
MP_QSTR_set,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
set_make_new,
print, set_print,
unary_op, set_unary_op,
binary_op, set_binary_op,
- getiter, set_getiter,
+ iter, set_getiter,
locals_dict, &set_locals_dict
);
@@ -568,12 +568,12 @@ STATIC MP_DEFINE_CONST_DICT(frozenset_locals_dict, frozenset_locals_dict_table);
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_frozenset,
MP_QSTR_frozenset,
- MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE,
+ MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER,
set_make_new,
print, set_print,
unary_op, set_unary_op,
binary_op, set_binary_op,
- getiter, set_getiter,
+ iter, set_getiter,
locals_dict, &frozenset_locals_dict
);
#endif
diff --git a/py/objstr.c b/py/objstr.c
index d425055559..12f6e15d04 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -2151,7 +2151,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
print, str_print,
binary_op, mp_obj_str_binary_op,
subscr, bytes_subscr,
- getiter, mp_obj_new_str_iterator,
+ iter, mp_obj_new_str_iterator,
buffer, mp_obj_str_get_buffer,
locals_dict, &mp_obj_str_locals_dict
);
@@ -2166,7 +2166,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
print, str_print,
binary_op, mp_obj_str_binary_op,
subscr, bytes_subscr,
- getiter, mp_obj_new_bytes_iterator,
+ iter, mp_obj_new_bytes_iterator,
buffer, mp_obj_str_get_buffer,
locals_dict, &mp_obj_bytes_locals_dict
);
diff --git a/py/objstringio.c b/py/objstringio.c
index 77547f88cf..4e19b83999 100644
--- a/py/objstringio.c
+++ b/py/objstringio.c
@@ -247,11 +247,9 @@ STATIC const mp_stream_p_t stringio_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_stringio,
MP_QSTR_StringIO,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
stringio_make_new,
print, stringio_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &stringio_stream_p,
locals_dict, &stringio_locals_dict
);
@@ -266,11 +264,9 @@ STATIC const mp_stream_p_t bytesio_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_bytesio,
MP_QSTR_BytesIO,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
stringio_make_new,
print, stringio_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &bytesio_stream_p,
locals_dict, &stringio_locals_dict
);
diff --git a/py/objstrunicode.c b/py/objstrunicode.c
index 15c59e4e95..9b28841ecd 100644
--- a/py/objstrunicode.c
+++ b/py/objstrunicode.c
@@ -232,13 +232,13 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_str,
MP_QSTR_str,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
mp_obj_str_make_new,
print, uni_print,
unary_op, uni_unary_op,
binary_op, mp_obj_str_binary_op,
subscr, str_subscr,
- getiter, mp_obj_new_str_iterator,
+ iter, mp_obj_new_str_iterator,
buffer, mp_obj_str_get_buffer,
locals_dict, &mp_obj_str_locals_dict
);
diff --git a/py/objtuple.c b/py/objtuple.c
index 01b2fa1488..485d44c52a 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -32,7 +32,7 @@
#include "py/runtime.h"
// type check is done on getiter method to allow tuple, namedtuple, attrtuple
-#define mp_obj_is_tuple_compatible(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), getiter) == mp_obj_tuple_getiter)
+#define mp_obj_is_tuple_compatible(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), iter) == mp_obj_tuple_getiter)
/******************************************************************************/
/* tuple */
@@ -111,7 +111,7 @@ STATIC mp_obj_t tuple_cmp_helper(mp_uint_t op, mp_obj_t self_in, mp_obj_t anothe
mp_check_self(mp_obj_is_tuple_compatible(self_in));
const mp_obj_type_t *another_type = mp_obj_get_type(another_in);
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
- if (MP_OBJ_TYPE_GET_SLOT_OR_NULL(another_type, getiter) != mp_obj_tuple_getiter) {
+ if (MP_OBJ_TYPE_GET_SLOT_OR_NULL(another_type, iter) != mp_obj_tuple_getiter) {
// Slow path for user subclasses
another_in = mp_obj_cast_to_native_base(another_in, MP_OBJ_FROM_PTR(&mp_type_tuple));
if (another_in == MP_OBJ_NULL) {
@@ -227,13 +227,13 @@ STATIC MP_DEFINE_CONST_DICT(tuple_locals_dict, tuple_locals_dict_table);
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_tuple,
MP_QSTR_tuple,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_GETITER,
mp_obj_tuple_make_new,
print, mp_obj_tuple_print,
unary_op, mp_obj_tuple_unary_op,
binary_op, mp_obj_tuple_binary_op,
subscr, mp_obj_tuple_subscr,
- getiter, mp_obj_tuple_getiter,
+ iter, mp_obj_tuple_getiter,
locals_dict, &tuple_locals_dict
);
diff --git a/py/objtype.c b/py/objtype.c
index 5b4e375bcc..183dce071e 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -142,7 +142,10 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
// this should not be applied to class types, as will result in extra
// lookup either.
if (lookup->slot_offset != 0 && mp_obj_is_native_type(type)) {
- if (MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(type, lookup->slot_offset)) {
+ // Check if there is a non-zero value in the specified slot index,
+ // with a special case for getiter where the slot won't be set
+ // for MP_TYPE_FLAG_ITER_IS_STREAM.
+ if (MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(type, lookup->slot_offset) || (lookup->slot_offset == MP_OBJ_TYPE_OFFSETOF_SLOT(iter) && type->flags & MP_TYPE_FLAG_ITER_IS_STREAM)) {
DEBUG_printf("mp_obj_class_lookup: Matched special meth slot (off=%d) for %s\n",
lookup->slot_offset, qstr_str(lookup->attr));
lookup->dest[0] = MP_OBJ_SENTINEL;
@@ -889,7 +892,7 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf)
struct class_lookup_data lookup = {
.obj = self,
.attr = MP_QSTR___iter__,
- .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(getiter),
+ .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(iter),
.dest = member,
.is_type = false,
};
@@ -898,10 +901,14 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf)
return MP_OBJ_NULL;
} else if (member[0] == MP_OBJ_SENTINEL) {
const mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]);
- if (iter_buf == NULL) {
- iter_buf = m_new_obj(mp_obj_iter_buf_t);
+ if (type->flags & MP_TYPE_FLAG_ITER_IS_ITERNEXT) {
+ return self->subobj[0];
+ } else {
+ if (iter_buf == NULL) {
+ iter_buf = m_new_obj(mp_obj_iter_buf_t);
+ }
+ return ((mp_getiter_fun_t)MP_OBJ_TYPE_GET_SLOT(type, iter))(self->subobj[0], iter_buf);
}
- return MP_OBJ_TYPE_GET_SLOT(type, getiter)(self->subobj[0], iter_buf);
} else {
return mp_call_method_n_kw(0, 0, member);
}
@@ -1122,7 +1129,9 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
// Basic validation of base classes
uint16_t base_flags = MP_TYPE_FLAG_EQ_NOT_REFLEXIVE
- | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST;
+ | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE
+ | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST
+ | MP_TYPE_FLAG_ITER_IS_GETITER;
size_t bases_len;
mp_obj_t *bases_items;
mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items);
@@ -1167,7 +1176,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
MP_OBJ_TYPE_SET_SLOT(o, binary_op, instance_binary_op, 3);
MP_OBJ_TYPE_SET_SLOT(o, attr, mp_obj_instance_attr, 4);
MP_OBJ_TYPE_SET_SLOT(o, subscr, instance_subscr, 5);
- MP_OBJ_TYPE_SET_SLOT(o, getiter, mp_obj_instance_getiter, 6);
+ MP_OBJ_TYPE_SET_SLOT(o, iter, mp_obj_instance_getiter, 6);
// MP_OBJ_TYPE_SET_SLOT(o, iternext, not implemented)
MP_OBJ_TYPE_SET_SLOT(o, buffer, instance_get_buffer, 7);
diff --git a/py/objzip.c b/py/objzip.c
index 0ceafd97f2..34d73465ef 100644
--- a/py/objzip.c
+++ b/py/objzip.c
@@ -69,8 +69,7 @@ STATIC mp_obj_t zip_iternext(mp_obj_t self_in) {
MP_DEFINE_CONST_OBJ_TYPE(
mp_type_zip,
MP_QSTR_zip,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_ITERNEXT,
zip_make_new,
- getiter, mp_identity_getiter,
- iternext, zip_iternext
+ iter, zip_iternext
);
diff --git a/py/runtime.c b/py/runtime.c
index d0e504a3d0..ec628bfe14 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -61,6 +61,8 @@ const mp_obj_module_t mp_module___main__ = {
MP_REGISTER_MODULE(MP_QSTR___main__, mp_module___main__);
+#define TYPE_HAS_ITERNEXT(type) (type->flags & (MP_TYPE_FLAG_ITER_IS_ITERNEXT | MP_TYPE_FLAG_ITER_IS_CUSTOM | MP_TYPE_FLAG_ITER_IS_STREAM))
+
void mp_init(void) {
qstr_init();
@@ -1167,7 +1169,7 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) {
}
#endif
- if (attr == MP_QSTR___next__ && MP_OBJ_TYPE_HAS_SLOT(type, iternext)) {
+ if (attr == MP_QSTR___next__ && TYPE_HAS_ITERNEXT(type)) {
dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj);
dest[1] = obj;
return;
@@ -1260,21 +1262,26 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
assert(o_in);
const mp_obj_type_t *type = mp_obj_get_type(o_in);
+ // Most types that use iternext just use the identity getiter. We handle this case explicitly
+ // so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used.
+ if ((type->flags & MP_TYPE_FLAG_ITER_IS_ITERNEXT) == MP_TYPE_FLAG_ITER_IS_ITERNEXT || (type->flags & MP_TYPE_FLAG_ITER_IS_STREAM) == MP_TYPE_FLAG_ITER_IS_STREAM) {
+ return o_in;
+ }
- if (MP_OBJ_TYPE_HAS_SLOT(type, getiter)) {
- // Check for native getiter which is the identity. We handle this case explicitly
- // so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used.
- if (MP_OBJ_TYPE_GET_SLOT(type, getiter) == mp_identity_getiter) {
- return o_in;
- }
-
+ if (MP_OBJ_TYPE_HAS_SLOT(type, iter)) {
// check for native getiter (corresponds to __iter__)
- if (iter_buf == NULL && MP_OBJ_TYPE_GET_SLOT(type, getiter) != mp_obj_instance_getiter) {
+ if (iter_buf == NULL && MP_OBJ_TYPE_GET_SLOT(type, iter) != mp_obj_instance_getiter) {
// if caller did not provide a buffer then allocate one on the heap
// mp_obj_instance_getiter is special, it will allocate only if needed
iter_buf = m_new_obj(mp_obj_iter_buf_t);
}
- mp_obj_t iter = MP_OBJ_TYPE_GET_SLOT(type, getiter)(o_in, iter_buf);
+ mp_getiter_fun_t getiter;
+ if (type->flags & MP_TYPE_FLAG_ITER_IS_CUSTOM) {
+ getiter = ((mp_getiter_iternext_custom_t *)MP_OBJ_TYPE_GET_SLOT(type, iter))->getiter;
+ } else {
+ getiter = (mp_getiter_fun_t)MP_OBJ_TYPE_GET_SLOT(type, iter);
+ }
+ mp_obj_t iter = getiter(o_in, iter_buf);
if (iter != MP_OBJ_NULL) {
return iter;
}
@@ -1302,13 +1309,26 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
}
+STATIC mp_fun_1_t type_get_iternext(const mp_obj_type_t *type) {
+ if ((type->flags & MP_TYPE_FLAG_ITER_IS_STREAM) == MP_TYPE_FLAG_ITER_IS_STREAM) {
+ mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self);
+ return mp_stream_unbuffered_iter;
+ } else if (type->flags & MP_TYPE_FLAG_ITER_IS_ITERNEXT) {
+ return (mp_fun_1_t)MP_OBJ_TYPE_GET_SLOT(type, iter);
+ } else if (type->flags & MP_TYPE_FLAG_ITER_IS_CUSTOM) {
+ return ((mp_getiter_iternext_custom_t *)MP_OBJ_TYPE_GET_SLOT(type, iter))->iternext;
+ } else {
+ return NULL;
+ }
+}
+
// may return MP_OBJ_STOP_ITERATION as an optimisation instead of raise StopIteration()
// may also raise StopIteration()
mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
const mp_obj_type_t *type = mp_obj_get_type(o_in);
- if (MP_OBJ_TYPE_HAS_SLOT(type, iternext)) {
+ if (TYPE_HAS_ITERNEXT(type)) {
MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
- return MP_OBJ_TYPE_GET_SLOT(type, iternext)(o_in);
+ return type_get_iternext(type)(o_in);
} else {
// check for __next__ method
mp_obj_t dest[2];
@@ -1332,9 +1352,9 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
mp_obj_t mp_iternext(mp_obj_t o_in) {
MP_STACK_CHECK(); // enumerate, filter, map and zip can recursively call mp_iternext
const mp_obj_type_t *type = mp_obj_get_type(o_in);
- if (MP_OBJ_TYPE_HAS_SLOT(type, iternext)) {
+ if (TYPE_HAS_ITERNEXT(type)) {
MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
- return MP_OBJ_TYPE_GET_SLOT(type, iternext)(o_in);
+ return type_get_iternext(type)(o_in);
} else {
// check for __next__ method
mp_obj_t dest[2];
@@ -1372,9 +1392,9 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val);
}
- if (MP_OBJ_TYPE_HAS_SLOT(type, iternext) && send_value == mp_const_none) {
+ if (TYPE_HAS_ITERNEXT(type) && send_value == mp_const_none) {
MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
- mp_obj_t ret = MP_OBJ_TYPE_GET_SLOT(type, iternext)(self_in);
+ mp_obj_t ret = type_get_iternext(type)(self_in);
*ret_val = ret;
if (ret != MP_OBJ_STOP_ITERATION) {
return MP_VM_RETURN_YIELD;
diff --git a/shared/runtime/sys_stdio_mphal.c b/shared/runtime/sys_stdio_mphal.c
index 6d43425e29..325f93dde1 100644
--- a/shared/runtime/sys_stdio_mphal.c
+++ b/shared/runtime/sys_stdio_mphal.c
@@ -126,11 +126,9 @@ STATIC const mp_stream_p_t stdio_obj_stream_p = {
MP_DEFINE_CONST_OBJ_TYPE(
stdio_obj_type,
MP_QSTR_FileIO,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
MP_TYPE_NULL_MAKE_NEW,
print, stdio_obj_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &stdio_obj_stream_p,
locals_dict, &stdio_locals_dict
);
@@ -162,11 +160,9 @@ STATIC const mp_stream_p_t stdio_buffer_obj_stream_p = {
STATIC MP_DEFINE_CONST_OBJ_TYPE(
stdio_buffer_obj_type,
MP_QSTR_FileIO,
- MP_TYPE_FLAG_NONE,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
MP_TYPE_NULL_MAKE_NEW,
print, stdio_obj_print,
- getiter, mp_identity_getiter,
- iternext, mp_stream_unbuffered_iter,
protocol, &stdio_buffer_obj_stream_p,
locals_dict, &stdio_locals_dict
);
diff --git a/tests/basics/io_stringio_base.py b/tests/basics/io_stringio_base.py
new file mode 100644
index 0000000000..dffc879074
--- /dev/null
+++ b/tests/basics/io_stringio_base.py
@@ -0,0 +1,24 @@
+# Checks that an instance type inheriting from a native base that uses
+# MP_TYPE_FLAG_ITER_IS_STREAM will still have a getiter.
+
+try:
+ import uio as io
+except ImportError:
+ import io
+
+a = io.StringIO()
+a.write("hello\nworld\nmicro\npython\n")
+a.seek(0)
+
+for line in a:
+ print(line)
+
+class X(io.StringIO):
+ pass
+
+b = X()
+b.write("hello\nworld\nmicro\npython\n")
+b.seek(0)
+
+for line in b:
+ print(line)