Detect if interactive or script mode

Looking for a reliable way to establish whether running in an IDE/interactive or simple script mode. If running as a script I want to turn off logging to screen.

See sys.ps1.

What is ā€œsimple script modeā€?

I usually want to be able to turn on or off logging to stdout depending on operating system and/or if I am debugging.

For this I use a command line option quite often.

Unfortunately:

print(sys.ps1, sys.ps2)
      ^^^^^^^
AttributeError: module 'sys' has no attribute 'ps1'

Unfortunately redirecting stdout doesn’t stop logging going to the screen.

I have used hasattr(sys, "ps1") many times in the past for this purpose

The documentation says ā€œThese are only defined if the interpreter is in interactive mode.ā€

The test should be

import sys

if hasattr(sys, 'ps1'):
    print('We are in interactive mode.")

You can also combine this with looking at __name__

import sys

if __name__ == '__main__':
    print('Running as script')
    if hasattr(sys, 'ps1'):
        print('Interactive')
    else:
        print('Not interactive')
else:
    print('Loaded as a module')

Then I guess you are logging to stderr not stdout.
That is not uncommon.

Try redirecting stderr python script.py 2>script.log on unix systems.

Doesn’t seem to exist in version Python 3.14; always returns False.

Unfortunately always returns:

Running as script
Not interactive

Even when run from within the IDE.

You are correct, I hadn’t noticed that.

Setting sys.stderr = None does indeed stop output to screen.

I get this

Python 3.13.3 (main, Jan  8 2026, 12:03:54) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> if __name__ == '__main__':
...     print('Running as script')
...     if hasattr(sys, 'ps1'):
...         print('Interactive')
...     else:
...         print('Not interactive')
... else:
...     print('Loaded as a module')
...
Running as script
Interactive
>>>

In the normal python REPL / interactive mode, ps1 works (even in 3.14). It also works in VSCode’s interactive windows.

% python
Python 3.14.3 (main, Mar  2 2026, 19:29:06) [Clang 17.0.0 (clang-1700.6.3.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> hasattr(sys, 'ps1')
True

In IDLE, it looks like this may intentionally not work (see gh-76039). If you want to detect if its ran via IDLE, you could use 'idlelib.run' in sys.modules.

What does ā€œscript modeā€ mean to you? Running python file.py? And what do you mean by ā€œrun from within the IDEā€ or by ā€œinteractive modeā€?

Works for me.

% python
Python 3.14.5+ (heads/3.14:575916d5569, Jun  6 2026, 15:28:37) [Cla
ng 22.1.6 ] on darwin
Type "help", "copyright", "credits" or "license" for more informati
on.
>>> hasattr(sys, "ps1")
True
>>>

The most reliable way is to pass a parameter when you want it to be quiet, which you can check for using something like quiet = "-q" in sys.argv.

You could also use count.
The example shows the verbose option but if you use a default of 3 you could use the quiet option to decrease the verbosity!
In my case, 0 is no verbosity and -v|-vv|-vvv is verbosity level 1|2|3!

That is my issue and PR and not setting sys.ps1 is more of a side-effect of other changes. It is usually also irrelevant to this issue because the code in the patch is executed in the idle gui process. By default, user code such as discussed here is run in a separate execution process with a separate sys module. It would be easy to set it when that process is started, but it should only be set when interaction starts. I will try to make this happen.

This works whether one runs a script from the editor or by enterings at the ā€˜>>>’ prompt. Unless one starts IDLE with -n, idlelib/run.py is imported into the execution process when it starts.

Revert to original; setting sys.stdout = None doesn’t actually stop logging to screen from happening.

import sys
if name == 'main':
    print('Running as script')
    if hasattr(sys, 'ps1'):
        print('Interactive')
    else:
        print('Not interactive')
else:
print('Loaded as a module')

Running as script
Not interactive

Presumably this is something which has been broken in Python 3.14?

For me in PyCharm:

>>> import sys

hasattr(sys, ā€˜ps1’)
False

By script mode, in this case, I mean if running within the IDE then I would expect it to send logging to screen. However if run from a command line or run as a service, where there is nowhere to output screen to, then I would expect logging to not disable logging to screen.