diff --git a/py/obj.c b/py/obj.c index 9a81d65eca..d2483ed993 100644 --- a/py/obj.c +++ b/py/obj.c @@ -444,7 +444,7 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { // note: returned value in *items may point to the interior of a GC block void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { - if (mp_obj_is_type(o, &mp_type_tuple)) { + if (mp_obj_is_tuple_compatible(o)) { mp_obj_tuple_get(o, len, items); } else if (mp_obj_is_type(o, &mp_type_list)) { mp_obj_list_get(o, len, items); diff --git a/py/obj.h b/py/obj.h index 75caf459d4..da2ef08451 100644 --- a/py/obj.h +++ b/py/obj.h @@ -764,6 +764,8 @@ extern const struct _mp_obj_exception_t mp_const_GeneratorExit_obj; #define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->binary_op == mp_obj_str_binary_op)) #define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->make_new == mp_obj_dict_make_new) #define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function)) +// 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) mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); static inline mp_obj_t mp_obj_new_bool(mp_int_t x) { diff --git a/py/objtuple.c b/py/objtuple.c index bb4f79997c..414cf65c3b 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -34,8 +34,6 @@ #include "supervisor/shared/translate.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 */ diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 87a40f6fc1..03f4fac0dc 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -80,22 +80,21 @@ MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); #if MICROPY_PY_COLLECTIONS mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - if (n_args != 1 || (kw_args != NULL && kw_args->used > 0)) { - return namedtuple_make_new(type, n_args, args, kw_args); - } - if (mp_obj_get_type(args[0])->getiter != mp_obj_tuple_getiter || ((mp_obj_tuple_t *)MP_OBJ_TO_PTR(args[0]))->len != 9) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); + size_t len; + mp_obj_t *items; + mp_obj_get_array(args[0], &len, &items); + if (len != 9) { mp_raise_TypeError(translate("time.struct_time() takes a 9-sequence")); } - - mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(args[0]); - return namedtuple_make_new(type, 9, tuple->items, NULL); + return namedtuple_make_new(type, len, items, NULL); } //| class struct_time: -//| def __init__(self, time_tuple: Tuple[int, int, int, int, int, int, int, int, int]) -> None: -//| """Structure used to capture a date and time. Note that it takes a tuple! +//| def __init__(self, time_tuple: Sequence[int]) -> None: +//| """Structure used to capture a date and time. Can be constructed from a `struct_time`, `tuple`, `list`, or `namedtuple` with 9 elements. //| -//| :param tuple time_tuple: Tuple of time info: ``(tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)`` +//| :param Sequence time_tuple: Sequence of time info: ``(tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)`` //| //| * ``tm_year``: the year, 2017 for example //| * ``tm_mon``: the month, range [1, 12]