Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Working With Breakpoints

You can use the b command, followed by the module name and line number, to set a breakpoint:

Shell
$ b util:5

This will set a breakpoint on line 5 of the util module. If we supply no module name, then pdb will set a breakpoint in the current module we’re running.

Running b with no line number will display a list of all our current breakpoints, which we can toggle on and off or clear. The c command will continue execution up until the next breakpoint is hit. a will show us the arguments passed into a function.

We can also create conditional breakpoints, which are breakpoints that only hit when a certain condition is met. In this example, you create a breakpoint that only hits if the argument passed to get_path() does not start with a /:

Shell
$ b util.get_path, not filename.startswith('/')

When you’re setting the breakpoint with a function name rather than a line number, note that the expression should use only function arguments or global variables that are available at the time the function is entered. Otherwise, the breakpoint will stop execution in the function regardless of the expression’s value.

00:00 So far, we’ve seen how we can set breakpoints within our code and also how we can step through our code line by line once we’ve hit these breakpoints. But what if we’re stopped at a breakpoint and we want to set a new breakpoint and then continue execution up until that point without having to step through every single line of code in between? Lucky for us, that’s easy to do.

00:27 Let’s take a look. To demo this, I’m going to use two files. This one is called example4.py, and it should look pretty familiar by now. Except, up at the top, I am importing a module called util, which I have right here.

00:46 This module simply contains the get_path() function from earlier.

00:53 You’ll see why I split up this code in a minute. As always, I’ll drop into my Z shell here and do ./example4.py. And we stop execution at the breakpoint on line 7. To create a breakpoint on line 5 of the util module, I can use the b command, followed by util:5, and pdb will tell me that it’s created a breakpoint in that module at line number 5.

01:29 Now I can use the c command to continue execution until that new breakpoint is hit. Now we’re stopped at the return line. And just like before, I can print out the filename, the head, and the tail. At any point, we can type b to get a list of all the breakpoints we’ve set.

01:53 They’re numbered starting at 1, and we can see here that it tells us how many times each breakpoint has been hit. Here, we could say enable 1 or disable 1 to toggle this breakpoint on or off or cl 1, short for clear 1, to delete it entirely.

02:14 I’m going to quit out of the debugging session and clear my console. Most debuggers also come with the ability to create conditional breakpoints, which are breakpoints that only break execution when a certain condition is met.

02:30 Our example4 file here presents a great opportunity to learn about this. This get_path() function has been great for returning a relative path to our file—

02:42 but what if we were expecting it to return an absolute path this entire time? Absolute file paths will always start with a forward slash (/), at least on a Unix-based system like the Linux subsystem I’m running.

02:58 So we need to create a breakpoint at the beginning of our get_path() function that will break only if the filename passed into it does not begin with a '/'. In my Z shell, I’ll type ./example4.py to run it once more. And now you see we’ve hit our breakpoint on line 7, just like before. To create a conditional breakpoint, I’ll type b util.get_path, not filename.startswith('/').

03:47 What I’m saying here is “Only break at the entry of this function if the filename passed into it does not start with a '/'.” I’ll press Enter, and you’ll see that pdb has set a breakpoint exactly where we need it.

04:03 Now just like before, I can enter c to continue execution, and we stop just before executing the first line of our get_path() function, which will import os. From here, I can use the a command to see the arguments provided—and there is the filename! Execution stops at the breakpoint because our filename starts with a '.' and not a '/'. It’s not an absolute path.

04:34 Before I close off this video, I should mention something real quick. In this example, I set the breakpoint with the function name. That’s where I did b util.get_path. Because I did that, the Boolean expression used for the breakpoint should only use function arguments or variables available at the time this function is entered.

05:00 Otherwise, pdb will always stop execution at the breakpoint because it doesn’t know what those variables are, and it wouldn’t be very conditional. For more information about this, see the video notes I’ve written down below.

Avatar image for Amitoz

Amitoz on March 16, 2020

Hello, Is there any way to download the files? example[1-5].py ?

Avatar image for Ricky White

Ricky White RP Team on March 16, 2020

Hi Amitoz. I’m afraid the files are not downloadable.

Avatar image for biatti

biatti on Aug. 26, 2021

Working With Breakpoints 2:04

I’ve been following along and recreating the files on my end. At this point in the video when running when running b util I get an End of File notification message. Here is what my code looks like:

Both files are located in the same directory, marked as Sources Root inside Pycharm.

pdb_test.py

import os, util

filename = __file__
import pdb; pdb.set_trace()
filename_path = util.get_path(filename)
print(f'path = {filename_path}')

util.py

import os
def get_path(filename):
    """Return file's path or empty string if no path"""
    head, tail = os.path.split(filename)
    return head

When running:

PS C:\Users\XXXXXX\PycharmProjects\CSC221\ds> ./pdb_test.py
> c:\users\xxxxxx\pycharmprojects\csc221\ds\pdb_test.py(14)<module>()
-> filename_path = util.get_path(filename)
(Pdb) b util:12
End of file
(Pdb)

Any ideas what I might have missed?

Avatar image for Martin Breuss

Martin Breuss RP Team on Aug. 26, 2021

Hi @biatti! It looks like this might not be your complete pdb_test.py file, since the first breakpoint happens on line 14:

c:\users\xxxxxx\pycharmprojects\csc221\ds\pdb_test.py(14)<module>()

So, line numbers are important here! If you think back to your End of File notification when attempting to set a new breakpoint in util.py at line 12 (b util:12), can you see why you’re getting it, assuming that this is the only content of your util.py:

import os
def get_path(filename):
    """Return file's path or empty string if no path"""
    head, tail = os.path.split(filename)
    return head
Avatar image for biatti

biatti on Aug. 26, 2021

Thanks Martin, yeah I’ve figured out what I was doing wrong. Feel pretty stupid now :) I was considering the lines I had in the pdb_test file

Avatar image for Martin Breuss

Martin Breuss RP Team on Aug. 27, 2021

Hi @biatti! Nice job in figuring it out and no need at all to feel stupid about it. It easy to mix up which file the line numbers would refer to! :)

Become a Member to join the conversation.