py: Allow retrieving a function's __name__.
Disabled by default. Enabled on unix and stmhal ports.
This commit is contained in:
parent
07b8dc68d6
commit
3cc17c69ff
2
py/bc.c
2
py/bc.c
|
@ -62,7 +62,7 @@ STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, mp_uint_t expecte
|
||||||
#elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
|
#elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
|
||||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||||
"%s() takes %d positional arguments but %d were given",
|
"%s() takes %d positional arguments but %d were given",
|
||||||
mp_obj_fun_get_name(f), expected, given));
|
qstr_str(mp_obj_fun_get_name(f)), expected, given));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -359,6 +359,11 @@ typedef double mp_float_t;
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Fine control over Python builtins, classes, modules, etc */
|
/* Fine control over Python builtins, classes, modules, etc */
|
||||||
|
|
||||||
|
// Whether to implement attributes on functions
|
||||||
|
#ifndef MICROPY_PY_FUNCTION_ATTRS
|
||||||
|
#define MICROPY_PY_FUNCTION_ATTRS (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Whether str object is proper unicode
|
// Whether str object is proper unicode
|
||||||
#ifndef MICROPY_PY_BUILTINS_STR_UNICODE
|
#ifndef MICROPY_PY_BUILTINS_STR_UNICODE
|
||||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (0)
|
#define MICROPY_PY_BUILTINS_STR_UNICODE (0)
|
||||||
|
|
4
py/obj.h
4
py/obj.h
|
@ -574,8 +574,8 @@ typedef struct _mp_obj_fun_builtin_t { // use this to make const objects that go
|
||||||
void *fun; // must be a pointer to a callable function in ROM
|
void *fun; // must be a pointer to a callable function in ROM
|
||||||
} mp_obj_fun_builtin_t;
|
} mp_obj_fun_builtin_t;
|
||||||
|
|
||||||
const char *mp_obj_fun_get_name(mp_const_obj_t fun);
|
qstr mp_obj_fun_get_name(mp_const_obj_t fun);
|
||||||
const char *mp_obj_code_get_name(const byte *code_info);
|
qstr mp_obj_code_get_name(const byte *code_info);
|
||||||
|
|
||||||
mp_obj_t mp_identity(mp_obj_t self);
|
mp_obj_t mp_identity(mp_obj_t self);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_identity_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_identity_obj);
|
||||||
|
|
|
@ -70,6 +70,15 @@ STATIC mp_obj_t bound_meth_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MICROPY_PY_FUNCTION_ATTRS
|
||||||
|
STATIC void bound_meth_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||||
|
if(attr == MP_QSTR___name__) {
|
||||||
|
mp_obj_bound_meth_t *o = self_in;
|
||||||
|
dest[0] = MP_OBJ_NEW_QSTR(mp_obj_fun_get_name(o->meth));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const mp_obj_type_t bound_meth_type = {
|
const mp_obj_type_t bound_meth_type = {
|
||||||
{ &mp_type_type },
|
{ &mp_type_type },
|
||||||
.name = MP_QSTR_bound_method,
|
.name = MP_QSTR_bound_method,
|
||||||
|
@ -77,6 +86,9 @@ const mp_obj_type_t bound_meth_type = {
|
||||||
.print = bound_meth_print,
|
.print = bound_meth_print,
|
||||||
#endif
|
#endif
|
||||||
.call = bound_meth_call,
|
.call = bound_meth_call,
|
||||||
|
#if MICROPY_PY_FUNCTION_ATTRS
|
||||||
|
.load_attr = bound_meth_load_attr,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self) {
|
mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self) {
|
||||||
|
|
19
py/objfun.c
19
py/objfun.c
|
@ -103,12 +103,12 @@ const mp_obj_type_t mp_type_fun_builtin = {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* byte code functions */
|
/* byte code functions */
|
||||||
|
|
||||||
const char *mp_obj_code_get_name(const byte *code_info) {
|
qstr mp_obj_code_get_name(const byte *code_info) {
|
||||||
mp_decode_uint(&code_info); // skip code_info_size entry
|
mp_decode_uint(&code_info); // skip code_info_size entry
|
||||||
return qstr_str(mp_decode_uint(&code_info));
|
return mp_decode_uint(&code_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *mp_obj_fun_get_name(mp_const_obj_t fun_in) {
|
qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) {
|
||||||
const mp_obj_fun_bc_t *fun = fun_in;
|
const mp_obj_fun_bc_t *fun = fun_in;
|
||||||
const byte *code_info = fun->bytecode;
|
const byte *code_info = fun->bytecode;
|
||||||
return mp_obj_code_get_name(code_info);
|
return mp_obj_code_get_name(code_info);
|
||||||
|
@ -118,7 +118,7 @@ const char *mp_obj_fun_get_name(mp_const_obj_t fun_in) {
|
||||||
STATIC void fun_bc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
|
STATIC void fun_bc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
|
||||||
(void)kind;
|
(void)kind;
|
||||||
mp_obj_fun_bc_t *o = o_in;
|
mp_obj_fun_bc_t *o = o_in;
|
||||||
print(env, "<function %s at 0x%x>", mp_obj_fun_get_name(o), o);
|
print(env, "<function %s at 0x%x>", qstr_str(mp_obj_fun_get_name(o)), o);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -246,6 +246,14 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MICROPY_PY_FUNCTION_ATTRS
|
||||||
|
STATIC void fun_bc_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||||
|
if(attr == MP_QSTR___name__) {
|
||||||
|
dest[0] = MP_OBJ_NEW_QSTR(mp_obj_fun_get_name(self_in));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const mp_obj_type_t mp_type_fun_bc = {
|
const mp_obj_type_t mp_type_fun_bc = {
|
||||||
{ &mp_type_type },
|
{ &mp_type_type },
|
||||||
.name = MP_QSTR_function,
|
.name = MP_QSTR_function,
|
||||||
|
@ -253,6 +261,9 @@ const mp_obj_type_t mp_type_fun_bc = {
|
||||||
.print = fun_bc_print,
|
.print = fun_bc_print,
|
||||||
#endif
|
#endif
|
||||||
.call = fun_bc_call,
|
.call = fun_bc_call,
|
||||||
|
#if MICROPY_PY_FUNCTION_ATTRS
|
||||||
|
.load_attr = fun_bc_load_attr,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
mp_obj_t mp_obj_new_fun_bc(mp_uint_t scope_flags, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_obj_t def_args_in, mp_obj_t def_kw_args, const byte *code) {
|
mp_obj_t mp_obj_new_fun_bc(mp_uint_t scope_flags, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_obj_t def_args_in, mp_obj_t def_kw_args, const byte *code) {
|
||||||
|
|
|
@ -97,7 +97,7 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun) {
|
||||||
STATIC void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
STATIC void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||||
(void)kind;
|
(void)kind;
|
||||||
mp_obj_gen_instance_t *self = self_in;
|
mp_obj_gen_instance_t *self = self_in;
|
||||||
print(env, "<generator object '%s' at %p>", mp_obj_code_get_name(self->code_state.code_info), self_in);
|
print(env, "<generator object '%s' at %p>", qstr_str(mp_obj_code_get_name(self->code_state.code_info)), self_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) {
|
mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) {
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||||
|
#define MICROPY_PY_FUNCTION_ATTRS (1)
|
||||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||||
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
def Fun():
|
||||||
|
pass
|
||||||
|
|
||||||
|
class A:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
def Fun(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(Fun.__name__)
|
||||||
|
print(A.__init__.__name__)
|
||||||
|
print(A.Fun.__name__)
|
||||||
|
print(A().Fun.__name__)
|
||||||
|
except AttributeError:
|
||||||
|
print('SKIP')
|
|
@ -57,6 +57,7 @@
|
||||||
#define MICROPY_OPT_COMPUTED_GOTO (1)
|
#define MICROPY_OPT_COMPUTED_GOTO (1)
|
||||||
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (1)
|
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (1)
|
||||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||||
|
#define MICROPY_PY_FUNCTION_ATTRS (1)
|
||||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||||
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
||||||
|
|
Loading…
Reference in New Issue