Skip to content

Bug in 8.0.0 pytest.warns handling #11906

Closed
@maread99

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'

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