Check if program runs in Debug mode

Question:

I use the PyCharm IDE for Python programming.

Is there a possibility to check, whether I’m in debugging mode or not when I run my program?

I use pyplot as plt and want a Figure only to be shown if I debug my program. Yes, I could have a global boolean _debug_ which is set by myself, but I look for a better solution.

Asked By: themacco

||

Answers:

According to the documentation, settrace / gettrace functions could be used in order to implement Python debugger:

sys.settrace(tracefunc) 

Set the system’s trace function, which allows
you to implement a Python source code debugger in Python. The function
is thread-specific; for a debugger to support multiple threads, it
must be registered using settrace() for each thread being debugged.

However, these methods may not be available in all implementations:

CPython implementation detail: The settrace() function is intended
only for implementing debuggers, profilers, coverage tools and the
like. Its behavior is part of the implementation platform, rather than
part of the language definition, and thus may not be available in all
Python implementations.

You could use the following snippet in order to check if someone is debugging your code:

import sys


gettrace = getattr(sys, 'gettrace', None)

if gettrace is None:
    print('No sys.gettrace')
elif gettrace():
    print('Hmm, Big Debugger is watching me')
else:
    print("Let's do something interesting")
    print(1 / 0)

This one works for pdb:

$ python -m pdb main.py 
> /home/soon/Src/Python/main/main.py(3)<module>()
-> import sys
(Pdb) step
> /home/soon/Src/Python/main/main.py(6)<module>()
-> gettrace = getattr(sys, 'gettrace', None)
(Pdb) step
> /home/soon/Src/Python/main/main.py(8)<module>()
-> if gettrace is None:
(Pdb) step
> /home/soon/Src/Python/main/main.py(10)<module>()
-> elif gettrace():
(Pdb) step
> /home/soon/Src/Python/main/main.py(11)<module>()
-> print('Hmm, Big Debugger is watching me')
(Pdb) step
Hmm, Big Debugger is watching me
--Return--
> /home/soon/Src/Python/main/main.py(11)<module>()->None
-> print('Hmm, Big Debugger is watching me')

And PyCharm:

/usr/bin/python3 /opt/pycharm-professional/helpers/pydev/pydevd.py --multiproc --qt-support --client 127.0.0.1 --port 34192 --file /home/soon/Src/Python/main/main.py
pydev debugger: process 17250 is connecting

Connected to pydev debugger (build 143.1559)
Hmm, Big Debugger is watching me

Process finished with exit code 0
Answered By: awesoon

Tested with:

  • PyCharm 2020.2 (and many versions before that)
  • Python 3.7.5 (and many versions before that)
  • Windows 10 x64

There are two ways of debugging in PyCharm:

  • Method #1: Selection-Based Debug Mode: menu [ View > Tool Windows > Python Console ], then select a line, right click then Execute Selection in Python Console.
  • Method #2: Standard Debug Mode: Create a new configuration using Edit Configuration on the dropdown in the toolbar, can debug with breakpoints, variable watch, etc.

The function below detects method #1 (above), as it always passes in --port=XXXX on the command line.

C:pythonpython.exe "C:Program FilesJetBrainsPyCharm Professional Edition with Anaconda plugin 2020.1.1pluginspythonhelperspydevpydevconsole.py" --mode=client --port=53093

Function:

import sys

def is_debug_pycharm_by_select():
    """
    Detect if running in Selection-Based Debug Mode under PyCharm:
      -  PyCharm menu [ View > Tool Windows > Python Console ], highlight Python line in editor, right click "Execute Selection in Python Console".
    :return: True if executing selection in Python Console.
    """
    for arg in sys.argv:
        if "--port=" in arg:  # This debug mode passes in "--port=XXXX".
            return True
    return False

if is_debug_pycharm_by_select():
    print("Selection-Based Debug Mode.")
else:
    print("Some other debug mode.")

Answered By: Contango

The following works for me in VSCode:

import sys 

def debugger_is_active() -> bool:
    """Return if the debugger is currently active"""
    return hasattr(sys, 'gettrace') and sys.gettrace() is not None
Answered By: driedler

In Pycharm 2021.1.3 with Python 3.9.

Simply used

sys.gettrace()

Below, debug mood will show the printed ‘Now in debug’, and run will print the play Mood

import sys
gettrace= sys.gettrace()

# For debugging
debug_status=True if gettrace else False

def xtest_debug():
    if debug_status:
        print('Now in debug')
    else:
        print('Play Mood')
xtest_debug()
Answered By: mpx

Tested on PyCharm 2021.3.2:

def is_debug():
    import sys

    gettrace = getattr(sys, 'gettrace', None)

    if gettrace is None:
        return False
    else:
        v = gettrace()
        if v is None:
            return False
        else:
            return True
Answered By: RedEyed

Just wanted to add a couple alternative implementations.

Using contextlib.suppress:

import sys 
from contextlib import suppress

def is_debugging() -> bool:
    with suppress(AttributeError):
        return sys.gettrace()

Using "walrus" operator new since Python 3.8:

import sys 

def is_debugging() -> bool:
    return (gettrace := getattr(sys, 'gettrace')) and gettrace()
Answered By: wihlke

I don’t use pycharm, but to check if the program is being debugged using python -mpdb myFile.py, this code will work:

import sys
if 'pdb' in sys.modules:
    print("I'm being debugged")

as long as you don’t otherwise import pdb.

Answered By: snoopyjc

Adding these three short answer as it seems others are rather long or less to the point.
gettrace() is already a function so no need to write another…

Any of these could (for example) be used to set the logging module logger level.

(tested in Py3.9 with VSCode and PyCharm comtemporary to this post date)

from sys import gettrace
if gettrace():
    print("Debug")
else:
    print("Run")

or if you need a variable

import sys
DEBUG = sys.gettrace() is not None

or a global – not such a good idea as you risk namespace collisions in large projects.

import sys
sys.modules['GLOB_DEBUG'] = sys.gettrace()
Answered By: Jay M

If using Python logging module, you could call:

logging.root.isEnabledFor(logging.DEBUG)

for checking if the root logging level is debug.

Simple as that.

Answered By: Gabriele Iannetti