ipdb debugger, step out of cycle - python

Is there a command to step out of cycles (say, for or while) while debugging on ipdb without having to use breakpoints out of them?
I use the until command to step out of list comprehensions, but don't know how could I do a similar thing, if possible, of entire loop blocks.

I believe this is the intent of the until command. It's like a next except that when a jump occurs to a previous line number for the loop, it will continue until exiting the loop.
unt(il)
Continue execution until the line with a number greater than the current
one is reached or until the current frame returns
In general, to "step out" of the current function, use return.
r(eturn)
Continue execution until the current function returns.

You can use j <line number> (jump) to go to another line.
for example, j 28 to go to line 28.

This could sound obvious: jump makes you jump.
This means that you don't execute the lines you jump: you should use this to skip code that you don’t want to run.
You probably need tbreak (Temporary breakpoint, which is removed automatically when it is first hit. The arguments are the same as break) as I did when I found this page.

If you are willing to use another debugger, trepan, has more ways you can step. It is more gdb-like. So you can give a count of how many times you want to step. Or you can give a line number in a continue debugger command which in essence sets a temporary breakpoint at the line and then issues "continue". Other things that change stepping are "set different". See also the even suffixes you can put on step.
Note that like ipdb, there is syntax highlighting of the source text.

Related

Debugging "in the middle of a huge loop" (python/pycharm) [duplicate]

I have a breakpoint in my Python debugger. I am using PyCharm. I want to iterate lets say 100 times to reach the point where I want to debug.
Now I can press 100 x times Resume Program, but is there a way to just execute a command to run n times over the breakpoint.
You can use a function in a conditional breakpoint to count iterations, take for example:
The conditional breakpoint can call a function which in addition to returning a boolean, counts the number of loop iterations.
def your_counter(stop):
global count
count = count + 1
if stop == count:
# count = 0 for periodic break
return True
else:
return False
The solution shown is for cases when a one-liner condition might not be practical, and/or when a loop counter needs to be implemented externally. Since the breakpoint condition is programmatic you can implement it to break periodically, or on any series/frequency criteria you want to apply.
The custom condition would break at the exact iteration you want, after you're done "step debugging" either press resume, stop, "run to cursor", or disable the breakpoint right-clicking on it (in practice this gets you out of the loop).
You can also change the value of any variable in the middle of debugging by editing in "variable watches".
PyCharm offers the possibility to add conditions on specific breakpoint.
This feature is called Conditional Breakpoints and you can find the documentation here.
I think that this is what you are looking for, because in this way you are able to enable the breakpoint only under specific conditions.

Break out of loop from console while in debug mode

I'm debugging some code in PyCharm by stepping through line-by-line. The code involves a long for-loop, but for debugging purposes, I don't need to iterate through the whole thing. Instead, I'd like to break out after a few iterations. I'm trying to figure out how to do so without modifying my code to have special debugging instructions.
Example for loop
indices = range(10000, 0, -1)
for i, val in enumerate(indices):
print(val) # I can tell that it's working after a few iterations
The first thing I tried was typing break in the debugging console when paused at the print(val) line. This resulted in a syntax error
SyntaxError: 'break' outside loop
I also thought about using the debugging console line to modify the variable that I am enumerating over. For example, entering
indices = []
This has no effect on the iterator. Apparently, the iterator has an independent copy of the variable.
In another language, Java for example, I would take advantage of the termination condition, but python loops don't have a termination condition. I could rewrite my for-loop as a while-loop so that it would have an explicit termination condition, but that would obfuscate the code.
The other option would be to add special debugging instructions. For example,
mode = 'debug'
indices = range(10000, 0, -1)
for i, val in enumerate(indices):
print(val) # I can tell that it's working after a few iterations
if mode == 'debug' and i % 10:
break
I dislike doing this because inevitably, one of these special instructions gets left in after debugging is finished and mucks everything up.
Do I have any other options to break out of the loop from the debug console or without modifying the code?
I dislike doing this because inevitably, one of these special instructions gets left in after debugging is finished and mucks everything up.
Python for loops just aren't designed to be changed during execution, besides hard coding break, return or throwing StopIteration. (You are debugging, so either change the range in the loops expression list, or let it run through). The reason being the advantages of straightforward simplicity outweigh exposing the for loop counter - see PEP 212.

