summaryrefslogtreecommitdiffstatshomepage
path: root/py/objtype.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/objtype.c')
-rw-r--r--py/objtype.c23
1 files changed, 16 insertions, 7 deletions
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);