Skip to content

Commit 3cc17c6

Browse files
stinosdpgeorge
authored andcommitted
py: Allow retrieving a function's __name__.
Disabled by default. Enabled on unix and stmhal ports.
1 parent 07b8dc6 commit 3cc17c6

File tree

9 files changed

+54
-8
lines changed

9 files changed

+54
-8
lines changed

py/bc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, mp_uint_t expecte
6262
#elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
6363
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
6464
"%s() takes %d positional arguments but %d were given",
65-
mp_obj_fun_get_name(f), expected, given));
65+
qstr_str(mp_obj_fun_get_name(f)), expected, given));
6666
#endif
6767
}
6868

py/mpconfig.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,11 @@ typedef double mp_float_t;
359359
/*****************************************************************************/
360360
/* Fine control over Python builtins, classes, modules, etc */
361361

362+
// Whether to implement attributes on functions
363+
#ifndef MICROPY_PY_FUNCTION_ATTRS
364+
#define MICROPY_PY_FUNCTION_ATTRS (0)
365+
#endif
366+
362367
// Whether str object is proper unicode
363368
#ifndef MICROPY_PY_BUILTINS_STR_UNICODE
364369
#define MICROPY_PY_BUILTINS_STR_UNICODE (0)

py/obj.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,8 @@ typedef struct _mp_obj_fun_builtin_t { // use this to make const objects that go
574574
void *fun; // must be a pointer to a callable function in ROM
575575
} mp_obj_fun_builtin_t;
576576

577-
const char *mp_obj_fun_get_name(mp_const_obj_t fun);
578-
const char *mp_obj_code_get_name(const byte *code_info);
577+
qstr mp_obj_fun_get_name(mp_const_obj_t fun);
578+
qstr mp_obj_code_get_name(const byte *code_info);
579579

580580
mp_obj_t mp_identity(mp_obj_t self);
581581
MP_DECLARE_CONST_FUN_OBJ(mp_identity_obj);

py/objboundmeth.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,25 @@ STATIC mp_obj_t bound_meth_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_
7070
}
7171
}
7272

73+
#if MICROPY_PY_FUNCTION_ATTRS
74+
STATIC void bound_meth_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
75+
if(attr == MP_QSTR___name__) {
76+
mp_obj_bound_meth_t *o = self_in;
77+
dest[0] = MP_OBJ_NEW_QSTR(mp_obj_fun_get_name(o->meth));
78+
}
79+
}
80+
#endif
81+
7382
const mp_obj_type_t bound_meth_type = {
7483
{ &mp_type_type },
7584
.name = MP_QSTR_bound_method,
7685
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
7786
.print = bound_meth_print,
7887
#endif
7988
.call = bound_meth_call,
89+
#if MICROPY_PY_FUNCTION_ATTRS
90+
.load_attr = bound_meth_load_attr,
91+
#endif
8092
};
8193

8294
mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self) {

py/objfun.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,12 @@ const mp_obj_type_t mp_type_fun_builtin = {
103103
/******************************************************************************/
104104
/* byte code functions */
105105

106-
const char *mp_obj_code_get_name(const byte *code_info) {
106+
qstr mp_obj_code_get_name(const byte *code_info) {
107107
mp_decode_uint(&code_info); // skip code_info_size entry
108-
return qstr_str(mp_decode_uint(&code_info));
108+
return mp_decode_uint(&code_info);
109109
}
110110

111-
const char *mp_obj_fun_get_name(mp_const_obj_t fun_in) {
111+
qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) {
112112
const mp_obj_fun_bc_t *fun = fun_in;
113113
const byte *code_info = fun->bytecode;
114114
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) {
118118
STATIC void fun_bc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
119119
(void)kind;
120120
mp_obj_fun_bc_t *o = o_in;
121-
print(env, "<function %s at 0x%x>", mp_obj_fun_get_name(o), o);
121+
print(env, "<function %s at 0x%x>", qstr_str(mp_obj_fun_get_name(o)), o);
122122
}
123123
#endif
124124

@@ -246,13 +246,24 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
246246
}
247247
}
248248

249+
#if MICROPY_PY_FUNCTION_ATTRS
250+
STATIC void fun_bc_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
251+
if(attr == MP_QSTR___name__) {
252+
dest[0] = MP_OBJ_NEW_QSTR(mp_obj_fun_get_name(self_in));
253+
}
254+
}
255+
#endif
256+
249257
const mp_obj_type_t mp_type_fun_bc = {
250258
{ &mp_type_type },
251259
.name = MP_QSTR_function,
252260
#if MICROPY_CPYTHON_COMPAT
253261
.print = fun_bc_print,
254262
#endif
255263
.call = fun_bc_call,
264+
#if MICROPY_PY_FUNCTION_ATTRS
265+
.load_attr = fun_bc_load_attr,
266+
#endif
256267
};
257268

258269
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) {

py/objgenerator.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun) {
9797
STATIC void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
9898
(void)kind;
9999
mp_obj_gen_instance_t *self = self_in;
100-
print(env, "<generator object '%s' at %p>", mp_obj_code_get_name(self->code_state.code_info), self_in);
100+
print(env, "<generator object '%s' at %p>", qstr_str(mp_obj_code_get_name(self->code_state.code_info)), self_in);
101101
}
102102

103103
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) {

stmhal/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#define MICROPY_STREAMS_NON_BLOCK (1)
5656
#define MICROPY_MODULE_WEAK_LINKS (1)
5757
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
58+
#define MICROPY_PY_FUNCTION_ATTRS (1)
5859
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
5960
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
6061
#define MICROPY_PY_BUILTINS_FROZENSET (1)

tests/basics/fun_name.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
def Fun():
2+
pass
3+
4+
class A:
5+
def __init__(self):
6+
pass
7+
def Fun(self):
8+
pass
9+
10+
try:
11+
print(Fun.__name__)
12+
print(A.__init__.__name__)
13+
print(A.Fun.__name__)
14+
print(A().Fun.__name__)
15+
except AttributeError:
16+
print('SKIP')

unix/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#define MICROPY_OPT_COMPUTED_GOTO (1)
5858
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (1)
5959
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
60+
#define MICROPY_PY_FUNCTION_ATTRS (1)
6061
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
6162
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
6263
#define MICROPY_PY_BUILTINS_FROZENSET (1)

0 commit comments

Comments
 (0)