Skip to content

Commit

Permalink
Merge pull request #10660 from ikonst/2023-01-13-raises-typing
Browse files Browse the repository at this point in the history
Derive pytest.raises from AbstractContextManager
  • Loading branch information
RonnyPfannschmidt committed Jan 18, 2023
2 parents 61cfaac + 1a96f16 commit 096b942
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 2 deletions.
2 changes: 2 additions & 0 deletions changelog/10660.bugfix.rst
@@ -0,0 +1,2 @@
Fix :py:func:`pytest.raises` to return a 'ContextManager' so that type-checkers could narrow
:code:`pytest.raises(...) if ... else nullcontext()` down to 'ContextManager' rather than 'object'.
4 changes: 2 additions & 2 deletions src/_pytest/python_api.py
Expand Up @@ -8,7 +8,7 @@
from typing import Any
from typing import Callable
from typing import cast
from typing import Generic
from typing import ContextManager
from typing import List
from typing import Mapping
from typing import Optional
Expand Down Expand Up @@ -957,7 +957,7 @@ def raises( # noqa: F811


@final
class RaisesContext(Generic[E]):
class RaisesContext(ContextManager[_pytest._code.ExceptionInfo[E]]):
def __init__(
self,
expected_exception: Union[Type[E], Tuple[Type[E], ...]],
Expand Down
11 changes: 11 additions & 0 deletions testing/typing_checks.py
Expand Up @@ -3,6 +3,11 @@
This file is not executed, it is only checked by mypy to ensure that
none of the code triggers any mypy errors.
"""
import contextlib
from typing import Optional

from typing_extensions import assert_type

import pytest


Expand All @@ -22,3 +27,9 @@ def check_fixture_ids_callable() -> None:
@pytest.mark.parametrize("func", [str, int], ids=lambda x: str(x.__name__))
def check_parametrize_ids_callable(func) -> None:
pass


def check_raises_is_a_context_manager(val: bool) -> None:
with pytest.raises(RuntimeError) if val else contextlib.nullcontext() as excinfo:
pass
assert_type(excinfo, Optional[pytest.ExceptionInfo[RuntimeError]])

0 comments on commit 096b942

Please sign in to comment.