How to assert both UserWarning and SystemExit in pytest

2024/10/13 17:19:12

Assert UserWarning and SystemExit in pytest

In my application I have a function that when provided with wrong argument values will raise a UserWarnings from warnings module and then raises SystemExit from sys module.

Code is something like:

def compare_tags(.....):requested_tags = user_requested_tags # as listall_tags = tags_calculated_from_input_file  # as list non_matching_key = [x for x in requested_tags if x not in all_tags]# if user requested non existing tag then raise warning and then exit if len(non_matching_key) > 0:# generate warningwarnings.warn("The requested '%s' keys from '%s' is not present in the input file. Please makes sure the input file has the metadata of interest or remove the non matching keys." %(non_matching_key, given_tags))# raise system exitsys.exit(0)

writing a pytest for above function

I want to test this UserWarning and SystemExit in pytest at once. I can check for SystemExit in the pytest as.

with pytest.raises(SystemExit):compare_tags(....)

but this will also dispaly a warning message (which is not an error).

If I want to check for warnings:

pytest.warns(UserWarning, compare_tags(...)

This will generate a SystemExit error because this called function will trigger system exit.

How can I put both the warnings and SystemExit check in the same pytest?

Answer

pytest.warns and pytest.raises are the usual context managers and can be declared in a single with statement when separated with a comma (see compound statements):

with pytest.warns(UserWarning), pytest.raises(SystemExit):compare_tags(...)

which is effectively the same as writing

with pytest.warns(UserWarning):with pytest.raises(SystemExit):compare_tags(...)

Notice that the order matters - when you put both context managers in the reverse order:

with pytest.raises(SystemExit), pytest.warns(UserWarning):...

this is the same as writing

with pytest.raises(SystemExit):with pytest.warns(UserWarning):...

The problem here is that pytest.raises will capture all raised errors and then check for what's captured. This includes what pytest.warns raises. This means that

with pytest.raises(SystemExit), pytest.warns(UserWarning):sys.exit(0)

will pass because the error raised in pytest.warns will be swallowed in pytest.raises, while

with pytest.warns(UserWarning), pytest.raises(SystemExit):sys.exit(0)

will fail as expected.

https://en.xdnf.cn/q/69510.html

Related Q&A

Distinguish button_press_event from drag and zoom clicks in matplotlib

I have a simple code that shows two subplots, and lets the user left click on the second subplot while recording the x,y coordinates of those clicks.The problem is that clicks to select a region to zoo…

String reversal in Python

I have taken an integer input and tried to reverse it in Python but in vain! I changed it into a string but still I am not able to. Is there any way to reverse it ? Is there any built-in function?I a…

Python: passing functions as arguments to initialize the methods of an object. Pythonic or not?

Im wondering if there is an accepted way to pass functions as parameters to objects (i.e. to define methods of that object in the init block).More specifically, how would one do this if the function de…

Encrypt and Decrypt by AES algorithm in both python and android

I have python and android code for AES encryption. When I encrypt a text in android, it decrypt on python successfully but it can’t decrypt in android side. Do anyone have an idea?Python code :impo…

How to conditionally assign values to tensor [masking for loss function]?

I want to create a L2 loss function that ignores values (=> pixels) where the label has the value 0. The tensor batch[1] contains the labels while output is a tensor for the net output, both have a …

Assign Colors to Lines

I am trying to plot a variable number of lines in matplotlib where the X, Y data and colors are stored in numpy arrays, as shown below. Is there a way to pass an array of colors into the plot function,…

How to display multiple annotations in Seaborn Heatmap cells

I want seaborn heatmap to display multiple values in each cell of the heatmap. Here is a manual example of what I want to see, just to be clear:data = np.array([[0.000000,0.000000],[-0.231049,0.000000]…

ImportError: No module named lxml on Mac

I am having a problem running a Python script and it is showing this message:ImportError: No module named lxmlI suppose I have to install somewhat called lxml but I am really newbie to Python and I don…

Pandas Rolling window Spearman correlation

I want to calculate the Spearman and/or Pearson Correlation between two columns of a DataFrame, using a rolling window.I have tried df[corr] = df[col1].rolling(P).corr(df[col2]) (P is the window size)b…

Python string splitlines() removes certain Unicode control characters

I noticed that Pythons standard string method splitlines() actually removes some crucial Unicode control characters as well. Example>>> s1 = uasdf \n fdsa \x1d asdf >>> s1.splitlines(…