From 078b112138aef905bc45c2569a48862b3680e4c0 Mon Sep 17 00:00:00 2001
From: jakkdl
Date: Thu, 11 Aug 2022 14:41:17 +0200
Subject: [PATCH 1/7] Squashed commit of the following:
commit 41d339c46763bbe26123e1e6504b6e32290e33e1
Author: Cheukting
Date: Thu Jun 23 17:01:04 2022 +0800
test in all py versions
commit b3572a5a12672228c3276fc8c8e05980dfb7888a
Author: Cheukting
Date: Thu Jun 23 16:41:06 2022 +0800
add test
commit 7166a2a51e4f99046b028b663c193d8b558c7fd4
Author: Cheukting
Date: Thu Jun 23 16:00:07 2022 +0800
update changelog
commit b958c73d489157f0c0d4e46425083a5e2e2bc851
Author: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Thu Jun 23 07:50:52 2022 +0000
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
commit ea7f376c6ca37c40c83df0e4a1cfaaedb34bae91
Author: Cheukting
Date: Thu Jun 23 15:48:21 2022 +0800
Fix MyPy
commit 97469beb1da40257e9a061a5e19548546c9312c4
Author: Cheukting
Date: Thu Jun 23 15:03:48 2022 +0800
fix if ExceptionGroup not exist
commit 84e553642cd69b4d499231d733df91ebfa84c7ad
Author: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Thu Jun 23 03:43:27 2022 +0000
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
commit 76bbef449b88bbd74fb5cca3b5293337a624ef03
Author: Cheukting
Date: Thu Jun 23 11:40:41 2022 +0800
adding changelog
commit db82bebc5a4969e2083adcd97bdfd2a63bb17d98
Author: Cheukting
Date: Thu Jun 23 11:33:10 2022 +0800
fall back to native when handeling to exception groups
---
changelog/9159.bugfix.rst | 1 +
src/_pytest/_code/code.py | 29 +++++++++++++++++++++++++----
testing/code/test_excinfo.py | 31 +++++++++++++++++++++++++++++++
tox.ini | 1 +
4 files changed, 58 insertions(+), 4 deletions(-)
create mode 100644 changelog/9159.bugfix.rst
diff --git a/changelog/9159.bugfix.rst b/changelog/9159.bugfix.rst
new file mode 100644
index 00000000000..5e7f0a3014d
--- /dev/null
+++ b/changelog/9159.bugfix.rst
@@ -0,0 +1 @@
+Showing inner exceptions by forcing native display in ``ExceptionGroups`` even when using display options other than ``--tb=native``. A temporary step before full implementation of pytest-native display for inner exceptions in ``ExceptionGroups``.
diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py
index 304a5cbd751..b1991f1aa31 100644
--- a/src/_pytest/_code/code.py
+++ b/src/_pytest/_code/code.py
@@ -56,6 +56,18 @@
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
+ExceptionGroupTypes: tuple = () # type: ignore
+try:
+ ExceptionGroupTypes += (ExceptionGroup,) # type: ignore
+except NameError:
+ pass # Is missing for `python<3.10`
+try:
+ import exceptiongroup
+
+ ExceptionGroupTypes += (exceptiongroup.ExceptionGroup,)
+except ModuleNotFoundError:
+ pass # No backport is installed
+
class Code:
"""Wrapper around Python code objects."""
@@ -923,11 +935,20 @@ def repr_excinfo(
seen: Set[int] = set()
while e is not None and id(e) not in seen:
seen.add(id(e))
- if excinfo_:
- reprtraceback = self.repr_traceback(excinfo_)
- reprcrash: Optional[ReprFileLocation] = (
- excinfo_._getreprcrash() if self.style != "value" else None
+ if isinstance(e, ExceptionGroupTypes):
+ reprtraceback: Union[
+ ReprTracebackNative, ReprTraceback
+ ] = ReprTracebackNative(
+ traceback.format_exception(
+ type(excinfo.value),
+ excinfo.value,
+ excinfo.traceback[0]._rawentry,
+ )
)
+ reprcrash: Optional[ReprFileLocation] = None
+ elif excinfo_:
+ reprtraceback = self.repr_traceback(excinfo_)
+ reprcrash = excinfo_._getreprcrash() if self.style != "value" else None
else:
# Fallback to native repr if the exception doesn't have a traceback:
# ExceptionInfo objects require a full traceback to work.
diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py
index af72857f3e7..78f777718e9 100644
--- a/testing/code/test_excinfo.py
+++ b/testing/code/test_excinfo.py
@@ -1470,3 +1470,34 @@ def __getattr__(self, attr):
with pytest.raises(RuntimeError) as excinfo:
RecursionDepthError().trigger
assert "maximum recursion" in str(excinfo.getrepr())
+
+
+def test_exceptiongroup(pytester: Pytester) -> None:
+ pytester.makepyfile(
+ """
+ def f(): raise ValueError("From f()")
+ def g(): raise RuntimeError("From g()")
+
+ def main():
+ excs = []
+ for callback in [f, g]:
+ try:
+ callback()
+ except Exception as err:
+ excs.append(err)
+ if excs:
+ raise ExceptionGroup("Oops", excs)
+
+ def test():
+ main()
+ """
+ )
+ result = pytester.runpytest()
+ assert result.ret != 0
+
+ match = [
+ r" | ExceptionGroup: Oops (2 sub-exceptions)",
+ r" | ValueError: From f()",
+ r" | RuntimeError: From g()",
+ ]
+ result.stdout.re_match_lines(match)
diff --git a/tox.ini b/tox.ini
index 93c390ffc57..fd2ff1ba176 100644
--- a/tox.ini
+++ b/tox.ini
@@ -46,6 +46,7 @@ setenv =
extras = testing
deps =
doctesting: PyYAML
+ exceptiongroup: exceptiongroup>=1.0.0
numpy: numpy>=1.19.4
pexpect: pexpect>=4.8.0
pluggymain: pluggy @ git+https://github.com/pytest-dev/pluggy.git
From 163201e56b0236b166b21373590cb3765087dc11 Mon Sep 17 00:00:00 2001
From: jakkdl
Date: Fri, 12 Aug 2022 16:28:46 +0200
Subject: [PATCH 2/7] Typed ExceptionGroupTypes and changed to
BaseExceptionGroup, fixed exceptionchain (excinfo->excinfo_, set reprcrash.
Extended tests, though they're wip.
---
AUTHORS | 1 +
src/_pytest/_code/code.py | 41 +++++++------
testing/code/test_excinfo.py | 110 ++++++++++++++++++++++++++---------
tox.ini | 5 +-
4 files changed, 109 insertions(+), 48 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index e797f21461a..ca2872f32a4 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -168,6 +168,7 @@ Jeff Rackauckas
Jeff Widman
Jenni Rinker
John Eddie Ayson
+John Litborn
John Towler
Jon Parise
Jon Sonesen
diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py
index b1991f1aa31..0c4041e8490 100644
--- a/src/_pytest/_code/code.py
+++ b/src/_pytest/_code/code.py
@@ -56,17 +56,18 @@
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
-ExceptionGroupTypes: tuple = () # type: ignore
-try:
- ExceptionGroupTypes += (ExceptionGroup,) # type: ignore
-except NameError:
- pass # Is missing for `python<3.10`
+ExceptionGroupTypes: Tuple[Type[BaseException], ...] = ()
+
+if sys.version_info >= (3, 11):
+ ExceptionGroupTypes = (BaseExceptionGroup,) # type: ignore # noqa: F821
try:
import exceptiongroup
- ExceptionGroupTypes += (exceptiongroup.ExceptionGroup,)
+ ExceptionGroupTypes += (exceptiongroup.BaseExceptionGroup,)
except ModuleNotFoundError:
- pass # No backport is installed
+ # no backport installed - if <3.11 that means programs can't raise exceptiongroups
+ # so we don't need to handle it
+ pass
class Code:
@@ -935,20 +936,22 @@ def repr_excinfo(
seen: Set[int] = set()
while e is not None and id(e) not in seen:
seen.add(id(e))
- if isinstance(e, ExceptionGroupTypes):
- reprtraceback: Union[
- ReprTracebackNative, ReprTraceback
- ] = ReprTracebackNative(
- traceback.format_exception(
- type(excinfo.value),
- excinfo.value,
- excinfo.traceback[0]._rawentry,
+ if excinfo_:
+ if isinstance(e, tuple(ExceptionGroupTypes)):
+ reprtraceback: Union[
+ ReprTracebackNative, ReprTraceback
+ ] = ReprTracebackNative(
+ traceback.format_exception(
+ type(excinfo_.value),
+ excinfo_.value,
+ excinfo_.traceback[0]._rawentry,
+ )
)
+ else:
+ reprtraceback = self.repr_traceback(excinfo_)
+ reprcrash: Optional[ReprFileLocation] = (
+ excinfo_._getreprcrash() if self.style != "value" else None
)
- reprcrash: Optional[ReprFileLocation] = None
- elif excinfo_:
- reprtraceback = self.repr_traceback(excinfo_)
- reprcrash = excinfo_._getreprcrash() if self.style != "value" else None
else:
# Fallback to native repr if the exception doesn't have a traceback:
# ExceptionInfo objects require a full traceback to work.
diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py
index 78f777718e9..2a032b02105 100644
--- a/testing/code/test_excinfo.py
+++ b/testing/code/test_excinfo.py
@@ -11,6 +11,11 @@
from typing import TYPE_CHECKING
from typing import Union
+try:
+ import exceptiongroup # noqa (referred to in strings)
+except ModuleNotFoundError:
+ pass
+
import _pytest
import pytest
from _pytest._code.code import ExceptionChainRepr
@@ -23,7 +28,6 @@
from _pytest.pytester import LineMatcher
from _pytest.pytester import Pytester
-
if TYPE_CHECKING:
from _pytest._code.code import _TracebackStyle
@@ -1472,32 +1476,84 @@ def __getattr__(self, attr):
assert "maximum recursion" in str(excinfo.getrepr())
-def test_exceptiongroup(pytester: Pytester) -> None:
- pytester.makepyfile(
- """
- def f(): raise ValueError("From f()")
- def g(): raise RuntimeError("From g()")
-
- def main():
- excs = []
- for callback in [f, g]:
- try:
- callback()
- except Exception as err:
- excs.append(err)
- if excs:
- raise ExceptionGroup("Oops", excs)
-
- def test():
- main()
+def _exceptiongroup_common(
+ pytester: Pytester,
+ outer_chain: str,
+ inner_chain: str,
+ native: bool,
+) -> None:
+ pre = "exceptiongroup." if not native else ""
+ pre2 = pre if sys.version_info < (3, 11) else ""
+ filestr = f"""
+ {"import exceptiongroup" if not native else ""}
+ import pytest
+
+ def f(): raise ValueError("From f()")
+ def g(): raise BaseException("From g()")
+
+ def inner(inner_chain):
+ excs = []
+ for callback in [f, g]:
+ try:
+ callback()
+ except BaseException as err:
+ excs.append(err)
+ if excs:
+ if inner_chain == "none":
+ raise {pre}BaseExceptionGroup("Oops", excs)
+ try:
+ raise SyntaxError()
+ except SyntaxError as e:
+ if inner_chain == "from":
+ raise {pre}BaseExceptionGroup("Oops", excs) from e
+ else:
+ raise {pre}BaseExceptionGroup("Oops", excs)
+
+ def outer(outer_chain, inner_chain):
+ try:
+ inner(inner_chain)
+ except {pre2}BaseExceptionGroup as e:
+ if outer_chain == "none":
+ raise
+ if outer_chain == "from":
+ raise IndexError() from e
+ else:
+ raise IndexError()
+
+
+ def test():
+ outer("{outer_chain}", "{inner_chain}")
"""
- )
+ pytester.makepyfile(test_excgroup=filestr)
result = pytester.runpytest()
- assert result.ret != 0
-
- match = [
- r" | ExceptionGroup: Oops (2 sub-exceptions)",
- r" | ValueError: From f()",
- r" | RuntimeError: From g()",
+ match_lines = [
+ rf" \| {pre2}BaseExceptionGroup: Oops \(2 sub-exceptions\)",
+ r" \| ValueError: From f\(\)",
+ r" \| BaseException: From g\(\)",
+ r"=* short test summary info =*",
]
- result.stdout.re_match_lines(match)
+ if outer_chain in ("another", "from"):
+ match_lines.append(r"FAILED test_excgroup.py::test - IndexError")
+ else:
+ match_lines.append(
+ rf"FAILED test_excgroup.py::test - {pre2}BaseExceptionGroup: Oops \(2 su.*"
+ )
+ result.stdout.re_match_lines(match_lines)
+
+
+@pytest.mark.skipif(
+ sys.version_info < (3, 11), reason="Native ExceptionGroup not implemented"
+)
+@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
+@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
+def test_native_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) -> None:
+ _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("inner_chain", ["none", "from", "another"])
+def test_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) -> None:
+ _exceptiongroup_common(pytester, outer_chain, inner_chain, native=False)
diff --git a/tox.ini b/tox.ini
index fd2ff1ba176..a80a7678276 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,8 +9,9 @@ envlist =
py39
py310
py311
+ py311-exceptiongroup
pypy3
- py37-{pexpect,xdist,unittestextras,numpy,pluggymain}
+ py37-{pexpect,xdist,unittestextras,numpy,pluggymain,exceptiongroup}
doctesting
plugins
py37-freeze
@@ -46,7 +47,7 @@ setenv =
extras = testing
deps =
doctesting: PyYAML
- exceptiongroup: exceptiongroup>=1.0.0
+ exceptiongroup: exceptiongroup>=1.0.0rc8
numpy: numpy>=1.19.4
pexpect: pexpect>=4.8.0
pluggymain: pluggy @ git+https://github.com/pytest-dev/pluggy.git
From c16a9cf789be913d994d31891e4071e240563081 Mon Sep 17 00:00:00 2001
From: jakkdl
Date: Sat, 13 Aug 2022 15:25:03 +0200
Subject: [PATCH 3/7] 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
---
.pre-commit-config.yaml | 1 +
src/_pytest/_code/code.py | 23 +++++++++++------------
testing/code/test_excinfo.py | 17 ++++++++---------
tox.ini | 4 ++--
4 files changed, 22 insertions(+), 23 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 694498b0850..cb26b74f593 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -68,6 +68,7 @@ repos:
- packaging
- tomli
- types-pkg_resources
+ - exceptiongroup>=1.0.0rc8
- repo: local
hooks:
- id: rst
diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py
index 0c4041e8490..34bf7bce8e2 100644
--- a/src/_pytest/_code/code.py
+++ b/src/_pytest/_code/code.py
@@ -56,18 +56,14 @@
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
-ExceptionGroupTypes: Tuple[Type[BaseException], ...] = ()
-
-if sys.version_info >= (3, 11):
- ExceptionGroupTypes = (BaseExceptionGroup,) # type: ignore # noqa: F821
+BaseExceptionGroup: Optional[Type[BaseException]]
try:
- import exceptiongroup
-
- ExceptionGroupTypes += (exceptiongroup.BaseExceptionGroup,)
-except ModuleNotFoundError:
- # no backport installed - if <3.11 that means programs can't raise exceptiongroups
- # so we don't need to handle it
- pass
+ BaseExceptionGroup = BaseExceptionGroup # type: ignore
+except NameError:
+ try:
+ from exceptiongroup import BaseExceptionGroup
+ except ModuleNotFoundError:
+ BaseExceptionGroup = None
class Code:
@@ -937,7 +933,10 @@ def repr_excinfo(
while e is not None and id(e) not in seen:
seen.add(id(e))
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[
ReprTracebackNative, ReprTraceback
] = ReprTracebackNative(
diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py
index 2a032b02105..2e5cc03e5a9 100644
--- a/testing/code/test_excinfo.py
+++ b/testing/code/test_excinfo.py
@@ -11,11 +11,6 @@
from typing import TYPE_CHECKING
from typing import Union
-try:
- import exceptiongroup # noqa (referred to in strings)
-except ModuleNotFoundError:
- pass
-
import _pytest
import pytest
from _pytest._code.code import ExceptionChainRepr
@@ -28,6 +23,7 @@
from _pytest.pytester import LineMatcher
from _pytest.pytester import Pytester
+
if TYPE_CHECKING:
from _pytest._code.code import _TracebackStyle
@@ -1526,7 +1522,12 @@ def test():
"""
pytester.makepyfile(test_excgroup=filestr)
result = pytester.runpytest()
- match_lines = [
+ match_lines = []
+ if inner_chain in ("another", "from"):
+ match_lines.append(r"SyntaxError: ")
+
+ match_lines += [
+ r" + Exception Group Traceback (most recent call last):",
rf" \| {pre2}BaseExceptionGroup: Oops \(2 sub-exceptions\)",
r" \| ValueError: From f\(\)",
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)
-@pytest.mark.skipif(
- "exceptiongroup" not in sys.modules, reason="exceptiongroup not installed"
-)
@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
def test_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) -> None:
+ pytest.importorskip("exceptiongroup")
_exceptiongroup_common(pytester, outer_chain, inner_chain, native=False)
diff --git a/tox.ini b/tox.ini
index a80a7678276..9a30bbc3a55 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,9 +9,9 @@ envlist =
py39
py310
py311
- py311-exceptiongroup
pypy3
- py37-{pexpect,xdist,unittestextras,numpy,pluggymain,exceptiongroup}
+ py37-{pexpect,xdist,unittestextras,numpy,pluggymain}
+ py311-exceptiongroup
doctesting
plugins
py37-freeze
From dd7b5ea6c59dec9a170bb00dda681db1bc4d30a4 Mon Sep 17 00:00:00 2001
From: jakkdl
Date: Tue, 16 Aug 2022 09:45:50 +0200
Subject: [PATCH 4/7] added py311-exceptiongroup to github CI, exceptiongroup
is now a hard dependency on py<3.11, renamed bad variable names
---
.github/workflows/test.yml | 5 +++++
.pre-commit-config.yaml | 1 +
setup.cfg | 1 +
src/_pytest/_code/code.py | 9 +++------
testing/code/test_excinfo.py | 17 +++++++++--------
5 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 0c5fda16e4a..1b77249e898 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -46,6 +46,7 @@ jobs:
"ubuntu-py39",
"ubuntu-py310",
"ubuntu-py311",
+ "ubuntu-py311-exceptiongroup",
"ubuntu-pypy3",
"macos-py37",
@@ -114,6 +115,10 @@ jobs:
python: "3.11-dev"
os: ubuntu-latest
tox_env: "py311"
+ - name: "ubuntu-py311-exceptiongroup"
+ python: "3.11-dev"
+ os: ubuntu-latest
+ tox_env: "py311-exceptiongroup"
- name: "ubuntu-pypy3"
python: "pypy-3.7"
os: ubuntu-latest
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index cb26b74f593..68d1e3cc05d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -68,6 +68,7 @@ repos:
- packaging
- tomli
- types-pkg_resources
+ # for python>=3.11
- exceptiongroup>=1.0.0rc8
- repo: local
hooks:
diff --git a/setup.cfg b/setup.cfg
index 3545a9503a8..38f50556c93 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -47,6 +47,7 @@ install_requires =
pluggy>=0.12,<2.0
py>=1.8.2
colorama;sys_platform=="win32"
+ exceptiongroup>=1.0.0rc8;python_version<"3.11"
importlib-metadata>=0.12;python_version<"3.8"
tomli>=1.0.0;python_version<"3.11"
python_requires = >=3.7
diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py
index 34bf7bce8e2..bd7fac63497 100644
--- a/src/_pytest/_code/code.py
+++ b/src/_pytest/_code/code.py
@@ -56,14 +56,11 @@
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
-BaseExceptionGroup: Optional[Type[BaseException]]
+BaseExceptionGroup: Type[BaseException]
try:
BaseExceptionGroup = BaseExceptionGroup # type: ignore
except NameError:
- try:
- from exceptiongroup import BaseExceptionGroup
- except ModuleNotFoundError:
- BaseExceptionGroup = None
+ from exceptiongroup import BaseExceptionGroup
class Code:
@@ -936,7 +933,7 @@ def repr_excinfo(
# 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):
+ if isinstance(e, BaseExceptionGroup):
reprtraceback: Union[
ReprTracebackNative, ReprTraceback
] = ReprTracebackNative(
diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py
index 2e5cc03e5a9..e428b9c5ca9 100644
--- a/testing/code/test_excinfo.py
+++ b/testing/code/test_excinfo.py
@@ -1478,8 +1478,8 @@ def _exceptiongroup_common(
inner_chain: str,
native: bool,
) -> None:
- pre = "exceptiongroup." if not native else ""
- pre2 = pre if sys.version_info < (3, 11) else ""
+ pre_raise = "exceptiongroup." if not native else ""
+ pre_catch = pre_raise if sys.version_info < (3, 11) else ""
filestr = f"""
{"import exceptiongroup" if not native else ""}
import pytest
@@ -1496,19 +1496,19 @@ def inner(inner_chain):
excs.append(err)
if excs:
if inner_chain == "none":
- raise {pre}BaseExceptionGroup("Oops", excs)
+ raise {pre_raise}BaseExceptionGroup("Oops", excs)
try:
raise SyntaxError()
except SyntaxError as e:
if inner_chain == "from":
- raise {pre}BaseExceptionGroup("Oops", excs) from e
+ raise {pre_raise}BaseExceptionGroup("Oops", excs) from e
else:
- raise {pre}BaseExceptionGroup("Oops", excs)
+ raise {pre_raise}BaseExceptionGroup("Oops", excs)
def outer(outer_chain, inner_chain):
try:
inner(inner_chain)
- except {pre2}BaseExceptionGroup as e:
+ except {pre_catch}BaseExceptionGroup as e:
if outer_chain == "none":
raise
if outer_chain == "from":
@@ -1528,7 +1528,7 @@ def test():
match_lines += [
r" + Exception Group Traceback (most recent call last):",
- rf" \| {pre2}BaseExceptionGroup: Oops \(2 sub-exceptions\)",
+ rf" \| {pre_catch}BaseExceptionGroup: Oops \(2 sub-exceptions\)",
r" \| ValueError: From f\(\)",
r" \| BaseException: From g\(\)",
r"=* short test summary info =*",
@@ -1537,7 +1537,7 @@ def test():
match_lines.append(r"FAILED test_excgroup.py::test - IndexError")
else:
match_lines.append(
- rf"FAILED test_excgroup.py::test - {pre2}BaseExceptionGroup: Oops \(2 su.*"
+ rf"FAILED test_excgroup.py::test - {pre_catch}BaseExceptionGroup: Oops \(2.*"
)
result.stdout.re_match_lines(match_lines)
@@ -1554,5 +1554,6 @@ def test_native_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) ->
@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
def test_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) -> None:
+ # with py>=3.11 does not depend on exceptiongroup, though there is a toxenv for it
pytest.importorskip("exceptiongroup")
_exceptiongroup_common(pytester, outer_chain, inner_chain, native=False)
From b457013e974733f794f160c22ba9b3806a3db471 Mon Sep 17 00:00:00 2001
From: jakkdl
Date: Tue, 16 Aug 2022 09:57:01 +0200
Subject: [PATCH 5/7] added use_coverage to ubuntu-py311
---
.github/workflows/test.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 1b77249e898..0dad2f9820f 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -115,6 +115,7 @@ jobs:
python: "3.11-dev"
os: ubuntu-latest
tox_env: "py311"
+ use_coverage: true
- name: "ubuntu-py311-exceptiongroup"
python: "3.11-dev"
os: ubuntu-latest
From 1a6a158036f2c92b8050a26cd42bc96b5c77bdab Mon Sep 17 00:00:00 2001
From: jakkdl
Date: Tue, 16 Aug 2022 16:05:55 +0200
Subject: [PATCH 6/7] import BaseExceptionGroup with explicit version check
instead of try/catch
---
src/_pytest/_code/code.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py
index bd7fac63497..97985def1c3 100644
--- a/src/_pytest/_code/code.py
+++ b/src/_pytest/_code/code.py
@@ -56,10 +56,7 @@
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
-BaseExceptionGroup: Type[BaseException]
-try:
- BaseExceptionGroup = BaseExceptionGroup # type: ignore
-except NameError:
+if sys.version_info[:2] < (3, 11):
from exceptiongroup import BaseExceptionGroup
From 05ceee7fc914416805f745ab1523969ea6fc9b8a Mon Sep 17 00:00:00 2001
From: jakkdl
Date: Wed, 17 Aug 2022 11:22:08 +0200
Subject: [PATCH 7/7] removed from CI, added comments to tox and pre-commit
---
.github/workflows/test.yml | 5 -----
.pre-commit-config.yaml | 3 ++-
tox.ini | 5 ++++-
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 0dad2f9820f..33b32a1abaa 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -46,7 +46,6 @@ jobs:
"ubuntu-py39",
"ubuntu-py310",
"ubuntu-py311",
- "ubuntu-py311-exceptiongroup",
"ubuntu-pypy3",
"macos-py37",
@@ -116,10 +115,6 @@ jobs:
os: ubuntu-latest
tox_env: "py311"
use_coverage: true
- - name: "ubuntu-py311-exceptiongroup"
- python: "3.11-dev"
- os: ubuntu-latest
- tox_env: "py311-exceptiongroup"
- name: "ubuntu-pypy3"
python: "pypy-3.7"
os: ubuntu-latest
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 68d1e3cc05d..72e1d8d62b1 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -68,7 +68,8 @@ repos:
- packaging
- tomli
- types-pkg_resources
- # for python>=3.11
+ # for mypy running on python>=3.11 since exceptiongroup is only a dependency
+ # on <3.11
- exceptiongroup>=1.0.0rc8
- repo: local
hooks:
diff --git a/tox.ini b/tox.ini
index 9a30bbc3a55..f1ab4b815a5 100644
--- a/tox.ini
+++ b/tox.ini
@@ -11,13 +11,16 @@ envlist =
py311
pypy3
py37-{pexpect,xdist,unittestextras,numpy,pluggymain}
- py311-exceptiongroup
doctesting
plugins
py37-freeze
docs
docs-checklinks
+ # checks that 3.11 native ExceptionGroup works with exceptiongroup
+ # not included in CI.
+ py311-exceptiongroup
+
[testenv]