How to automatically switch to debug mode on a warning?
I found the answer offered by @user2683246 elegant and useful. Here is a variant of the solution modified for compatibility with Python3 (tested with Python 3.7):
#!/usr/bin/env python
import pdb, warnings, sys
import builtins
if __name__ == '__main__':
args, n = [], len(sys.argv)
if n < 2:
sys.exit(1)
elif n > 2:
args.append(builtins.__dict__[sys.argv[2]])
if n > 3:
args.append(int(sys.argv[3]))
warnings.simplefilter('error', *args) # treat warnings as exceptions
try:
with open(sys.argv[1]) as f:
code = compile(f.read(), sys.argv[1], 'exec')
exec(code)
except:
pdb.post_mortem(sys.exc_info()[-1])
Notable changes:
- Replace the
execfile()
call with the Python 3 variant; and - Replace
__builtin__
withbuiltins
.
You can write a script dbg.py
:
import pdb, warnings, sys
import __builtin__
if __name__ == '__main__':
args, n = [], len(sys.argv)
if n < 2:
sys.exit(1)
elif n > 2:
args.append(__builtin__.__dict__[sys.argv[2]])
if n > 3:
args.append(int(sys.argv[3]))
warnings.simplefilter('error', *args) # treat warnings as exceptions
try:
execfile(sys.argv[1])
except:
pdb.post_mortem(sys.exc_info()[-1])
You can then use it to debug your script like that. Pass in your script name as the first argument if you want to run pdb on any warning:
$ python dbg.py yourscript.py
Pass in warning type as the second argument if you only want pdb to run when some particular type of warning is raised:
$ python dbg.py yourscript.py DeprecationWarning
Line number as the third argument:
$ python dbg.py yourscript.py DeprecationWarning 342
You can also rewrite the code using warnings.filterwarnings
instead of warnings.simplefilter
to make warnings filtering even more flexible.