##// END OF EJS Templates
Refuse to install event loop hooks when not using `prompt_toolkit` (#14132)...
Refuse to install event loop hooks when not using `prompt_toolkit` (#14132) Without this, `%gui` is effectively a no-op but the user thinks it works. For example. If running `ipython`: ``` In [1]: import matplotlib; matplotlib.use('QtAgg'); from matplotlib import pyplot; pyplot.ion(); pyplot.plot([1, 2, 3, 4]) Installed qt6 event loop hook. Out[1]: [<matplotlib.lines.Line2D at 0x1ba2f59d2a0>] ``` The window appears and responds as expected. If running `ipython --simple-prompt`, the user would see the same output, when in fact no event loop hook was installed since it's not supported without `prompt_toolkit`. The resulting Qt window is unresponsive because the event loop is not running, i.e. with `--simple-prompt`, Qt windows should block (but `pyplot` doesn't/can't know to do that) With this PR, the user will see: ``` In [1]: import matplotlib; matplotlib.use('QtAgg'); from matplotlib import pyplot; pyplot.ion(); pyplot.plot([1, 2, 3, 4]) Cannot install event loop hook for "qt" when running with `--simple-prompt`. NOTE: Tk is supported natively; use Tk apps and Tk backends with `--simple-prompt`. Out[1]: [<matplotlib.lines.Line2D at 0x170be0c0310>] ``` They'll still get an unresponsive Qt window, but they'll at least be told this can't work (while anything using Tk will work just fine).

File last commit:

r28335:2cee9a97
r28368:22fc5ab5 merge
Show More
test_exceptiongroup_tb.py
112 lines | 3.5 KiB | text/x-python | PythonLexer
/ IPython / core / tests / test_exceptiongroup_tb.py
jakkdl
add tests, fix exceptiongroup dependency, add doc requirement in another place
r28333 import unittest
import re
from IPython.utils.capture import capture_output
import sys
import pytest
from tempfile import TemporaryDirectory
from IPython.testing import tools as tt
jakkdl
fix formatting
r28335
jakkdl
add tests, fix exceptiongroup dependency, add doc requirement in another place
r28333 def _exceptiongroup_common(
outer_chain: str,
inner_chain: str,
native: bool,
) -> None:
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
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_raise}BaseExceptionGroup("Oops", excs)
try:
raise SyntaxError()
except SyntaxError as e:
if inner_chain == "from":
raise {pre_raise}BaseExceptionGroup("Oops", excs) from e
else:
raise {pre_raise}BaseExceptionGroup("Oops", excs)
def outer(outer_chain, inner_chain):
try:
inner(inner_chain)
except {pre_catch}BaseExceptionGroup as e:
if outer_chain == "none":
raise
if outer_chain == "from":
raise IndexError() from e
else:
raise IndexError
outer("{outer_chain}", "{inner_chain}")
"""
with capture_output() as cap:
ip.run_cell(filestr)
match_lines = []
if inner_chain == "another":
match_lines += [
"During handling of the above exception, another exception occurred:",
]
jakkdl
fix formatting
r28335 elif inner_chain == "from":
jakkdl
add tests, fix exceptiongroup dependency, add doc requirement in another place
r28333 match_lines += [
"The above exception was the direct cause of the following exception:",
]
match_lines += [
" + Exception Group Traceback (most recent call last):",
f" | {pre_catch}BaseExceptionGroup: Oops (2 sub-exceptions)",
" | ValueError: From f()",
" | BaseException: From g()",
]
if outer_chain == "another":
match_lines += [
"During handling of the above exception, another exception occurred:",
"IndexError",
]
elif outer_chain == "from":
match_lines += [
"The above exception was the direct cause of the following exception:",
"IndexError",
]
error_lines = cap.stderr.split("\n")
err_index = match_index = 0
for expected in match_lines:
jakkdl
fix formatting
r28335 for i, actual in enumerate(error_lines):
jakkdl
add tests, fix exceptiongroup dependency, add doc requirement in another place
r28333 if actual == expected:
jakkdl
fix formatting
r28335 error_lines = error_lines[i + 1 :]
jakkdl
add tests, fix exceptiongroup dependency, add doc requirement in another place
r28333 break
else:
jakkdl
fix formatting
r28335 assert False, f"{expected} not found in cap.stderr"
jakkdl
add tests, fix exceptiongroup dependency, add doc requirement in another place
r28333
@pytest.mark.skipif(
jakkdl
fix formatting
r28335 sys.version_info < (3, 11), reason="Native ExceptionGroup not implemented"
)
jakkdl
add tests, fix exceptiongroup dependency, add doc requirement in another place
r28333 @pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
def test_native_exceptiongroup(outer_chain, inner_chain) -> None:
_exceptiongroup_common(outer_chain, inner_chain, native=True)
jakkdl
fix formatting
r28335
jakkdl
add tests, fix exceptiongroup dependency, add doc requirement in another place
r28333 @pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
def test_native_exceptiongroup(outer_chain, inner_chain) -> None:
pytest.importorskip("exceptiongroup")
_exceptiongroup_common(outer_chain, inner_chain, native=False)