Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
392 views
in Technique[技术] by (71.8m points)

python - Get Traceback of warnings

In numpy we can do np.seterr(invalid='raise') to get a traceback for warnings raising an error instead (see this post).

  • Is there a general way for tracing warnings?
  • Can I make python to give a traceback, when a warning is raised?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can get what you want by assigning to warnings.showwarning. The warnings module documentation itself recommends that you do that, so it's not that you're being tempted by the dark side of the source. :)

You may replace this function with an alternative implementation by assigning to warnings.showwarning.

You can define a new function that does what warning.showwarning normaly does and additionally it prints the stack. Then you place it instead of the original:

import traceback
import warnings
import sys

def warn_with_traceback(message, category, filename, lineno, file=None, line=None):

    log = file if hasattr(file,'write') else sys.stderr
    traceback.print_stack(file=log)
    log.write(warnings.formatwarning(message, category, filename, lineno, line))

warnings.showwarning = warn_with_traceback

After this, every warning will print the stack trace as well as the warning message. Take into account, however, that if the warning is ignored because it is not the first one, nothing will happen, so you still need to execute:

warnings.simplefilter("always")

You can get a similar control that the one numpy.seterr gives through the warning module's filters

If what you want is python to report every a warning every time it is triggered and not only the first time, you can include something like:

import warnings
warnings.simplefilter("always")

You can get other behaviours by passing different strings as arguments. Using the same function you can also specify different behaviours for warnings depending on the module that raised them, the message they provide, the warning class, the line of code that is causing it and so on...

You can check the list in the module documentation

As an example, you can set all the warnings to raise exceptions, except the DeprecationWarnings that should be ignored completely:

import warnings
warnings.simplefilter("error")
warnings.simplefilter("ignore", DeprecationWarning)

This way you get the full traceback for each warning raised as error (only the first one, since execution will stop... but you can address them one by one, and create a filter to ignore the ones you don't want to hear about again...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...