Ignore pycharm breakpoint for first N hits

I'm trying to ignore a specific breakpoint in pycharm for the first N times it hits. Since I'm looking to set it to something like 10k, manually doing this is not an option. I found the expanded options for breakpoints, including the condition field, but I'm not sure how I can craft a condition which takes into account how many times the breakpoint has been hit. Thanks.
You can just create a variable in Python specifically for the breakpoint counting purpose, which you increment every time you you go past the break point line. Then just use that variable in your break point condition (i.e. breakpoint_count == 10000).
Update
If you can't add new code into the real python code you can use the breakpoint condition:
eval("exec('try:\\n x += 1\\nexcept NameError:\\n x = 1') or x == 10000")
What this does is execute a try statement which increments a variable or creates it if it doesn't exist. Then evaluates that along with a statement checking if the variable has been incremented enough times yet with that being your ending condition. Note, the exec is required to run the try, but the eval is needed to "return" the condition to PyCharm. This is absurdly hacky, but it works for your case!

PyCharm: debugging line by line?

I am using PyCharm (community version) for my Python IDE. I want the program to debug in a line-by-line fashion. So I don't want to set every line as a break point... Is there a way I could do this?
As #Cyber mentioned, the debugging hotkeys will let you step through line by line, step down into function calls, etc., once you've hit a breakpoint and stopped somewhere.
If you really want to step through each line, you could set a breakpoint somewhere at the very beginning of your code. If you're using a main() function in your code, e.g.:
def main():
....
if __name__ == '__main__':
main() # Breakpoint here, 'Step Inside' to go to next line
then you could set the breakpoint at the call to main(). (If you're not, you might want to try this approach.)
One other thing I'd point out is PyCharm's easy-to-overlook feature of conditional breakpoints. If you right-click on the breakpoint symbol in the gutter area of the editor, you can type in a condition, like n > 10; the breakpoint only triggers when that line is executed and the condition is met. When you're trying to debug code issues within a recursive function, say, this can simplify things a lot.
I know the last part isn't really what you were asking for, but as your codebase gets bigger, going through each line can get really time consuming. You'll probably want to focus more on things like unit testing and logging with larger projects.
To run in debug mode press the 'bug' button (or Shift + F9).
Step over - F8
Step into - F7
Step out - Shift+F8.
Step to next breakpoint (or end) - F9
The pdb module only needs 2 lines of code in your program to be able to step through line by line.
import pdb # Insert this as the first line of your program
pdb.set_trace() # Insert this once in your program to step through it
# code you want to step into
This youtube video explains everything in 6 mins.
As mentioned above you can use the hotkeys, alternatively, you can use the debugger UI:
The blue arrows on the top allow you to step over, step into, or step out.

How do I skip a loop with pdb?

How can I skip over a loop using pdb.set_trace()?
For example,
pdb.set_trace()
for i in range(5):
print(i)
print('Done!')
pdb prompts before the loop. I input a command. All 1-5 values are returned and then I'd like to be prompted with pdb again before the print('Done!') executes.
Try the until statement.
Go to the last line of the loop (with next or n) and then use until or unt. This will take you to the next line, right after the loop.
http://www.doughellmann.com/PyMOTW/pdb/ has a good explanation
You should set a breakpoint after the loop ("break main.py:4" presuming the above lines are in a file called main.py) and then continue ("c").
In the link mentioned by the accepted answer (https://pymotw.com/3/pdb/), I found this section somewhat more helpful:
To let execution run until a specific line, pass the line number to
the until command.
Here's an example of how that can work re: loops:
It spares you from two things: having to create extra breakpoints, and having to navigate to the end of a loop (especially when you might have already iterated such that you wouldn't be able to without re-running the debugger).
Here's the Python docs on until. Btw I'm using pdb++ as a drop-in for the standard debugger (hence the formatting) but until works the same in both.
You can set another breakpoint after the loop and jump to it (when debugging) with c:
pdb.set_trace()
for i in range(5):
print(i)
pdb.set_trace()
print('Done!')
If I understood this correctly.
One possible way of doing this would be:
Once you get you pdb prompt . Just hit n (next) 10 times to exit the loop.
However, I am not aware of a way to exit a loop in pdb.
You could use r to exit a function though.

Categories

Resources