Skip to content

Commit

Permalink
Merge pull request #2702 from jakkdl/ipython_exceptiongroup_support
Browse files Browse the repository at this point in the history
Remove special handling due to IPython lacking support for exception groups
  • Loading branch information
Zac-HD committed Sep 5, 2023
2 parents 4ea1e6d + 51db601 commit bf204c4
Show file tree
Hide file tree
Showing 7 changed files with 5 additions and 198 deletions.
1 change: 1 addition & 0 deletions newsfragments/2702.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Removed special ``MultiError`` traceback handling for IPython. As of `version 8.15 <https://ipython.readthedocs.io/en/stable/whatsnew/version8.html#ipython-8-15>`_ `ExceptionGroup` is handled natively.
1 change: 0 additions & 1 deletion test-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ pytest >= 5.0 # for faulthandler in core
coverage >= 7.2.5
async_generator >= 1.9
pyright
ipython # for the IPython traceback integration tests
pyOpenSSL >= 22.0.0 # for the ssl + DTLS tests
trustme # for the ssl + DTLS tests
pylint # for pylint finding all symbols tests
Expand Down
39 changes: 1 addition & 38 deletions test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,12 @@ astor==0.8.1
# via -r test-requirements.in
astroid==2.15.6
# via pylint
asttokens==2.2.1
# via stack-data
async-generator==1.10
# via -r test-requirements.in
attrs==23.1.0
# via
# -r test-requirements.in
# outcome
backcall==0.2.0
# via ipython
black==23.7.0 ; implementation_name == "cpython"
# via -r test-requirements.in
build==0.10.0
Expand All @@ -38,16 +34,12 @@ cryptography==41.0.3
# pyopenssl
# trustme
# types-pyopenssl
decorator==5.1.1
# via ipython
dill==0.3.7
# via pylint
exceptiongroup==1.1.3 ; python_version < "3.11"
# via
# -r test-requirements.in
# pytest
executing==1.2.0
# via stack-data
flake8==6.1.0
# via
# -r test-requirements.in
Expand All @@ -60,18 +52,12 @@ idna==3.4
# trustme
iniconfig==2.0.0
# via pytest
ipython==8.12.2
# via -r test-requirements.in
isort==5.12.0
# via pylint
jedi==0.19.0
# via
# -r test-requirements.in
# ipython
# via -r test-requirements.in
lazy-object-proxy==1.9.0
# via astroid
matplotlib-inline==0.1.6
# via ipython
mccabe==0.7.0
# via
# flake8
Expand All @@ -96,10 +82,6 @@ parso==0.8.3
# via jedi
pathspec==0.11.2
# via black
pexpect==4.8.0
# via ipython
pickleshare==0.7.5
# via ipython
pip-tools==7.3.0
# via -r test-requirements.in
platformdirs==3.10.0
Expand All @@ -108,20 +90,12 @@ platformdirs==3.10.0
# pylint
pluggy==1.3.0
# via pytest
prompt-toolkit==3.0.39
# via ipython
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.2
# via stack-data
pycodestyle==2.11.0
# via flake8
pycparser==2.21
# via cffi
pyflakes==3.1.0
# via flake8
pygments==2.16.1
# via ipython
pylint==2.17.5
# via -r test-requirements.in
pyopenssl==23.2.0
Expand All @@ -132,14 +106,10 @@ pyright==1.1.325
# via -r test-requirements.in
pytest==7.4.0
# via -r test-requirements.in
six==1.16.0
# via asttokens
sniffio==1.3.0
# via -r test-requirements.in
sortedcontainers==2.4.0
# via -r test-requirements.in
stack-data==0.6.2
# via ipython
tomli==2.0.1
# via
# black
Expand All @@ -152,10 +122,6 @@ tomli==2.0.1
# pytest
tomlkit==0.12.1
# via pylint
traitlets==5.9.0
# via
# ipython
# matplotlib-inline
trustme==1.1.0
# via -r test-requirements.in
types-pyopenssl==23.2.0.2 ; implementation_name == "cpython"
Expand All @@ -165,11 +131,8 @@ typing-extensions==4.7.1
# -r test-requirements.in
# astroid
# black
# ipython
# mypy
# pylint
wcwidth==0.2.6
# via prompt-toolkit
wheel==0.41.2
# via pip-tools
wrapt==1.15.0
Expand Down
36 changes: 1 addition & 35 deletions trio/_core/_multierror.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import sys
import warnings
from collections.abc import Callable, Sequence
from types import TracebackType
from typing import TYPE_CHECKING, Any, cast, overload
Expand All @@ -11,9 +10,7 @@
from trio._deprecate import warn_deprecated

