For one, it seems the only type of change you can watch for are changes via assignment for top level variables. For example, any of the mutable built-ins (and I confirmed this by trying to use pyscribe) can't be watched for all changes. For example, mutating the list later with .append() doesn't log anything, nor does changing a value in a dictionary. You also can't watch a particular key in a dictionary, or an attribute in a class (these lead to parse errors when trying to run pyscribe).
Even if you modified the code to support this, you wouldn't be able to control access everywhere that piece of data went. Suppose I had a dict and and some point:
...
d = {'foo': 'bar'}
ps.watch(d)
ThirdPartyLib.do_stuff(d)
If that third party library mutated d, there'd be no way for you to know, unless you also were able to desugar those files (basically impossible because in some cases the source code isn't even available).In any case, this type of mutation is generally what causes the most bugs. A value changing by assignment doesn't need a run-time logger. These change are in plain sight; just do a search for the variable name in the local body of the function. Mutation that occurs in other contexts (when the object has been renamed, or passed to another function where access is through a different variable name) is the difficult thing to debug, and pyscribe cannot handle that with the current design.
Honestly, I think this is better handled with mocking objects. See how python Mock library does things, and possibly use it yourself (it wouldn't be all that much work to write your own wrapper, but Mock is seriously powerful). Basically watching a variable means wrapping it with a mocked object that defers all reads/writes to the real object, while logging all those changes. Not relying on desugaring also means you can watch what happens to your data when you pass it into third party libraries.