How to tell the Python debugger to finish the program? - python

I have recently come across a VERY cool Python module called pdb. For those that are not familiar with it, it is super easy to use and gives you access to pretty much anything within scope at the time. All you have to do to use it is import pdb and put this line in your program where you want to set the breakpoint:
pdb.set_trace()
It works very much like gdb, and I wouldnt be surprised if it was built on top to some extent. Anyway, what I would like to know:
Say I have stopped at my first breakpoint, evaluated some things, and now I want to finish my program. How can I tell the debugger to finish the program, WITHOUT stopping at any more breakpoints? There are some commands, like continue, step, and next, but none of these seem to run the rest of the program uninterrupted. Anyone have some experience with this or am I asking for something that doesnt exist? Thanks!

I would just override pdb.set_trace function, delete all breakpoints and continue
pdb.set_trace = lambda : 0
The good thing is that you can do monkey patching in the debugger.
vikasdhi#redpanda:~$ cat ~/tmp/test.py
for i in range(1000):
import pdb
pdb.set_trace()
vikasdhi#redpanda:~$ python ~/tmp/test.py
> /home/vikasdhi/tmp/test.py(1)<module>()
-> for i in range(1000):
it stopped for the first time
(Pdb) c
> /home/vikasdhi/tmp/test.py(1)<module>()
-> for i in range(1000):
(Pdb) c
> /home/vikasdhi/tmp/test.py(1)<module>()
-> for i in range(1000):
when i want to skip everything i just replace the function
(Pdb) pdb.set_trace = lambda : 0
(Pdb) c
vikasdhi#redpanda:~$

the command is cl or clear.
cl(ear) [filename:lineno | bpnumber [bpnumber ...]]
With a filename:lineno argument, clear all the breakpoints at this line. With a space separated list of breakpoint numbers, clear those breakpoints. Without argument, clear all breaks (but first ask confirmation).

Related

Break points and Stepping through the code in Pandas/Python

In Excel VBA, we can step through a block of code by pressing the F8 key. Even inside a for loop, we can step though one line at a time by pressing the F8 key.
Also, we can add break points by pressing the F9 key. In order to halt the code running further more after a certain break-point.
These will help us to easily Debug & Test the code effortlessly.
My question is, Is there any similar shortcuts available in Python/Pandas? is it possible in python to step line by line inside a For loop and/or add break points like VBA?
There's a python debugger that you can import. pdb.set_trace will add checkpoints where you can step through code. There are also notebook implementations of this as well.
import pdb
x = 'hello'
print(x)
pdb.set_trace()
y = 'world'
print(y)
As of 3.7, there's a built-in breakpoint that removes the need to import pdb.

How to ignore the next pdb-like breakpoints, including set_trace() calls?

