Dropping into a debugger with the built-in debugger() function

One of the nice little things Python 3.7 brought us is the new built-in function breakpoint(), which was proposed in PEP 553. As its name suggests, it allows us to create a breakpoint in Python source code.

Now, creating breakpoints in the source is nothing new, but it was always a bit tedious:

name = input("Enter name: ")
import pdb; pdb.set_trace()
user = find_user(name=name)

Quite a lot of typing, and just like the author of the linked PEP, I also mistype it quite often. When deep into the bug tracking, such typos and script re-runs are moderately annoying and unnecessarily contribute to the overall cognitive load. Typing breakpoint() is slightly easier.

Additionally, if the project is set up to use auto code formatting tools such as black on every build, these tools are happy to refactor this debugging snippet to follow the style guide, adding insult to injury:

name = input("Enter name: ")
import pdb

pdb.set_trace()  # argh!!
user = find_user(name=name)

On the other hand, the following looks considerably cleaner and does not suffer from the same problem:

name = input("Enter name: ")
breakpoint()
user = find_user(name=name)

When called, the breakpoint() function calls the sys.breakpointhook() hook. The latter drops you into the build-in debugger pdb by default, but you can override the hook to do something else, such as invoking a completely different debugger or trolling:

import sys

def trolling():
    raise RuntimeError("Debugging not allowed!")

sys.breakpointhook = trolling  # for the lulz

...

breakpoint()  # RuntimeError: Debugging not allowed!

The default implementation of the hook also allows customizing the breakpoint() behavior through the PYTHONBREAKPOINT environment variable (provided that the hook was not overridden as above):

  • If PYTHONBREAKPOINT is not set or set to the empty string, pdb.set_trace() is called.
  • If set to "0", breakpoint() returns immediately and does not do anything. Useful for quickly disabling all breakpoints without modifying the source.
  • If set to anything else, e.g. "ipdb.set_trace", the value is treated as the name of the function to import and run. If importing fails, a warning is issued and the breakpoint is a no-op.

Useful? Tell me what you think!

3 thoughts on “Dropping into a debugger with the built-in debugger() function”

  1. I need some help with Python I have a project to program Bookshop application to display books,add them ,update them,delete them and search them …I did some of these but I couldn’t arrange the cods and I don’t know if it right or not ..and what’s the wrong . . and how can I manage it… please help me
    Bookname=[None]100
    Bookauthor=[None]
    100
    Bookprice=[None]*100
    index=-1

    def MainMenu():
    print(“1-Display all Book”)
    print(“2-Add Book”)
    print(“3-Delete Book”)
    print(“4-Update Book”)
    print(“5-Search Book”)
    print(“6-Exit”)
    choice=int(input(“Enter your choice: “))
    return choice

    def DisplayallBook():
    if index==-1:
    print(“there are no book”)
    return
    else:
    print(“Bookname,Bookauthor,Bookprice,end=” “”)
    for i in Bookname:
    if(i is not None):
    print = (“python , basmah , 100,end=” “”)
    for i in Bookauthor:
    if(i is not None):
    print = (“java , basmah , 200,end=”””)
    for i in Bookprice:
    if (i is not None):
    print = (“php , batool , 100,end=” “”)
    def AddBook():
    e = int(input(” Enter count of book to add: “))
    Bookname = input(“Enter Book 1 name : “)
    Bookauthor = input(“Enter Book 1 author : “)
    Bookprice = input(“Enter Book 1 price : “)
    j = input(“Enter Book 2 name : “)
    y = input(“Enter Book 2 author : “)
    f = input(“Enter Book 2 price : “)
    h = input(“Enter Book 3 name : “)
    m = input(“Enter Book 3 author : “)
    d = input(“Enter Book 3 price : “)

    Like

  2. It’s hard to tell, since the code is not properly formatted and thus difficult to decipher. Can you reformat it using a proper markup? Or, alternatively, paste it somewhere else (e.g. gist.github.com) and link it here.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: