python -i (interactive environment)

J

Joe

When you run "python -i scriptname.py" after the script completes you left
at the interactive command prompt.

Is there a way to have this occur from a running program?

In other words can I just run scriptname.py (NOT python -i scriptname.py)
and inside of scriptname.py I decide that I want to fall back to the
interactive prompt?

I've searched and so far the only thing I've come up with is to use pdb, but
that is not exactly the same as the interactive prompt.

Is there any way to do it that I have missed?

Thanks.
 
P

Pierre Barbier de Reuille

Very simple is you're on UNIX ...

You juste have to put at the beginnin of your file :

#!/usr/bin/python -i

And it juste does what you want :)

Pierre

Joe a écrit :
 
J

Joe

Hi Pierre,

Thanks for the reply, but I am not on Unix and it even if I was that
solution it does not achieve the desired results.

I want the script to decide whether to fall back to the interactive prompt.
You solution makes it ALWAYS fall back to the interactive prompt.

I want to do something like:

try:
# execute code
except MyExceptionOccurred, except_msg:
# fall to interactive prompt.

In other words I want to have my program to determine whether the
interactive prompt to be displayed or not.

Thanks!
 
R

Raymond L. Buvel

I posted the following a while back. I think this is what you are
looking for.

This can be done fairly easily by creating a module (lets call it
interactive) with the following code in it.
-----------
import sys,os

def debug_exception(type, value, traceback):
# Restore redirected standard I/O
sys.stdin = sys.__stdin__
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__

# Kick the interpreter into interactive mode and call the original
# exception handler.
os.environ['PYTHONINSPECT'] = '1'
sys.__excepthook__(type, value, traceback)

sys.excepthook = debug_exception
-----------

Now if you import this module and raise an unhandled exception, you will
be in interactive mode. In other words, I think the following script
does what you are asking for.

-----------
import interactive

raise RuntimeError('Interactive Mode')
-----------

This also has the advantage that if there are no unhandled exceptions in
your script, the script runs and terminates normally.

Enjoy,
Ray Buvel
 
M

Michael Hoffman

Joe said:
I want the script to decide whether to fall back to the interactive prompt.
You solution makes it ALWAYS fall back to the interactive prompt.

Actually, using sys.exit() means the program can exit even if python -i
is used.

You can use:

import code
code.interact()

which emulates the interactive prompt.
 
M

MikeyG

Joe said:
When you run "python -i scriptname.py" after the script completes you left
at the interactive command prompt.

Is there a way to have this occur from a running program?

In other words can I just run scriptname.py (NOT python -i scriptname.py)
and inside of scriptname.py I decide that I want to fall back to the
interactive prompt?

I've searched and so far the only thing I've come up with is to use pdb, but
that is not exactly the same as the interactive prompt.

Is there any way to do it that I have missed?

Thanks.

Yes you can set the PYTHONINSPECT environment variable to something
other than an empty string from within your program.

MikeG
 
J

Joe

Thanks Michael, that's what I was looking for.

Are there any differences between that and the actual interactve prompt that
I should be aware of?

Would you consider that a better method than using (thanks to those who
suggested this other option):

import os
os.environ['PYTHONINSPECT'] = '1'
 
M

Michael Hoffman

Joe said:
Are there any differences between that and the actual interactve prompt that
I should be aware of?

I don't know, unfortunately.
Would you consider that a better method than using (thanks to those who
suggested this other option):

import os
os.environ['PYTHONINSPECT'] = '1'

Actually I would do that everyone else suggested for your use case. I thought
about trying this method but couldn't imagine that it would actually work!
 
J

Joe

Funny you said that, because I didn't even bother trying it because I didn't
think it would work either. I figured that python did something internally
when it saw the -i switch. Looks like it just checks for it when it's done
with your code.

One difference between the two methods that I see is that when you set
PYTHONINSPECT you don't really have to do anything else and unless
sys.exit() or raise SystemExit is used you will get the interactive prompt.

Using code.interact you would need to wrap everything in a try/except block
and call code.interact from there, or you could invoke it whenever you
wanted too. This has the advantage that you can even trap SystemExit if you
want too.

Thanks again to everyone!
 
R

Reinhold Birkenfeld

Michael said:
Joe said:
Are there any differences between that and the actual interactve prompt that
I should be aware of?

I don't know, unfortunately.
Would you consider that a better method than using (thanks to those who
suggested this other option):

import os
os.environ['PYTHONINSPECT'] = '1'

Actually I would do that everyone else suggested for your use case. I thought
about trying this method but couldn't imagine that it would actually work!

Actually, using this behavior is encouraged by the developers. See this
comment in Modules/main.c:

/* Check this environment variable at the end, to give programs the
* opportunity to set it from Python.
*/

Reinhold
 
J

Joe

Reinhold,

Interesting.

A key difference between the two is that PYTHONINSPECT will allow you access
to the prompt at the end of your program (assuming no sys.exit or raise
SystemExit) but code.interact() allows you to jump into the program at any
point.
 
S

Steve Holden

Michael said:
Actually, using sys.exit() means the program can exit even if python -i
is used.

You can use:

import code
code.interact()

which emulates the interactive prompt.

Unfortunately it does so in an entirely new namespace, thereby losing
the advantage of -i - namely, that you can investigate the program's
namespace after it's terminated.

regards
Steve
 
J

Just

Steve Holden said:
Unfortunately it does so in an entirely new namespace, thereby losing
the advantage of -i - namely, that you can investigate the program's
namespace after it's terminated.

code.interact() has a namespace argument ('local'), so it really easy to
have it use the namespace you want.

Just
 
P

Paulo Eduardo Neves

When I'm using pyunit and want to stop in a point during the test
(skipping all the framework initialization), I just start the debugger:

import pdb
pdb.set_trace()

You'll get the debugger prompt.
 
J

Joe

Found that out :-(

You can use the local=locals() option so at least you have access to the
local variables, which in the case of debugging, is exactly what I needed.

Since -i gives you control at the end of the program the locals are already
gone.

Seems like both approaches have their advantages depending on the situation.
 
J

Joe

Right, but only one namespace. Would be nice if there was a way to give it
both the global and the local namespaces. In my case though the local
namespace was sufficient.
 
J

Joe

Isn't this a bug?

Here's the test program:

import code

def test_func():
lv = 1
print '\n\nBEFORE lv: %s\n' % (lv)
code.interact(local=locals())
print '\n\nAFTER lv: %s\n' % (lv)
return

test_func()

gv = 1
print '\n\nBEFORE gv: %s\n' % (gv)
code.interact(local=locals())
print '\n\nAFTER gv: %s\n' % (gv)

Here's the output and interactive session:



BEFORE lv: 1

Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)


AFTER lv: 1



BEFORE gv: 1

Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)


AFTER gv: 2

In the case of code.interact being called inside the function, the locals
were available to the interactive environment but changes did not stick when
you returned back the function. (started as lv=1 changed to lv=2 in
interactive session, back to lv=1 in function) Since you are still in the
function and since code.interact used the same local environment why didn't
the change stick until testfunc ended?

When code.interact was called from the outside the function (globals() ==
locals()) the changes stuck. (started as gv=1, changed to gv=2 in
interactive session, stuck as gv=2 back in main).
 
S

Steven Bethard

Joe said:
Isn't this a bug?

Here's the test program:

import code

def test_func():
lv = 1
print '\n\nBEFORE lv: %s\n' % (lv)
code.interact(local=locals())
print '\n\nAFTER lv: %s\n' % (lv)
return

Check the documentation for locals() [1]:

"Update and return a dictionary representing the current local symbol
table. Warning: The contents of this dictionary should not be modified;
changes may not affect the values of local variables used by the
interpreter."

So if you change things in the dictionary returned by locals() you won't
actually change the local variables.

STeVe

[1] http://docs.python.org/lib/built-in-funcs.html#l2h-45
 
J

Joe

Steve,

Thanks, I knew about that but my question is why is it not working
consistently?

Joe


Steven Bethard said:
Joe said:
Isn't this a bug?

Here's the test program:

import code

def test_func():
lv = 1
print '\n\nBEFORE lv: %s\n' % (lv)
code.interact(local=locals())
print '\n\nAFTER lv: %s\n' % (lv)
return

Check the documentation for locals() [1]:

"Update and return a dictionary representing the current local symbol
table. Warning: The contents of this dictionary should not be modified;
changes may not affect the values of local variables used by the
interpreter."

So if you change things in the dictionary returned by locals() you won't
actually change the local variables.

STeVe

[1] http://docs.python.org/lib/built-in-funcs.html#l2h-45
 
S

Steven Bethard

Joe said:
Thanks, I knew about that but my question is why is it not working
consistently?

At the module level, locals() is globals():

py> locals() is globals()
True

And the globals() dict is modifiable.

HTH,

STeVe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,222
Messages
2,571,140
Members
47,755
Latest member
Grazynkaa

Latest Threads

Top