pudb icon indicating copy to clipboard operation
pudb copied to clipboard

Add ability to break exactly when a variable changes

Open asmeurer opened this issue 12 years ago • 4 comments

The whole point of watch expressions is that that is the expression you are interested in. So it would be useful to be able to press c and have the script stop exactly when it changes. This probably should be the default (though either way, there should be an option). At least, that's what the name "watch expression" suggests to me.

asmeurer avatar Mar 12 '13 23:03 asmeurer

Three remarks:

  • What does 'changed' mean? current_value is not previous_value?
  • bdb doesn't provide any help with this. So pudb would have to do this on its own, which would potentially be quite expensive. Also, what should it do if the current scope is exited?
  • Watch expressions are going to stay what they are--expressions whose values you'd like to see ("watch"). Data-changed breakpoints are a different matter.

inducer avatar Mar 13 '13 02:03 inducer

OK, I didn't put much thought into it yet :)

I just noticed that I wanted this feature today when I was trying to figure out the first time in a module that a variable became defined, and the best way I could figure out to do it was to set it as a watch expression and press n until I saw the value change.

To answer your questions:

What does 'changed' mean? current_value is not previous_value?

I guess we should experiment with performance, but probably we should let the user customize this. It should be either is comparison or comparison against the string form. Anything else is potentially dangerous anyway (e.g., ==), not to mention not guaranteed to work.

bdb doesn't provide any help with this. So pudb would have to do this on its own, which would potentially be quite expensive. Also, what should it do if the current scope is exited?

OK, I didn't know that. I'll have to think about how to implement this then.

Watch expressions are going to stay what they are--expressions whose values you'd like to see ("watch"). Data-changed breakpoints are a different matter.

I guess watch expressions are the wrong way to think about this. Better would be to add a new checkbox for the dialog that comes up when you press enter on a variable, which would enable this tracking. It would also work for watch expressions.

Actually, thinking about how to implement this, it would be harder to do for a watch expression--and potentially much more expensive. I think you'd have to somehow add a hook to the locals dictionary, which has a callback to PuDB if the variable changes. This may or may not work (from my understanding, the locals dictionary is not really a dictionary, so such a hook may not work. I also don't know what kinds of optimizations exist for it). Making it work for watch expressions would be trickier: the hook would have to reevaluate the watch expression each time the locals dictionary is accessed. There are also subtleties if you want to support attributes with new/old-style classes and __slots__ and so on.

So all in all, this is definitely a hard problem. But it might be fun to learn more about the Python internals. And I don't think there's any question that it would be a useful feature.

If my locals hack doesn't work, I suppose we could have PuDB "n" continually until the expression changes (without updating the UI each time). That would indeed be slow: each Python statement would be reduced to running at the speed of a Python loop, but there's always at least some speed tradeoff given if you are using a debugger.

asmeurer avatar Mar 13 '13 02:03 asmeurer

locals falls short. You might want to break on a changed instance attribute...

inducer avatar Mar 13 '13 02:03 inducer

Looks like with code from https://github.com/cool-RR/PySnooper it is possible to cover this.

techtonik avatar Sep 06 '19 01:09 techtonik