Detect Where Python Code Is Running (e.g., In Spyder Interpreter Vs. Idle Vs. Cmd)
Solution 1:
Here is the solution I ended up using. After reading Markus's answer, I noticed that Spyder adds half a dozen or so environment variables to os.environ
with names like SPYDER_ENCODING
, SPYDER_SHELL_ID
, etc. Detecting the presence of any of these seems relatively unambiguous, compared to detecting the absence of a variable with as generic a name as 'PYTHONSTARTUP'
. The code is simple, and works independently of Spyder's startup script (as far as I can tell):
ifany('SPYDER'in name for name in os.environ)
# use alternativeelse:
# use getpass
Since the string is at the beginning of each environment variable name, you could also use str.startswith
, but it's less flexible, and a little bit slower (I was curious):
>>>import timeit>>>s = timeit.Timer("[name.startswith('SPYDER') for name in os.environ]", "import os")>>>i = timeit.Timer("['SPYDER' in name for name in os.environ]", "import os")>>>s.timeit()
16.18333065883474
>>>i.timeit()
6.156869294143846
The sys.executable
method may or may not be useful depending on your installation. I have a couple WinPython installations and a separate Python 2.7 installation, so I was able to check the condition sys.executable.find('WinPy') == -1
to detect a folder name in the path of the executable Spyder uses. Since the warning that shows in IDLE when you try to use getpass
is less "loud" than it could be, in my opinion, I ended up also checking the condition sys.executable.find('pythonw.exe') == -1
to make it slightly louder. Using sys.executable
only, that method looks like:
if sys.executable.find('pythonw.exe') == sys.executable.find('WinPy') == -1:
# use getpasselse:
# use alternative
But since I want this to work on other machines, and it's much more likely that another user would modify their WinPython installation folder name than that they would rename their IDLE executable, my final code uses sys.executable
to detect IDLE and os.environ
to detect Spyder, providing a "louder" warning in either case and keeping the code from breaking in the latter.
if any('SPYDER' in name for name in os.environ) \or'pythonw.exe' in sys.executable:
password = raw_input('WARNING: PASSWORD WILL BE SHOWN ON SCREEN\n\n' * 3
+ 'Please enter your password: ')else:
password = getpass.getpass("Please enter your password: ")
Solution 2:
By default, Spyder uses a startup scrip, see Preferences -> Console -> Adanced setting. This option is usually set to the scientific_startup.py
file that loads pylab et al.
The easiest solution is to just add a global variable to the file and then use that in your if statement, e.g. add this line at the end of scientific_startup.py
:
SPYDER_IDE_ACTIVE = True
In your script:
ifnot'SPYDER_IDE_ACTIVE' in globals():
use getpass
else:
use alternative
This will work without throwing an error. You can also use exceptions if you like that more.
A second solution would be (if you cannot modify that file for some reason) to just check if the environment variable PYTHONSTARTUP
is set. On my machine (using the Anaconda Python stack), it is not set for a regular Python shell. You could do
import osifnot'PYTHONSTARTUP'inos.environ:
use getpass
else:
use alternative
Solution 3:
Spyder provides the option of executing the current editor script in a native system terminal. This would produce identical behavior as if you were running from the command line. To set this up, open the Run Settings dialog by hitting F6
. Then select the radio button "Execute in an external System terminal". Now run the script as usual by hitting F5
. You should be able to use getpass
in the normal fashion with this approach.
Solution 4:
You could add env variable when running in Spyder and check it in code.
Post a Comment for "Detect Where Python Code Is Running (e.g., In Spyder Interpreter Vs. Idle Vs. Cmd)"