Skip to content

Bug in 8.0.0 pytest.warns handling #11906

Description

@maread99

There seems to be a handling error in 8.0.0, when pytest.warns fails to match the message. Seems that the warning class itself is being called towards the end of the handling...

import pytest
import warnings

assert pytest.__version__ == "8.0.0"

class AWarning(UserWarning):
    
    def __init__(self, a, b):
        pass

a, b = 1, 2
with pytest.warns(AWarning, match="not gonna match"):
    warnings.warn(AWarning(a, b))
---------------------------------------------------------------------------
Failed                                    Traceback (most recent call last)
    [... skipping hidden 1 frame]

File ~\...\market_prices\.venv\lib\site-packages\_pytest\outcomes.py:187, in fail(reason, pytrace, msg)
    186 reason = _resolve_msg_to_reason("fail", reason, msg)
--> 187 raise Failed(msg=reason, pytrace=pytrace)

Failed: DID NOT WARN. No warnings of type (<class '__main__.AWarning'>,) matching the regex were emitted.
 Regex: not gonna match
 Emitted warnings: [AWarning(1, 2)].

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
Cell In[1], line 13
     11 a, b = 1, 2
     12 with pytest.warns(AWarning, match="not gonna match"):
---> 13     warnings.warn(AWarning(a, b))

File ~\...\market_prices\.venv\lib\site-packages\_pytest\recwarn.py:333, in WarningsChecker.__exit__(self, exc_type, exc_val, exc_tb)
    331 for w in self:
    332     if not self.matches(w):
--> 333         warnings.warn_explicit(
    334             str(w.message),
    335             w.message.__class__,  # type: ignore[arg-type]
    336             w.filename,
    337             w.lineno,
    338             module=w.__module__,
    339             source=w.source,
    340         )

TypeError: __init__() missing 1 required positional argument: 'b'

NB: only seems to happen if the Warning class takes more than one argument. For example, if arg b is stripped from all the above then the failure to match is handled as expected.

Also, worked fine in 7.4.4:

import pytest
import warnings

assert pytest.__version__ == "7.4.4"

class AWarning(UserWarning):
    
    def __init__(self, a, b):
        pass

a, b = 1, 2
with pytest.warns(AWarning, match="not gonna match"):
    warnings.warn(AWarning(a, b))
---------------------------------------------------------------------------
Failed                                    Traceback (most recent call last)
Cell In[1], line 13
     11 a, b = 1, 2
     12 with pytest.warns(AWarning, match="not gonna match"):
---> 13     warnings.warn(AWarning(a, b))

    [... skipping hidden 1 frame]

File ~\...\market_prices\.venv\lib\site-packages\_pytest\outcomes.py:198, in fail(reason, pytrace, msg)
    196 __tracebackhide__ = True
    197 reason = _resolve_msg_to_reason("fail", reason, msg)
--> 198 raise Failed(msg=reason, pytrace=pytrace)

Failed: DID NOT WARN. No warnings of type (<class '__main__.AWarning'>,) matching the regex were emitted.
 Regex: not gonna match
 Emitted warnings: [AWarning(1, 2)]

Thanks is advance for looking at this!

OS: 'Windows-10-10.0.22631-SP0'

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions