Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pythonic, custom warnings

Basic question: What's the most Pythonic/logical way to make my own, custom warning classes? What are the correct warning and exception classes that I should be subclassing?

Motivation: The requirements for the library I'm writing specify that if a MyContainer object c contains an item x and the caller of the library tries to place a "duplicate" of x -- call it y -- into c, a warning is issued to the caller and the return value of c.my_transformation_method(x, y) is placed into c to replace x. In other words, MyContainers will replace elements with their duplicates, but must warn the user when doing so.

Based on my reading, the most flexible way to warn the caller of a library about a nonfatal action is with the warnings standard module. It allows the caller to handle the warning as it sees fit, doing anything from ignoring warnings to treating them as errors. (Note that I'm using Python 3, but I don't think that's essential to the question here.)

Example: What I've done is defined the following warning subclass:

class DuplicateItemWarning(UserWarning, ValueError):
    pass

Then the add() method of MyContainer calls warnings.warn('detected duplicate', DuplicateItemWarning) when it detects an attempt to insert a duplicate item.

Specific questions:

  1. Should I be subclassing UserWarning as above, or just sublcassing Warning?

  2. It seems semantically sensible to subclass ValueError (which, in the above example, merely inserts ValueError in the MRO between Warning and Exception) in case a caller wants to treat warnings as errors. Is there a drawback to this I'm not seeing?

  3. I could find no previous questions on StackOverflow about customizing warning classes. Is this because Python programmers don't even like using the warnings module?

like image 832
wkschwartz Avatar asked Apr 25 '12 18:04

wkschwartz


People also ask

How do you add warnings in Python?

Warning Functions In the above program warnings are displayed using the warn() function of warning module. filterwarnings(action, message=”, category=Warning, module=”, lineno=0, append=False): This function adds an entry into the specifications of the warnings filter.

What Is syntax warning in Python?

Python has a SyntaxWarning that can warn you about dubious syntax that is typically not a SyntaxError . Python 3.8 adds a few new ones that can help you when you're coding and debugging. The difference between is and == can be confusing.

What is DeprecationWarning in Python?

removing is danger because user may used that and if a developer want to remove a thing first have to notify others to don't use this feature or things and after this he can remove. and DeprecationWarning is this notification.


1 Answers

After reading the PEP 230 about the warning framework and the warnings docs, I think I have the answer to your questions:

  1. UserWarning and all others are warning categories, they don't seem to have another role than just classification. This way you could filter them out in your production environment for example. So, basically, you could subclass from Warning if the warning does not fall in any other category. If in the context, UserWarning or RuntimeWarning seem enough, just use them.

  2. Warnings are already Exceptions. So, technically, to "catch" them as errors, you just need to change the filter, no need to subclass from any XXXError. Now, again it's all about making sense. If the warnings are about the values passed, you could subclass from ValueError, especially if there would be many different custom warnings, you would expect the caller to "catch" all warnings regarding values all at once.

    try:
         # do something
    except MyCustomWarningOne:
        # do something else
    except MyCustomWarningTwo:
        # do something else also
    except ValueError: # or RuntimeWarning if you subclass from it
        # catch some other warning (both of these subclass from ValueError for example)
    
  3. The warnings module is Guido van Rossum's idea. (See PEP 230). If that ain't Pythonic enough ... :D

like image 199
jadkik94 Avatar answered Oct 01 '22 16:10

jadkik94