It then uses sys.settrace (which is intended as an interface for debuggers) to step through the code and check whether the variable has been changed. Documentation on sys.settrace: https://docs.python.org/3/library/sys.html#sys.settrace
Python exposes most of its guts as part of the standard library, making clever hacks like this possible.
lol, thank you for the attention. Yes this will incur a performance penalty, and is similar to what "pdb" introduces(if your are familiar with pdb). Most of the python debugger did single step or breakpoint feature in this way.
And it's a little more than inspect and frames. Note that it is much easier to do watch("a") than watch(a), but it's slightly less intuitive. So I also did some AST hack to make watch(a) possible :)
Are you on Twitter or anything? I'd like to follow your work. (Put some info in your HN profile!)
I noticed that watchpoints doesn't work in the REPL, and since I live in the REPL, it limits my usage somewhat. But after digging into the code, I'm not quite sure if it even makes sense in the context of <stdin>...
I was also -- as the other commenter said, excuse the french -- fucking amazed that this works great:
from watchpoints import watch
a = []
watch(a)
a.append(1) # Trigger
a = {} # Trigger
def qq():
global a
a = 99 # Trigger
qq()
Not that you’d want to, but it’s a fun thought experiment.