9

Is there a way for a python script to automatically detect whether it is being run interactively or not? Alternatively, can one detect whether ipython is being used versus the regular c python executable?

Background: My python scripts generally have a call to exit() in them. From time to time, I run the scripts interactively for debugging and profiling, usually in ipython. When I'm running interactively, I want to suppress the calls to exit.

Clarification:

Suppose I have a script, myscript.py, that looks like:

#!/usr/bin/python
...do useful stuff...
exit(exit_status)

Sometimes, I want to run the script within an IPython session that I have already started, saying something like:

In [nnn]: %run -p -D myscript.pstats myscript.py

At the end of the script, the exit() call will cause ipython to hang while it asks me if I really want to exit. This is a minor annoyance while debugging (too minor for me to care), but it can mess up profiling results: the exit prompt gets included in the profile results (making the analysis harder if I start a profiling session before going off to lunch).

What I'd like is something that allows me modify my script so it looks like:

#!/usr/bin/python
...do useful stuff...
if is_python_running_interactively():
    print "The exit_status was %d" % (exit_status,)
else:
    exit(exit_status)
sorin
  • 161,544
  • 178
  • 535
  • 806
Mr Fooz
  • 109,094
  • 6
  • 73
  • 101

4 Answers4

14

I stumbled on the following and it seems to do the trick for me:

def in_ipython():
    try:
        return __IPYTHON__
    except NameError:
        return False
Mr Fooz
  • 109,094
  • 6
  • 73
  • 101
5

I compared all the methods I found and made a table of results. The best one seems to be this:

hasattr(sys, 'ps1')

enter image description here

If anyone has other scenarios that might differ, comment and I'll add it

pyjamas
  • 4,608
  • 5
  • 38
  • 70
4

Docs say that sys.ps1 doesn't exist in noninteractive mode. Additionally, one can use sys.flags (for python 2.6+) to detect if we have used python -i <whatever>.

This scripts detects if we run interactively, non-interactively, and in post-mortem mode (which may be attributed to interactive mode if python interpreter is called using python -i implicitly and user thinks he landed into "interactive" console):

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys

# IPython recognition is missing; test here if __IPYTHON__ exists, etc.

if hasattr(sys, 'ps1'):
    print("Running interactively.")
else:
    print("Not running interactively...")
    if sys.flags.interactive:
        print("... but I'm in interactive postmortem mode.")

IPython support can be added as described by Mr Fooz.

MasterScrat
  • 7,090
  • 14
  • 48
  • 80
dmitry_romanov
  • 5,146
  • 1
  • 33
  • 36
3

When invoked interactively, python will run the script in $PYTHONSTARTUP, so you could simply have that environment variable invoke a script which sets a global

William Pursell
  • 204,365
  • 48
  • 270
  • 300