I'm having the following issue:
I have code very much like the following
def my_function():
import pdb; pdb.set_trace()
....
During runtime, my function is called a lot of times. I'm interested in inspecting the code execution the first time this function is called.
If I'm done inspecting, I'd want to hit c, and have the normal execution of the program resume, without stopping at this break point the next times this function is called.
Is there a way to do this? Or must I do something completely different, like putting the set_trace() call some place that's only called once, and then once the breakpoint is hit, using a command like tbreak my_function, to set a one-time break point there?
You can try setting an attribute of the function the first time it is executed. Something like:
def my_function():
if not hasattr(my_function,'first_time'):
my_function.first_time = 1 # Dummy value
import pdb; pdb.set_trace()
...
The attribute first_time will persist between function calls and the very first time the function is called, it will be created. Every next time the function is called, it will already exist and the code in the if statement will not be executed. This solution relies on your function not being a method inside a class since class methods can't have attributes, being that they're attributes of the class already.
Just as a note, I'm not sure if you have the import in your actual code, but best coding practices state you should put imports only at the beginning of your code, not inside functions as you have it.
When I have this problem , I import pdb; pdb.set_trace() at the beginning of the file (import time) or in __main__ (run time) then use the debugger list (or just l) command to find your line number and break (or just b) to set a breakpoint.
You can also launch the program in PDB mode from the start and get to the same point.
(Pdb) help break
b(reak) ([file:]lineno | function) [, condition]
With a line number argument, set a break there in the current
file. With a function name, set a break at first executable line
of that function. Without argument, list all breaks. If a second
argument is present, it is a string specifying an expression
which must evaluate to true before the breakpoint is honored.
The line number may be prefixed with a filename and a colon,
to specify a breakpoint in another file (probably one that
hasn't been loaded yet). The file is searched for on sys.path;
the .py suffix may be omitted.
I'll set a breakpoint at line 5, for example
(Pdb) b 5
Breakpoint 1 at /home/flipmcf/program.py:5
Now, continue
(Pdb) c
you will enter Pdb when the breakpoint is reached.
Since you only want to see the first run, simply remove the breakpoint
(Pdb) help clear
cl(ear) filename:lineno
cl(ear) [bpnumber [bpnumber...]]
With a space separated list of breakpoint numbers, clear
those breakpoints. Without argument, clear all breaks (but
first ask confirmation). With a filename:lineno argument,
clear all breaks at that line in that file.
Note that the argument is different from previous versions of
the debugger (in python distributions 1.5.1 and before) where
a linenumber was used instead of either filename:lineno or
breakpoint numbers.
(Pdb) clear 1
Deleted breakpoint 1
(Pdb) c

Tracing the execution of a Python program line/statement by line programmatically

What would be the easiest way to execute a Python script and, for each executed statement, pass the line number or the line itself to a callback function? For example
A piece of code to be executed
for i in range(5):
z = i**2
and a callback
def callback(line):
print line
The output would be:
for i in range(5):
z = i**2
for i in range(5):
z = i**2
for i in range(5):
z = i**2
...
etc
Another way of stating this is that I want to know the piece of code that would be next to execute if I were running the script stepping through a debugger.. I've seen this question about tracing but I'm interested in doing more than tracing the number of times executed in the callback function.
A debugger is going to be helpful, but only if I can run it non-interactive mode with the ability to call back to the python code
Look at the sys.settrace function. This allows you to specify a tracing function which is executed for every line of code. It was, I think, specifically implemented to create pdb so it's at the right level of abstraction you seem to want. Implementing what you want will not be trivial but I think it's the best place to start.
For an production program that uses this, look at coverage.py.
Accepting Noufal's answer since it put me on the right path, but this helped as well
http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html
The April's fools module goto is a working example of tracing implemented in Python, so although it's doubtlessly slower (than the C implementation in coverage.py), it's rather easy to understand. http://entrian.com/goto/

Counter in a recursive function in Python is not producing an output with Print(using Netbeans)

I am new to Python. I am using Netbeans IDE 6.8. When I run the code below- using RUN FILE- it does not seem to produce any output. On the other hand when I debug the code, the output shows the value of counter- 6.
Is this a problem with the program below or one of quirks of Netbeans.
Here is the code:
class Counter:
pass
def cInit():
# Create counter
ctr = Counter()
ctr.value = 0
# Define and call a recursive function that modifies counter
def inner(n):
if (n > 0): inner(n-1)
ctr.value = ctr.value + 1
inner(5)
# Get counter
return ctr.value
if __name__ == "__main__":
print "Hello World";
d = cInit()
print d
This is a classic "bug" of netbeans and other IDEs. For terminal programs, they open a terminal, run the program under it, and then close it. This of course, means that your output window disappears.
There are two ways to fix it, depending on your IDE. Some IDEs have an option to wait for a key press after program completion, it'll be buried in your options panel somewhere. The other is to put a raw_input() command at the end of your code, so that the terminal pauses and waits for user input before closing. That may get very annoying for your end users if they run the thing on the command line, since they may not want it to pause in the middle of a pipeline.
There is nothing wrong with your code, it works fine when run under the Python REPL. This may be a Netbeans quirk -- does print work in other files?
As a side note -- if this is something to do with Netbeans, don't expect any official fix anytime soon -- Oracle killed Python support in Netbeans 7

Get a Global Variable while a Python Program is running

I write a Python 2.5 Command Line program on CentOS 5.5 and it has been running for 1 day and is still running. Now I want to end this program but get the value of a global variable.
I have done some Google. It seems the only way to get the value of a global variable is to attach the Python program to a GDB.
Suppose the global variable is a List, and its name is resultlist. How can I get its value?
This is possible to do, but is extremely tricky, and a single wrong move will cause the program to crash (or be lost in an indeterminate state).
You can use the C function PyEval_GetGlobals() to return the dictionary of globals (as it would if you called globals() in python), and then use PyObject_Print() to print that object to a file (the easiest being whatever stdout is connected to).
You'll want to run GDB and attach it to the instance of python. Then set a breakpoint on a function you know will be called (if your program is printing output, then PyObject_Print() will work; otherwise this page has some functions that probably get called a lot.), then when the program hits the breakpoint, you'll want to disable it, and print the globals.
For example, if my Python program has a PID of 15847:
(gdb) attach 15847
Attaching to process 15847.
Reading symbols for shared libraries . done
Reading symbols for shared libraries ............. done
0x00007fff870b5e52 in select$DARWIN_EXTSN ()
(gdb) break PyObject_Print
Breakpoint 1 at 0x10003d8f4
(gdb) c
Continuing.
The next time your program goes to print something:
Breakpoint 1, 0x000000010003d8f4 in PyObject_Print ()
(gdb) disable
(gdb) call (int)PyObject_Print((void*)PyEval_GetGlobals())
$1 = 0
(gdb) c
Continuing.
Then, in the output of your program, you'll see the global dictionary.
I'm afraid names won't help you much. Since you didn't build in some printing mechanism and your process is already running you're pretty much screwed.
If you have an idea what the values might be your best bet would be using a process memory scanner and start messing around. Though I estimate your chances of success very low, I'm sorry.

Categories