Altering a Python function's local variables with a trace functionSome time ago I wrote that there was no way to change a function's local variables from outside it (well, specifically their name bindings). As it turns out, I'm wrong; there is one way to do it by going in the back door, although it's not a useful way. There is specific code in CPython that allows a trace function to completely
alter a function's local variables and even function arguments; this (C)
code specifically reloads the internal interpreter version of local
variables from the (You may be able to give it a local tracing function by getting
its frame object and then assigning a suitable function to
What you can do to local variables and function arguments is relatively unrestricted. You can change values, you can unbind variables (so that access to them will get UnboundLocalError), and you can bind variables that are currently unbound. However, as expected, you cannot add new local variables; attempts to do so are ignored. Unfortunately, there is a further complication: you have to access
For example, suppose that you write: def localtrace(evt, frame, arg): frame.f_locals['a'] = 10 frame.f_locals['b'] = 20 return None If you arrange to hook this up, you will discover that only your change
to The way to get around this is to dereference def localtrace(evt, frame, arg): d = frame.f_locals d['a'] = 10 d['b'] = 20 return None This will work, changing both (I suspect that at least some Python debuggers are currently falling victim to this dark corner.) As a trivia note, the same C code that is used to update the real
function locals for tracing functions is also invoked if you do ' As an extra special trivia note, profile functions can also do this since they (currently) go through the same low-level C code as trace functions. But really, you don't want to go there. Sidebar: How to actually turn off local tracingAccording to the fine documentation, returning Until this bug is fixed, you will need to 'turn off' tracing by
returning a do-nothing trace function from your real local tracing
function. A suitable one is ' My firm impression from both of these issues is that tracing functions and their access to function local variables are a very, very dark corner of the CPython interpreter, and you meddle in it at your peril. It seems clear that not very many people have ever tried to do anything with it, and there may be other problems too. |
These are my WanderingThoughts GettingAround This is part of CSpace, and is written by ChrisSiebenmann. * * * Atom feeds are available; see the bottom of most pages. Categories: links, linux, programming, python, snark, solaris, spam, sysadmin, tech, unix, web |