if sys.version_info < (3, 11):
from exceptiongroup import BaseExceptionGroup, ExceptionGroup, print_exception
else:
from traceback import print_exception
from exceptiongroup import BaseExceptionGroup, ExceptionGroup

if TYPE_CHECKING:
from typing_extensions import Self
Expand Down Expand Up @@ -461,37 +458,6 @@ def concat_tb(
return current_head


# Remove when IPython gains support for exception groups
# (https://github.com/ipython/ipython/issues/13753)
if "IPython" in sys.modules:
import IPython

ip = IPython.get_ipython()
if ip is not None:
if ip.custom_exceptions != ():
warnings.warn(
"IPython detected, but you already have a custom exception "
"handler installed. I'll skip installing Trio's custom "
"handler, but this means exception groups will not show full "
"tracebacks.",
category=RuntimeWarning,
)
else:

def trio_show_traceback(
self: IPython.core.interactiveshell.InteractiveShell,
etype: type[BaseException],
value: BaseException,
tb: TracebackType,
tb_offset: int | None = None,
) -> None:
# XX it would be better to integrate with IPython's fancy
# exception formatting stuff (and not ignore tb_offset)
print_exception(value)

ip.set_custom_exc((BaseExceptionGroup,), trio_show_traceback)


# Ubuntu's system Python has a sitecustomize.py file that import
# apport_python_hook and replaces sys.excepthook.
#
Expand Down
84 changes: 2 additions & 82 deletions trio/_core/_tests/test_multierror.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ def test_non_base_multierror():
assert isinstance(exc, ExceptionGroup)


def run_script(name, use_ipython=False):
def run_script(name: str) -> subprocess.CompletedProcess[bytes]:
import trio

trio_path = Path(trio.__file__).parent.parent
Expand All @@ -447,24 +447,7 @@ def run_script(name, use_ipython=False):
env["PYTHONPATH"] = os.pathsep.join(pp)
print("subprocess PYTHONPATH:", env.get("PYTHONPATH"))

if use_ipython:
lines = [
"import runpy",
f"runpy.run_path(r'{script_path}', run_name='trio.fake')",
"exit()",
]

cmd = [
sys.executable,
"-u",
"-m",
"IPython",
# no startup files
"--quick",
"--TerminalIPythonApp.code_to_run=" + "\n".join(lines),
]
else:
cmd = [sys.executable, "-u", str(script_path)]
cmd = [sys.executable, "-u", str(script_path)]
print("running:", cmd)
completed = subprocess.run(
cmd, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
Expand All @@ -474,69 +457,6 @@ def run_script(name, use_ipython=False):
return completed


def check_simple_excepthook(completed):
assert_match_in_seq(
[
"in <module>",
"MultiError",
"--- 1 ---",
"in exc1_fn",
"ValueError",
"--- 2 ---",
"in exc2_fn",
"KeyError",
],
completed.stdout.decode("utf-8"),
)


try:
import IPython # noqa: F401
except ImportError: # pragma: no cover
have_ipython = False
else:
have_ipython = True

need_ipython = pytest.mark.skipif(not have_ipython, reason="need IPython")


@slow
@need_ipython
def test_ipython_exc_handler():
completed = run_script("simple_excepthook.py", use_ipython=True)
check_simple_excepthook(completed)


@slow
@need_ipython
def test_ipython_imported_but_unused():
completed = run_script("simple_excepthook_IPython.py")
check_simple_excepthook(completed)


@slow
@need_ipython
def test_ipython_custom_exc_handler():
# Check we get a nice warning (but only one!) if the user is using IPython
# and already has some other set_custom_exc handler installed.
completed = run_script("ipython_custom_exc.py", use_ipython=True)
assert_match_in_seq(
[
# The warning
"RuntimeWarning",
"IPython detected",
"skip installing Trio",
# The MultiError
"MultiError",
"ValueError",
"KeyError",
],
completed.stdout.decode("utf-8"),
)
# Make sure our other warning doesn't show up
assert "custom sys.excepthook" not in completed.stdout.decode("utf-8")


@slow
@pytest.mark.skipif(
not Path("/usr/lib/python3/dist-packages/apport_python_hook.py").exists(),
Expand Down
36 changes: 0 additions & 36 deletions trio/_core/_tests/test_multierror_scripts/ipython_custom_exc.py

This file was deleted.

This file was deleted.

0 comments on commit bf204c4

Please sign in to comment.