Debug keyword to allow debug code to be nooped

Often in our python code we will have code that is only supposed to run when in debug mode, what we’ve found is there are 2 common pitfalls with the way of handling this today.

  1. Every codebase ends up with it’s own way to disable the debugging code.
  2. It’s easy to write debug code that still has the code evaluated by the python intepreatator at some level even if it never runs. This can be a problem for performance sensitive code since the small amount of time to evaluate the debug condition can still count. For example it’s not easy to disable logger.debug calls in a way where we don’t incur the penalty for those lines evaluating.

My suggestion for a nice QOL improvment for python would be to introduce a “debug context manager”, Python already has a “optimized mode”. Right now that just disables assert but what if it could also allow us to write code that can be switched off.

I’m not sure what the syntax could be but perhaps something as simple as:

debug logger.debug(f'The size of this image is: {expensive_debug_shape_calculation(image)}")

or

debug:
   # Bunch of expensive lines of code only needed fordebugging
   #

Essentially it would work like “assert” but instead of being focused on assertions it would just be a hint to python that this line of code can be ignored when in optimized mode.

Maybe if __debug__?

Which already exists and is implemented via the -O option.

6 Likes

More than maybe, that’s exactly what if __debug__ does :slight_smile:

rosuav@sikorsky:~$ echo 'if __debug__: print("Hello")'|python3 -m dis
  0           RESUME                   0

  1           LOAD_NAME                0 (print)
              PUSH_NULL
              LOAD_CONST               1 ('Hello')
              CALL                     1
              POP_TOP
              LOAD_CONST               2 (None)
              RETURN_VALUE
rosuav@sikorsky:~$ echo 'if __debug__: print("Hello")'|python3 -Om dis
  0           RESUME                   0

  1           LOAD_CONST               1 (None)
              RETURN_VALUE

As you can see, with the -O parameter, it gets completely compiled out.

The problem with __debug__ sadly is that it requires the -O flag to set it to False. So almost all uses of python software will be run as debug and it would require special knowledge to have it run as production. Furthermore, quite a lot of the ways python code is run by end-user, either don’t let you set that flag or make it obscure how to set it.

Result is that only people that already know the ins and outs of python will be able to run some python software as „not debug“, which is a little bit backwards.

I have seen core dev write similar things about the __debug__ keyword.

EDIT: Don’t actually want to claim such a thing, if I can’t find a link to that discussion anymore.

I personally think its is almost useless

I get the feeling that the python source code thinks the same way, because it has the -X dev flag that sets developer mode.

I usually check for that flag being set and then run possible debug code depending on it.


If sys.flags.dev_mode:
    …

Probably has some overhead and needs extra code. Would be nice if we could have it as a keyword, but I wouldn’t even know how it could be named to be backwards compatible.

It also would be impossible to happen with the requirements to get a new keyword in. Yes it is only an attribute check now, but it requires an import and it just feels wrong to have a __debug__ keyword that is semi useless in a majority of cases and a usefull way being buried two levels deep in the sys module.

Edit 2:

Just noticed that I have missed the part were the original Idea was for only the case of running with -O. In that case __debug__ is exactly that. Never wanted to hijack the conversation so Mods feel free to delete this if you want,no need to migrate it to a new idea or so.

I don’t understand. Why check for -X dev instead of checking for -O ? Everything you’ve said about -O being obscure and little-used applies even more strongly to -X dev, plus it’s a run-time check that can’t be optimized out.

-O sets __debug__ to false

-X sets sys.flags.dev_mode to true

If I double click my python script, without doing anything else, __debug__ will always be true, while dev mode will be false.

With dev mode I explicitly set something to run my software in a debug state and everyone that does not know python flags, does not have to care. With -O they need to know that flag exist and need to pass it in everytime if they dont want to be spammed by debug messages or debug code.

1 Like