added exceptiongroup to pre-commit-config, moved away from tuple to directly defining BaseExceptionGroup, added block comment, added match line for inner exception, changked mark.skipif to importorskip to not need top-level import, changed tox.ini a bit - only uncovered should now be py37 without exceptiongroup, due to hypothesis
This commit is contained in:
parent
163201e56b
commit
c16a9cf789
|
@ -68,6 +68,7 @@ repos:
|
||||||
- packaging
|
- packaging
|
||||||
- tomli
|
- tomli
|
||||||
- types-pkg_resources
|
- types-pkg_resources
|
||||||
|
- exceptiongroup>=1.0.0rc8
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
- id: rst
|
- id: rst
|
||||||
|
|
|
@ -56,18 +56,14 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
|
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
|
||||||
|
|
||||||
ExceptionGroupTypes: Tuple[Type[BaseException], ...] = ()
|
BaseExceptionGroup: Optional[Type[BaseException]]
|
||||||
|
|
||||||
if sys.version_info >= (3, 11):
|
|
||||||
ExceptionGroupTypes = (BaseExceptionGroup,) # type: ignore # noqa: F821
|
|
||||||
try:
|
try:
|
||||||
import exceptiongroup
|
BaseExceptionGroup = BaseExceptionGroup # type: ignore
|
||||||
|
except NameError:
|
||||||
ExceptionGroupTypes += (exceptiongroup.BaseExceptionGroup,)
|
try:
|
||||||
|
from exceptiongroup import BaseExceptionGroup
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
# no backport installed - if <3.11 that means programs can't raise exceptiongroups
|
BaseExceptionGroup = None
|
||||||
# so we don't need to handle it
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Code:
|
class Code:
|
||||||
|
@ -937,7 +933,10 @@ class FormattedExcinfo:
|
||||||
while e is not None and id(e) not in seen:
|
while e is not None and id(e) not in seen:
|
||||||
seen.add(id(e))
|
seen.add(id(e))
|
||||||
if excinfo_:
|
if excinfo_:
|
||||||
if isinstance(e, tuple(ExceptionGroupTypes)):
|
# Fall back to native traceback as a temporary workaround until
|
||||||
|
# full support for exception groups added to ExceptionInfo.
|
||||||
|
# See https://github.com/pytest-dev/pytest/issues/9159
|
||||||
|
if BaseExceptionGroup is not None and isinstance(e, BaseExceptionGroup):
|
||||||
reprtraceback: Union[
|
reprtraceback: Union[
|
||||||
ReprTracebackNative, ReprTraceback
|
ReprTracebackNative, ReprTraceback
|
||||||
] = ReprTracebackNative(
|
] = ReprTracebackNative(
|
||||||
|
|
|
@ -11,11 +11,6 @@ from typing import Tuple
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
try:
|
|
||||||
import exceptiongroup # noqa (referred to in strings)
|
|
||||||
except ModuleNotFoundError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
import _pytest
|
import _pytest
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest._code.code import ExceptionChainRepr
|
from _pytest._code.code import ExceptionChainRepr
|
||||||
|
@ -28,6 +23,7 @@ from _pytest.pathlib import import_path
|
||||||
from _pytest.pytester import LineMatcher
|
from _pytest.pytester import LineMatcher
|
||||||
from _pytest.pytester import Pytester
|
from _pytest.pytester import Pytester
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from _pytest._code.code import _TracebackStyle
|
from _pytest._code.code import _TracebackStyle
|
||||||
|
|
||||||
|
@ -1526,7 +1522,12 @@ def _exceptiongroup_common(
|
||||||
"""
|
"""
|
||||||
pytester.makepyfile(test_excgroup=filestr)
|
pytester.makepyfile(test_excgroup=filestr)
|
||||||
result = pytester.runpytest()
|
result = pytester.runpytest()
|
||||||
match_lines = [
|
match_lines = []
|
||||||
|
if inner_chain in ("another", "from"):
|
||||||
|
match_lines.append(r"SyntaxError: <no detail available>")
|
||||||
|
|
||||||
|
match_lines += [
|
||||||
|
r" + Exception Group Traceback (most recent call last):",
|
||||||
rf" \| {pre2}BaseExceptionGroup: Oops \(2 sub-exceptions\)",
|
rf" \| {pre2}BaseExceptionGroup: Oops \(2 sub-exceptions\)",
|
||||||
r" \| ValueError: From f\(\)",
|
r" \| ValueError: From f\(\)",
|
||||||
r" \| BaseException: From g\(\)",
|
r" \| BaseException: From g\(\)",
|
||||||
|
@ -1550,10 +1551,8 @@ def test_native_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) ->
|
||||||
_exceptiongroup_common(pytester, outer_chain, inner_chain, native=True)
|
_exceptiongroup_common(pytester, outer_chain, inner_chain, native=True)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
|
||||||
"exceptiongroup" not in sys.modules, reason="exceptiongroup not installed"
|
|
||||||
)
|
|
||||||
@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
|
@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
|
||||||
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
|
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
|
||||||
def test_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) -> None:
|
def test_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) -> None:
|
||||||
|
pytest.importorskip("exceptiongroup")
|
||||||
_exceptiongroup_common(pytester, outer_chain, inner_chain, native=False)
|
_exceptiongroup_common(pytester, outer_chain, inner_chain, native=False)
|
||||||
|
|
4
tox.ini
4
tox.ini
|
@ -9,9 +9,9 @@ envlist =
|
||||||
py39
|
py39
|
||||||
py310
|
py310
|
||||||
py311
|
py311
|
||||||
py311-exceptiongroup
|
|
||||||
pypy3
|
pypy3
|
||||||
py37-{pexpect,xdist,unittestextras,numpy,pluggymain,exceptiongroup}
|
py37-{pexpect,xdist,unittestextras,numpy,pluggymain}
|
||||||
|
py311-exceptiongroup
|
||||||
doctesting
|
doctesting
|
||||||
plugins
|
plugins
|
||||||
py37-freeze
|
py37-freeze
|
||||||
|
|
Loading…
Reference in New Issue