Skip to content

MuXue1230-owo/dowhen

 
 

Repository files navigation

dowhen

build readthedocs coverage pypi support-version sponsor

dowhen makes instrumentation (monkeypatch) super intuitive and maintainable with minimal overhead!

You can execute arbitrary code at specific points of your application, third-party libraries or stdlib in order to

  • debug your program
  • change the original behavior of the libraries
  • monitor your application
  • profile performance

Installation

pip install dowhen

Usage

The core idea behind dowhen is to do a callback on a trigger. The trigger is specified with when and there are 3 kinds of callbacks.

do

do executes an arbitrary piece of code.

from dowhen import do

def f(x):
    x += 100
    # Let's change the value of x before return
    return x

# do("x = 1") is the callback
# when(f, "return x") is the trigger
# This is equivalent to:
# handler = when(f, "return x").do("x = 1")
handler = do("x = 1").when(f, "return x")
# x = 1 is executed before "return x"
assert f(0) == 1

# You can remove the handler
handler.remove()
assert f(0) == 100

bp

bp sets a breakpoint and brings up pdb.

from dowhen import bp

# bp() is another callback that brings up pdb
handler = bp().when(f, "return x")
# This will enter pdb
f(0)
# You can temporarily disable the handler
# handler.enable() will enable it again
handler.disable()

goto

goto changes the next line to execute.

from dowhen import goto

# This will skip the line of `x += 100`
# The handler will be removed after the with context
with goto("return x").when(f, "x += 100"):
    assert f(0) == 0

callback chains

from dowhen import when

# You can chain callbacks and they'll run in order at the trigger
# You don't need to store the handler if you don't use it
when(f, "x += 100").goto("return x").do("x = 42")
assert f(0) == 42

Instrumentation Builder

InstrumentBuilder provides a fluent interface for building complex instrumentation scenarios.

from dowhen import instrument

# Using instrument() as a factory function
handler = instrument().at(f, "return x").do("x = 1")
assert f(0) == 1

# Using InstrumentBuilder class directly
from dowhen import InstrumentBuilder
builder = InstrumentBuilder()
handler = builder.at(f, "return x").do("x = 1").apply()
assert f(0) == 1

# Chaining multiple actions
handler = instrument().at(f, "x += 100").do("x += 1").goto("return x").apply()

Performance Profiling

dowhen provides built-in performance profiling capabilities.

from dowhen import profile_instrumentation, get_performance_stats

# Profile a function with the profile_instrumentation context manager
with profile_instrumentation(f, iterations=100):
    f(0)

# Get performance statistics
report = get_performance_stats(f)
print(report.summary())  # Print summary report
print(report.detailed())  # Print detailed report

License

Copyright 2025 Tian Gao.

Distributed under the terms of the Apache 2.0 license.

About

An intuitive and low-overhead instrumentation tool for Python

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 99.5%
  • Makefile 0.5%