py/objfun: Support function attributes on native functions.

Native functions can just reuse the bytecode function attribute code.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2022-06-25 00:05:39 +10:00
parent 268ec1e3eb
commit e22b7fb4af
4 changed files with 36 additions and 0 deletions

View File

@ -421,8 +421,14 @@ STATIC const mp_obj_type_t mp_type_fun_native = {
{ &mp_type_type }, { &mp_type_type },
.flags = MP_TYPE_FLAG_BINDS_SELF, .flags = MP_TYPE_FLAG_BINDS_SELF,
.name = MP_QSTR_function, .name = MP_QSTR_function,
#if MICROPY_CPYTHON_COMPAT
.print = fun_bc_print,
#endif
.call = fun_native_call, .call = fun_native_call,
.unary_op = mp_generic_unary_op, .unary_op = mp_generic_unary_op,
#if MICROPY_PY_FUNCTION_ATTRS
.attr = mp_obj_fun_bc_attr,
#endif
}; };
mp_obj_t mp_obj_new_fun_native(const mp_obj_t *def_args, const void *fun_data, const mp_module_context_t *mc, struct _mp_raw_code_t *const *child_table) { mp_obj_t mp_obj_new_fun_native(const mp_obj_t *def_args, const void *fun_data, const mp_module_context_t *mc, struct _mp_raw_code_t *const *child_table) {

View File

@ -0,0 +1,25 @@
# test native function attributes
def f():
pass
if not hasattr(f, "__name__"):
print("SKIP")
raise SystemExit
@micropython.native
def native_f():
pass
print(type(native_f.__name__))
print(type(native_f.__globals__))
print(native_f.__globals__ is globals())
try:
native_f.__name__ = None
except AttributeError:
print("AttributeError")

View File

@ -0,0 +1,4 @@
<class 'str'>
<class 'dict'>
True
AttributeError

View File

@ -603,6 +603,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
skip_tests.add("basics/del_deref.py") # requires checking for unbound local skip_tests.add("basics/del_deref.py") # requires checking for unbound local
skip_tests.add("basics/del_local.py") # requires checking for unbound local skip_tests.add("basics/del_local.py") # requires checking for unbound local
skip_tests.add("basics/exception_chain.py") # raise from is not supported skip_tests.add("basics/exception_chain.py") # raise from is not supported
skip_tests.add("basics/fun_name.py") # requires proper names for native functions
skip_tests.add("basics/scope_implicit.py") # requires checking for unbound local skip_tests.add("basics/scope_implicit.py") # requires checking for unbound local
skip_tests.add("basics/sys_tracebacklimit.py") # requires traceback info skip_tests.add("basics/sys_tracebacklimit.py") # requires traceback info
skip_tests.add("basics/try_finally_return2.py") # requires raise_varargs skip_tests.add("basics/try_finally_return2.py") # requires raise_varargs