How to set custom locals for function call?

Andras Tantos python-list at andras.tantosonline.com
Tue Sep 1 00:45:18 EDT 2020


All,

I'm new here, so please direct me to the right forum, if this is not the 
one...

What I'm trying to do is to call a function, but monitor all the local 
variable accesses within that function. What I thought I would need to 
do, is to |exec| the function with a custom |locals| dictionary. The 
code below attempts to do it.

|classMySymbolTable(dict):defset_type(self,t):self.type =t 
def__getitem__(self,key):print(f"Requesting key {key} from {self.type} 
table")returnsuper().__getitem__(key)def__setitem__(self,key,value):print(f"Setting 
key {key} from {self.type} table to value 
{value}")returnsuper().__setitem__(key,value)defmylocals(func):defwrapper(*args,**kwargs):loc 
=MySymbolTable()glob 
=MySymbolTable(globals())loc.set_type("local")glob.set_type("global")exec(func.__code__,glob,loc)returnwrapper 
@mylocalsdeffun1():print(f"fun1 with locals: {type(locals())} and 
globals: {type(globals())}")a =1b =2c =3a =b c =5fun1()|

However, when I run it, I get the following output:

|Requestingkey printfromglobaltable Requestingkey type fromglobaltable 
Requestingkey locals fromglobaltable Requestingkey type fromglobaltable 
Requestingkey globals fromglobaltable fun1 
withlocals:<class'dict'>andglobals:<class'__main__.MySymbolTable'>|

That is to say, global accesses are redirected to my custom dict, but 
local assignments are not. You can even see that in the types of the two 
objects printed in the last line.

My hunch is that since I'm using the functions |__code__| member, I end 
up executing pre-compiled byte-code which has already assumptions about 
the locals dict built into it.

If I'm right (or even if I'm not), what is the right way to achieve my 
goal: that local assignments get redirected to the supplied dictionary?

Thanks,
Andras Tantos




More information about the Python-list mailing list