Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debug python CLI that takes stdin?

I'm trying to debug a Python CLI I wrote that can take its arguments from stdin. A simple test case would have the output of

echo "test" | python mytool.py 

be equivalent to the output of

python mytool.py test 

I'd like to debug some issues with this tool, so I tried to run this:

echo "test" | pdb mytool.py 

But I get this output, then pdb exits:

> /path/to/mytool.py(5)<module>() -> ''' (Pdb) *** NameError: name 'test' is not defined (Pdb) 

The same thing occurs when I add -m python to the shebang, and if I run pdb.set_trace() inside the script.

What's going on here?

like image 263
whereswalden Avatar asked Jun 12 '13 19:06

whereswalden


People also ask

How do you debug Python command line arguments?

Go to your project properties, either by right-clicking on the project and picking "Properties" or by picking Properties from the Project menu. Click on Debug, then enter your arguments into the "Script Arguments" field. Save.

How do you debug Python in terminal?

Directly use command python pdg-debug.py without -m pdb to run the code. The program will automatically break at the position of pdb. set_trace() and enter the pdb debugging environment. You can use the command p variable to view the variables or use the command c to continue to run.

How do I run a Python script in debug mode?

Starting Python Debugger To start debugging within the program just insert import pdb, pdb. set_trace() commands. Run your script normally and execution will stop where we have introduced a breakpoint.


1 Answers

Another option is to create you own Pdb object, and set there the stdin and stdout. My proof of concept involves 2 terminals, but for sure some work can be merged some kind of very unsecure network server.

  1. Create two fifos:

    mkfifo fifo_stdin mkfifo fifo_stdout 
  2. In one terminal, open stdout on background, and write to stdin:

    cat fifo_stdout & cat > fifo_stdin 
  3. In your python code/console create the pdb object, and use it:

    import pdb mypdb=pdb.Pdb(stdin=open('fifo_stdin','r'), stdout=open('fifo_stdout','w')) ... mypdb.set_trace() ... 
  4. Profit!

You should be able to use pdb on the first console.

The only drawback is having to use your custom pdb, but some monkey patching at init (PYTHONSTARTUP or similar) can help:

import pdb mypdb=pdb.Pdb(stdin=open('fifo_stdin','r'), stdout=open('fifo_stdout','w')) pdb.set_trace=mypdb.set_trace 
like image 148
dmoreno Avatar answered Sep 18 '22 23:09

dmoreno