pdb.gods_grace()

pdb.gods_grace()

"Oh Bhai! Debug this code for me.": A senior developer to me on the first day of the job.

"Ok!" I told, not knowing the quicksand I was going to be sticking my foot in. A new guy on the first day at the job. Things weren't looking so bright for the newbie searching for a bright future ahead in tech field at this point. I didn't know how to do s*it. Playing the games with instructions, and so new to the concepts, I wouldn't even get the instructions understood.

Thanks that it was Python, the language I chose to kickstart my career with.

Enough of the story, lets get to the point now.

Technical stuff

Not all debugging tools are created equal. Print statements, Logging module, IDE assisted debugging, Traceback module (ignoring breakpoint() at this point) were good. But not good enough.

Not going to debugging in other languages as I was familiar to only Python at this point.

Getting started

Debugging the code is like riding a rollercoaster. Add breakpoints, cross the fingers and hope your code lands where you intended. "Why is it not working?", well I know. And if you are lucky, "How is it working?", well I don't want to know.

The pdb module is like a GPS to your code. The typical usage to break into debugger is to insert:

import pdb; pdb.set_trace()

import pdb() imports pdb into your python script. And once imported, use pdb.set_trace() to set breakpoint in your script. This step pauses your program's execution and enters the pdb interactive mode.

def print_texts():
    text1 = "Python"
    text2 = "pdb module"
    import pdb; pdb.set_trace()
    print(text1)
    print(text2)

print_texts()

Let's take this small code above to explain the basics of what power the module holds, and how can you proceed to debugging the Python scripts as a beginner. Keep in note, here the program execution is stopped above print(text1) line after it is run.

Lets appreciate a few highlights on how to navigate through your code where this module transforms debugging into smooth journey.

  • Interrogate through the objects:

    Take no wild guesses, just ask. Just ask. As simple as it sounds. Want to know the attributes of the object that the variable "text1" references to? Just do:

      -> print(text1)
      (Pdb) dir(text1)
      ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
      (Pdb)
    

    You may also print the variables to see what they hold or refer to at the point where the execution stops. Just do whatever you need to do to get across the bug. Just interact with the variables at the runtime. Use print() statement (for context), everything works as intended in a python program.

  • Navigate through the script:
    You can use several commands to navigate through your code at this point after you have used this module like n(next), c(continue), break(b) and many more. Through these commands you can closely interrogate how the code executes, through each single line.
    Also you can debug and see how the recursion works, how the conditional statements you set up in your code works and verify the logical calculations you have done in the script. To see more debugger commands you can use, you can refer here.

    Lets see how the next command (n) works in this point.

      -> print(text1)
      (Pdb) dir(text1)
      ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
      (Pdb) n
      Python
      -> print(text2)
    

    Enter another n, you shall print the value your variable text2 refers to.

  • Some of other more advanced features you can use are:

    • Conditional Breakpoints

    • Post-Mortem Debugging

    • View stack frames

    • Restarting Execution

    • Enable, Disable and List Breakpoints

and many more. You can learn more about the pdb() module through the official documentation here.

This module holds a royal decree, a debugging monarch for the beginners. While other languages might be wrestling with debugging circus, we sip the tea and enjoy its elegance. Friendly, yet powerful hence making suitable for beginners and well liked by experienced ones. Effective debugging is also about understanding it better, gaining more information on other coder's code behavior. Pdb() module easily holds the top spot, fulfilling these essentials.