ionelmc / python-hunter

Hunter is a flexible code tracing toolkit.
https://python-hunter.readthedocs.io/
BSD 2-Clause "Simplified" License
794 stars 46 forks source link

Specialized variable watcher #80

Open ionelmc opened 4 years ago

ionelmc commented 4 years ago

There's VarsPrinter and VarsSnooper but they can't handle well this usecase: find out when a specific field or variable changes, perhaps even to a certain value.

Some ideas for a predicate:

Watcher(attr="foobar", type="MyClass", value=lambda value: value.startswith("stuff"))
Watcher(name="self", value=lambda value: value.field.startswith("stuff"))
Watcher(name="self", attr="field", type="MyClass", value=lambda value: value.startswith("stuff"))
Watcher(name=lambda name: name in ["self", "instance", "obj"], attr="field", type="MyClass", value=lambda value: value.startswith("stuff"))

Usecases like this one https://stackoverflow.com/a/54536941/23658 could be supported like this:

inst = ...

trace(Watcher(object=inst, attr="field", type="MyClass", value=lambda value: value.startswith("stuff")))

inst.field = "stuff123"

All the options and alternative names:

There is a question of disallowing name and object at the same time. Perhaps allow it but make it mean "if object is object and variable name is name".

Another problem is if type is a string or the actual type.

ionelmc commented 4 years ago

Idea 1 - implement an ID tracker (don't poke around in objects):

Trigger condition: state[<criteria>] != new_id and (value(new_value) if callable(value) else value == new_value). Need to note that value == new_value is a potentially dangerous side-effect incurring operation.