py/objtuple: Allow compatible subclasses of tuple in mp_obj_tuple_get.

As part of this patch a private macro mp_obj_is_tuple_compatible is
introduced to encapsulate the check, which is used in two locations.

Fixes #5005.
This commit is contained in:
Jeff Epler 2019-08-13 07:07:49 -05:00 committed by Damien George
parent 0b85b5b8b3
commit 12f13ee634

View File

@ -31,6 +31,9 @@
#include "py/objtuple.h"
#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_get_type(o)->getiter == mp_obj_tuple_getiter)
/******************************************************************************/
/* tuple */
@ -101,8 +104,7 @@ STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_arg
// Don't pass MP_BINARY_OP_NOT_EQUAL here
STATIC mp_obj_t tuple_cmp_helper(mp_uint_t op, mp_obj_t self_in, mp_obj_t another_in) {
// type check is done on getiter method to allow tuple, namedtuple, attrtuple
mp_check_self(mp_obj_get_type(self_in)->getiter == mp_obj_tuple_getiter);
mp_check_self(mp_obj_is_tuple_compatible(self_in));
mp_obj_type_t *another_type = mp_obj_get_type(another_in);
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
if (another_type->getiter != mp_obj_tuple_getiter) {
@ -249,7 +251,7 @@ mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items) {
}
void mp_obj_tuple_get(mp_obj_t self_in, size_t *len, mp_obj_t **items) {
assert(mp_obj_is_type(self_in, &mp_type_tuple));
assert(mp_obj_is_tuple_compatible(self_in));
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
*len = self->len;
*items = &self->items[0];