How to execute multi-line statements within Python's own debugger (PDB) - python

So I am running a Python script within which I am calling Python's debugger, PDB by writing:
import ipdb; ipdb.set_trace()
(iPython's version of PDB, though for the matter I don't think it makes a difference; I use it for the colored output only).
Now, when I get to the debugger I want to execute a multi-line statement such as an if clause or a for loop but as soon as I type
if condition:
and hit the return key, I get the error message *** SyntaxError: invalid syntax (<stdin>, line 1)
How can one execute multi-line statements within PDB? If not possible is there a way around this to still executing an if clause or a for loop?

You could do this while in pdb to launch a temporary interactive Python session with all the local variables available:
(pdb) !import code; code.interact(local=vars())
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
When you're done, use Ctrl-D to return to the regular pdb prompt.
Just don't hit Ctrl-C, that will terminate the entire pdb session.

In python3 ipdb (and pdb) have a command called interact. It can be used to:
Start an interactive interpreter (using the code module) whose global namespace contains all the (global and local) names found in the current scope.
To use it, simply enter interact at the pdb prompt. Among other things, it's useful for applying code spanning multiple lines, and also for avoiding accidental triggering of other pdb commands.

My recommendation is to use IPython embedding.
ipdb> from IPython import embed; embed()

Inside the Python (2.7.1) interpreter or debugger (import pdb), you can execute a multi-line statement with the following syntax.
for i in range(5): print("Hello"); print("World"); print(i)
Note: When I'm inside the interpreter, I have to hit return twice before the code will execute. Inside the debugger, however, I only have to hit return once.

There is the special case if you want a couple of commands be executed when hitting a break point. Then there is the debugger command commands. It allows you to enter multiple lines of commands and then end the whole sequence with the end key word. More with (pdb) help commands.

I don't know if you can do this, that'd be a great feature for ipdb though. You can use list comprehensions of course, and execute simple multi-line expressions like:
if y == 3: print y; print y; print y;
You could also write some functions beforehand to do whatever it is you need done that would normally take multiple lines.

Related

Syntax error when defining a function on the Python command line

I am trying to define a function on the Python REPL. Every time I try to run the below code, I get a syntax error.
Code:
def hello():
print ("Hello!")
hello()
Error:
C:\Users\~\Desktop>python
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> def hello():
... print ("Hello!")
... hello()
File "<stdin>", line 3
hello()
^
SyntaxError: invalid syntax
A possible explanation I've come across on stackoverflow is this post Python Error : File "<stdin>" where it says I can't run scripts from the Python interpreter. If that's true, why is that the case? I.e. if I'm able to run >>>2+2 in the cmd window, why am I not able to run a 'def' function? Hoping to look for clarification on this point - Thanks!
Edit: Put the error in text, not just the pic.
Press enter once after defining your function (that is, enter one blank line). Essentially, this lets Python know that you are done defining your function.
Once you see >>> again, you can call your function.
See the picture for how it should look when done right:
If you want to understand why this is happening, rather than just learn a workaround that works for some mysterious reason:
Interactive mode works by reading, compiling, and executing one statement at a time. This is a dead-simple rule—besides being dead-simple to implement it in the C code, it's also dead-simple to work through exactly in your head—once you understand it, that is. When given a choice between an implementation that's easy to explain, document, and work through in your head or one that's more complicated but sometimes easier to use, Python usually goes with the former.
If you enter a simple one-line statement, that's easy: the line is a complete statement, so it just compiles and executes that line.
But if you enter the first line of a compound statement—one that has a : on the end of the line and then an indented block—the statement isn't done until you write an indented block and then unindent again. So, it prints that special ... prompt instead of >>> to let you know it's continuing to read the same statement, and keeps going until you unindent.
If you unindent by typing a blank line, the statement is done, so it compiles and executes it, and everything is good.
If you unindent by typing a new one-liner statement, now it has two statements. If it tries to compile and run that as a single statement, that fails.
By the way, there's nothing magical about def here; the same thing will happen with any compound statement:
>>> for i in range(10):
... print(i)
... print('Done')
You'll get the same SyntaxError.
Couldn't Python figure out that you gave it two statements, and compile and run them one after another? Yes. In fact, if you use IPython/Jupyter, it actually does exactly that. But this would make the rule more complicated—not to mention things like handling exceptions in the first statement. Python chooses the simple rule you can trace through in your head over the complicated rule here, even though the complicated rule would do what you want more often.
So, how does this work in a module file? Well, modules aren't compiled a statement at a time, they're compiled all at once, as a list of statements, and then run all at once. That obviously doesn't work for the interactive terminal, because it can't run anything until it compiles everything, and it doesn't have everything until quitting time.
One last thing: why do continued expressions work?
>>> (1 +
... 2)
3
Expressions don't care about indentation. They end when all the parens/brackets/braces are balanced at the end of a line, not when the next line is unindented. So, as soon as you enter that 2), it knows the input is complete, and can compile it.
And the same thing is true for backslash continuation:
>>> 1 + \
... 2
3
No need for an unindented line; as soon as you type that 2 without a backslash continuation, the input is complete.
You should add a newline between defining function and calling it:
def hello():
print ("Hello!")
hello()
It looks like you've entered the whole block as a single statement. You'll need to hit enter after entering:
def hello():
print ("Hello!")
So that the interpreter understands that this is a single definition that you've entered. Once that's been defined, then try running the hello() function.

