Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork3k
Compiling Nested Functions
Nested functions can access variables defined in an outer function:
deff(x:int)->None:defg()->None:print(x)# Refer to x in the outer functiong()
To support this, mypyc creates a hiddenenvironment class, and instances of this class hold locals that are accessed in nested functions. The nested function is also represented as an instance of a generated class which has a reference to the environment. The example above behaves like this when compiled, roughly:
classf_env:# Generated class, implementation detailx:intg:g_f_objclassg_f_obj:# Generated class, implementation detail__mypyc_env__:f_envdef__call__(self)->None:print(self.__mypyc_env__.x)deff(x:int)->None:_env=f_env()_env.x=xg=g_f_obj()g.__mypyc_env__=_env_env.g=gg()
The environment class_env
also holds a reference to the nested functiong
to allow recursive calls ing
, and mutually recursive calls if there are multiple nested functions. The nested function has no direct access to the locals of the outer function, other than those accessible via the environment. In this case there are no recursive calls so we could drop theg
attribute. It's sometimes needed and we generate it always, for simplicity.
The environment and the nested function object are separate instances so that locals from an outer function can be shared between multiple nested functions. If there was only a single nested function, mypyc could merge the environment and the function object (but this is not implemented).
mypyc/irbuild/envclass.py
(environment classes)mypyc/irbuild/callable_class
(nested function objects)