diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/obj.c | 7 | ||||
-rw-r--r-- | py/objtype.c | 17 | ||||
-rw-r--r-- | py/objtype.h | 4 |
3 files changed, 25 insertions, 3 deletions
@@ -34,6 +34,7 @@ #include "misc.h" #include "qstr.h" #include "obj.h" +#include "objtype.h" #include "mpz.h" #include "objint.h" #include "runtime0.h" @@ -145,7 +146,11 @@ bool mp_obj_is_true(mp_obj_t arg) { } bool mp_obj_is_callable(mp_obj_t o_in) { - return mp_obj_get_type(o_in)->call != NULL; + mp_call_fun_t call = mp_obj_get_type(o_in)->call; + if (call != mp_obj_instance_call) { + return call != NULL; + } + return mp_obj_instance_is_callable(o_in); } mp_int_t mp_obj_hash(mp_obj_t o_in) { diff --git a/py/objtype.c b/py/objtype.c index cb6b957336..b0c6a629d0 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -583,7 +583,7 @@ STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value } } -STATIC mp_obj_t instance_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { +bool mp_obj_instance_is_callable(mp_obj_t self_in) { mp_obj_instance_t *self = self_in; mp_obj_t member[2] = {MP_OBJ_NULL}; struct class_lookup_data lookup = { @@ -593,6 +593,19 @@ STATIC mp_obj_t instance_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw .dest = member, }; mp_obj_class_lookup(&lookup, self->base.type); + return member[0] != MP_OBJ_NULL; +} + +mp_obj_t mp_obj_instance_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + mp_obj_instance_t *self = self_in; + mp_obj_t member[2] = {MP_OBJ_NULL, MP_OBJ_NULL}; + struct class_lookup_data lookup = { + .obj = self, + .attr = MP_QSTR___call__, + .meth_offset = offsetof(mp_obj_type_t, call), + .dest = member, + }; + mp_obj_class_lookup(&lookup, self->base.type); if (member[0] == MP_OBJ_NULL) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(self_in))); } @@ -777,7 +790,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) o->load_attr = instance_load_attr; o->store_attr = instance_store_attr; o->subscr = instance_subscr; - o->call = instance_call; + o->call = mp_obj_instance_call; o->getiter = instance_getiter; o->bases_tuple = bases_tuple; o->locals_dict = locals_dict; diff --git a/py/objtype.h b/py/objtype.h index 6a8a18c50a..dd2e44a799 100644 --- a/py/objtype.h +++ b/py/objtype.h @@ -32,3 +32,7 @@ typedef struct _mp_obj_instance_t { mp_obj_t subobj[]; // TODO maybe cache __getattr__ and __setattr__ for efficient lookup of them } mp_obj_instance_t; + +// these need to be exposed so mp_obj_is_callable can work correctly +bool mp_obj_instance_is_callable(mp_obj_t self_in); +mp_obj_t mp_obj_instance_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args); |