Import lPython to debug a program

Someone explain to me instead of verifying your python code program with some print function, it is suggested to use :
import lPython
lPython.embed()
As I don't have I lot of experience with python, could anyone be able to show me how it work with an example? And maybe how to understand each statement?
I believe you have a typo with IPython.
Here is an example:
a = 1
from IPython import embed # please notice the 'I' not the 'l'
embed()
c = 2
What this line of code does - it stops execution of your program and runs python session which allows you to introspect values. For instance if I run this code:
python tmp.py
It will stop the execution, run python and it will show you an ipython interpepator.
Python 2.7.13 (default, Dec 18 2016, 07:03:39)
Type "copyright", "credits" or "license" for more information.
IPython 5.1.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]:
If you type 'who' there you will list of all variables defined before ipython was called. See more information here: ipythondocs
however
I would strongly recommend to get familiar with pdb or ipdb.
Check documentation here pdbdocs. It is much more easier and gives you an ability of actual debugging of the code as in previous solution any changes you make - will not affect execution runtime.

Is there an interpreter for Python similar to Pry for Ruby? [duplicate]

Is there a way to programmatically force a Python script to drop into a REPL at an arbitrary point in its execution, even if the script was launched from the command line?
I'm writing a quick and dirty plotting program, which I want to read data from stdin or a file, plot it, and then drop into the REPL to allow for the plot to be customized.
I frequently use this:
def interact():
import code
code.InteractiveConsole(locals=globals()).interact()
You could try using the interactive option for python:
python -i program.py
This will execute the code in program.py, then go to the REPL. Anything you define or import in the top level of program.py will be available.
Here's how you should do it (IPython > v0.11):
import IPython
IPython.embed()
For IPython <= v0.11:
from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed()
ipshell() # this call anywhere in your program will start IPython
You should use IPython, the Cadillac of Python REPLs. See http://ipython.org/ipython-doc/stable/interactive/reference.html#embedding-ipython
From the documentation:
It can also be useful in scientific
computing situations where it is
common to need to do some automatic,
computationally intensive part and
then stop to look at data, plots, etc.
Opening an IPython instance will give
you full access to your data and
functions, and you can resume program
execution once you are done with the
interactive part (perhaps to stop
again later, as many times as needed).
You can launch the debugger:
import pdb;pdb.set_trace()
Not sure what you want the REPL for, but the debugger is very similar.
To get use of iPython and functionality of debugger you should use ipdb,
You can use it in the same way as pdb, with the addition of :
import ipdb
ipdb.set_trace()
I just did this in one of my own scripts (it runs inside an automation framework that is a huge PITA to instrument):
x = 0 # exit loop counter
while x == 0:
user_input = raw_input("Please enter a command, or press q to quit: ")
if user_input[0] == "q":
x = 1
else:
try:
print eval(user_input)
except:
print "I can't do that, Dave."
continue
Just place this wherever you want a breakpoint, and you can check the state using the same syntax as the python interpreter (although it doesn't seem to let you do module imports).
It's not very elegant, but it doesn't require any other setup.
Great answers above, but if you would like this functionality in your IDE. Using Visual Studio Code (v1.5.*) with Python Setup:
Highlight the lines you would like to run and
right click and select Run Selection/Line in Interactive Window from the drop down.
Press shift + enter on your keyboard.
Right click on the Python file you want to execute in the file explorer and select Run Current File in Interactive Window
This will launch an interactive session, with linting, code completion and syntax highlighting:
Enter the code you would like to evaluate, and hit shift + enter on your keyboard to execute.
Enjoy Python!

How can I add a command to the Python interactive shell?

I'm trying to save myself just a few keystrokes for a command I type fairly regularly in Python.
In my python startup script, I define a function called load which is similar to import, but adds some functionality. It takes a single string:
def load(s):
# Do some stuff
return something
In order to call this function I have to type
>>> load('something')
I would rather be able to simply type:
>>> load something
I am running Python with readline support, so I know there exists some programmability there, but I don't know if this sort of thing is possible using it.
I attempted to get around this by using the InteractivConsole and creating an instance of it in my startup file, like so:
import code, re, traceback
class LoadingInteractiveConsole(code.InteractiveConsole):
def raw_input(self, prompt = ""):
s = raw_input(prompt)
match = re.match('^load\s+(.+)', s)
if match:
module = match.group(1)
try:
load(module)
print "Loaded " + module
except ImportError:
traceback.print_exc()
return ''
else:
return s
console = LoadingInteractiveConsole()
console.interact("")
This works with the caveat that I have to hit Ctrl-D twice to exit the python interpreter: once to get out of my custom console, once to get out of the real one.
Is there a way to do this without writing a custom C program and embedding the interpreter into it?
Edit
Out of channel, I had the suggestion of appending this to the end of my startup file:
import sys
sys.exit()
It works well enough, but I'm still interested in alternative solutions.
You could try ipython - which gives a python shell which does allow many things including automatic parentheses which gives you the function call as you requested.
I think you want the cmd module.
See a tutorial here:
http://wiki.python.org/moin/CmdModule
Hate to answer my own question, but there hasn't been an answer that works for all the versions of Python I use. Aside from the solution I posted in my question edit (which is what I'm now using), here's another:
Edit .bashrc to contain the following lines:
alias python3='python3 ~/py/shellreplace.py'
alias python='python ~/py/shellreplace.py'
alias python27='python27 ~/py/shellreplace.py'
Then simply move all of the LoadingInteractiveConsole code into the file ~/py/shellreplace.py Once the script finishes executing, python will cease executing, and the improved interactive session will be seamless.

