From 925bd67cfb1607264fae79a4fdf5e79ab1ae46aa Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 26 Sep 2020 01:17:11 +1000 Subject: [PATCH] py/objfun: Support fun.__globals__ attribute. This returns a reference to the globals dict associated with the function, ie the global scope that the function was defined in. This attribute is read-only but the dict itself is modifiable, per CPython behaviour. Signed-off-by: Damien George --- py/objfun.c | 4 ++++ tests/basics/fun_globals.py | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 tests/basics/fun_globals.py diff --git a/py/objfun.c b/py/objfun.c index 052f4b1ced..178f834431 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -355,6 +355,10 @@ void mp_obj_fun_bc_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)); } + if (attr == MP_QSTR___globals__) { + mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); + dest[0] = MP_OBJ_FROM_PTR(self->globals); + } } #endif diff --git a/tests/basics/fun_globals.py b/tests/basics/fun_globals.py new file mode 100644 index 0000000000..3f32e8bdb0 --- /dev/null +++ b/tests/basics/fun_globals.py @@ -0,0 +1,21 @@ +# test the __globals__ attribute of a function + + +def foo(): + pass + + +if not hasattr(foo, "__globals__"): + print("SKIP") + raise SystemExit + +print(type(foo.__globals__)) +print(foo.__globals__ is globals()) + +foo.__globals__["bar"] = 123 +print(bar) + +try: + foo.__globals__ = None +except AttributeError: + print("AttributeError")