Skip to content

DataDog/wilma

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wilma

Smarter-than-caveman debugging

Who is Wilma?

Wilma is a Python debugging tool intended to solve some of the issues that come with the traditional practice of print-statement debugging (also known as Caveman Debugging).

What are the issues?

"The most effective debugging tool is still careful thought, coupled with judiciously placed print statements."

— Brian Kernighan, "Unix for Beginners" (1979)

One problem with this approach is that it requires changing the source code to add new print statements. Most of them would probably need to be removed before the code goes to production, and there is always a chance that some might be go unnoticed and forgotten. Furthermore, it is not easy to toggle them on or off while debugging, as they tend to be scattered across multiple sources.

How Wilma solves them

Wilma lets you define print statements in a separate configuration file, which are then injected into the bytecode at runtime. This means that there is no longer the need to make changes to source files (not only that, but one can easily add print statement to third-party libraries too!). Consequently, there is no risk of forgetting print statements in sources, and switching them off is as easy as commenting them out in just a single place!

Example

Suppose that we have a function that takes a single argument, e.g.

# File: test.py
def foo(secret):
    print("I'm not telling you the secret!")
    return None

foo("Wilma rox!")

There is no way of knowing what was passed to the function when it is called by just looking at its output:

$ python -m test
I'm not telling you the secret!

So we can use Wilma to inject a print statement at the beginning of line 4 that prints the value of the secret argument:

# File: wilma.toml
[probes]
"test.py:4" = "print('The secret is: ', secret)"

If we now run the same script through Wilma, this time we get:

$ wilma python -m test
I'm not telling you the secret!
The secret is: Wilma rox!

By default, Wilma looks for the file wilma.toml in the current working directory. You can specify a custom Wilma file with the -c/--config option.

NOTE Wilma should be installed within the same environment of the target application to work properly. For examole, you may want to list Wilma amongst the developent dependencies of your project.

Tools

Wilma comes with a set of useful tools to quickly perform debug operations. For example, to change the value of the secret local variable, you can use the following configuration

# File: wilma.toml
[probes]
"test.py:3" = """
with wilma.locals() as ls:
    ls["secret"] = "new secret"
"""
"test.py:4" = "print('The secret is: ', secret)"

When you run the test module you should now see new secret instead of the original value.

The wilma module is imported automatically, so there is no need to add it explicitly to the imports.

Dependencies

You can also inject extra dependencies that you perhaps would include in your project only for debugging purposes. For example, if you want to use the rich library to pretty-print, you can add it to the dependencies section of the configuration file:

imports = [ "rich as r" ]

[dependencies]
rich = "latest"

[probes]
"test.py:3" = "r.print(f'secret=\"{secret}\"')"

In this example, we import rich and give it the alias r. We then add rich to the dependencies that we want Wilma to install (assuming that rich is not already available from the target environment). In this case we request the latest version, but the string after the = sign can be any valid version specifier, e.g. ~=10.4.0.