How to drop into REPL (Read, Eval, Print, Loop) from Python code

Is there a way to programmatically force a Python script to drop into a REPL at an arbitrary point in its execution, even if the script was launched from the command line?
I'm writing a quick and dirty plotting program, which I want to read data from stdin or a file, plot it, and then drop into the REPL to allow for the plot to be customized.
I frequently use this:
def interact():
import code
code.InteractiveConsole(locals=globals()).interact()
You could try using the interactive option for python:
python -i program.py
This will execute the code in program.py, then go to the REPL. Anything you define or import in the top level of program.py will be available.
Here's how you should do it (IPython > v0.11):
import IPython
IPython.embed()
For IPython <= v0.11:
from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed()
ipshell() # this call anywhere in your program will start IPython
You should use IPython, the Cadillac of Python REPLs. See http://ipython.org/ipython-doc/stable/interactive/reference.html#embedding-ipython
From the documentation:
It can also be useful in scientific
computing situations where it is
common to need to do some automatic,
computationally intensive part and
then stop to look at data, plots, etc.
Opening an IPython instance will give
you full access to your data and
functions, and you can resume program
execution once you are done with the
interactive part (perhaps to stop
again later, as many times as needed).
You can launch the debugger:
import pdb;pdb.set_trace()
Not sure what you want the REPL for, but the debugger is very similar.
To get use of iPython and functionality of debugger you should use ipdb,
You can use it in the same way as pdb, with the addition of :
import ipdb
ipdb.set_trace()
I just did this in one of my own scripts (it runs inside an automation framework that is a huge PITA to instrument):
x = 0 # exit loop counter
while x == 0:
user_input = raw_input("Please enter a command, or press q to quit: ")
if user_input[0] == "q":
x = 1
else:
try:
print eval(user_input)
except:
print "I can't do that, Dave."
continue
Just place this wherever you want a breakpoint, and you can check the state using the same syntax as the python interpreter (although it doesn't seem to let you do module imports).
It's not very elegant, but it doesn't require any other setup.
Great answers above, but if you would like this functionality in your IDE. Using Visual Studio Code (v1.5.*) with Python Setup:
Highlight the lines you would like to run and
right click and select Run Selection/Line in Interactive Window from the drop down.
Press shift + enter on your keyboard.
Right click on the Python file you want to execute in the file explorer and select Run Current File in Interactive Window
This will launch an interactive session, with linting, code completion and syntax highlighting:
Enter the code you would like to evaluate, and hit shift + enter on your keyboard to execute.
Enjoy Python!

Categories

Resources