In pdb not only can you set breakpoints with conditions[1], you can also assign commands to be executed when the breakpoint is reached[2]. You can also use `display` command to - effectively - insert temporary `print`s in any stack frame[3]. Coupled with `up`, `down`, and `jump` commands, and the ability to evaluate any code in the scope of a break, it really gives you a lot of options on how to find the problem.
Though, logging is still a good thing. When I see a commented out `print` in code review, I usually suggest to replace it with a DEBUG level logger call. Extensive logging does help to trace the execution, it can be disabled when not needed, and can improve the readability of the code. Although raw print is an antipattern (can't easily enable some and disable other, need to clean up after debugging, doesn't display the stack trace, etc.), logging is a valid technique which complements the usage of a debugger nicely.
[1] https://docs.python.org/3/library/pdb.html#pdbcommand-break
[2] https://docs.python.org/3/library/pdb.html#pdbcommand-comman...
[3] https://docs.python.org/3/library/pdb.html#pdbcommand-displa...