How to reset warnings completely

How can I see the warning again without restarting python. Now I only see them once.

Consider this code for example:

import pandas as pd  
pd.Series([1]) / 0

      

I get

RuntimeWarning: divide by zero encountered in true_divide 

      

But when I run it again, it runs silently.

How can I see the warning again without restarting python?


I tried to do

del __warningregistry__

      

but that doesn't help.

It looks like only some types of warnings are stored there. For example, if I:

def f():   
    X = pd.DataFrame(dict(a=[1,2,3],b=[4,5,6]))
    Y = X.iloc[:2]
    Y['c'] = 8

      

then this will only raise a warning the first time it is called f()

. However, now when do del __warningregistry__

I see the warning again.


What is the difference between the first and second warning? Why is only the second stored in this __warningregistry__

? Where is the first one stored?

+3


source to share


2 answers


How can I see the warning again without restarting python?

As long as you start using the script, you don't need to restart.

import pandas as pd
import numpy as np
import warnings
np.seterr(all='warn')
warnings.simplefilter("always")

      

At this point, every time you try to divide by zero, it will display

RuntimeWarning: divide by zero encountered in true_divide 

      


Explanation:



We are creating a couple of alert filters. The first ( np.seterr

) tells NumPy how it should handle warnings. I've set it up to display warnings at all, but if you're only interested in seeing the division by zero warnings, change the setting from all

to divide

.

Next, we'll change how we want the module to warnings

always display warnings. We do this by creating an alert filter .

What is the difference between the first and second warning? Why is only the second one stored in this __warningregistry__? Where is the first one stored?

This is described in the bug report reporting this issue:

If you didn't raise the warning before using the simple filter, this will work. The unwanted behavior is due to the __warningsregistry__. It was installed when the warning was first issued. When the second warning comes up, the filter doesn't even look. I think the best way to fix this is to invalidate the __warningsregistry__ when the filter is used. It would probably be better to store the alert data globally rather than in a module, so it's easy to invalidate.

By the way, the bug was closed as fixed for versions 3.4 and 3.5.

+3


source


warnings

is a pretty awesome standard library module. You will love getting to know this :)

A bit of background

The warnings

default behavior is to show only a specific warning coming from a specific line when it first appears. For example, the following code will generate two warnings for the user:

import numpy as np

# 10 warnings, but only the first copy will be shown
for i in range(10):
    np.true_divide(1, 0)

# This is on a separate line from the other "copies", so its warning will show
np.true_divide(1, 0)

      

You have several options to change this behavior.

Option 1: Reset the alert registry

when you want python to "forget" what you saw before, you can use : resetwarnings

# warns every time, because the warnings registry has been reset
for i in range(10):
    warnings.resetwarnings()
    np.true_divide(1, 0)

      



Note that this will also reset any alert configuration changes you made. Which brings me to ...

Option 2: change the alert configuration

The alerts module documentation covers this in more detail, but one simple option is to use an easy- simplefilter

to-change default behavior.

import warnings
import numpy as np

# Show all warnings
warnings.simplefilter('always')
for i in range(10):
    # Now this will warn every loop
    np.true_divide(1, 0)

      

Since this is a global configuration change, it has global implications that you probably want to avoid (all warnings anywhere in your application will appear every time). A less drastic option is to use a context manager:

with warnings.catch_warnings():
    warnings.simplefilter('always')
    for i in range(10):
        # This will warn every loop
        np.true_divide(1, 0)

# Back to normal behavior: only warn once
for i in range(10):
    np.true_divide(1, 0)

      

There are also more detailed configuration changes for certain types of alerts. To do this, check the docs .

0


source







All Articles