##// 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:

r27747:f5d4e0ac
r28368:22fc5ab5 merge
Show More
contexts.py
61 lines | 1.6 KiB | text/x-python | PythonLexer
# encoding: utf-8
"""Miscellaneous context managers.
"""
import warnings
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
class preserve_keys(object):
"""Preserve a set of keys in a dictionary.
Upon entering the context manager the current values of the keys
will be saved. Upon exiting, the dictionary will be updated to
restore the original value of the preserved keys. Preserved keys
which did not exist when entering the context manager will be
deleted.
Examples
--------
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> with preserve_keys(d, 'b', 'c', 'd'):
... del d['a']
... del d['b'] # will be reset to 2
... d['c'] = None # will be reset to 3
... d['d'] = 4 # will be deleted
... d['e'] = 5
... print(sorted(d.items()))
...
[('c', None), ('d', 4), ('e', 5)]
>>> print(sorted(d.items()))
[('b', 2), ('c', 3), ('e', 5)]
"""
def __init__(self, dictionary, *keys):
self.dictionary = dictionary
self.keys = keys
def __enter__(self):
# Actions to perform upon exiting.
to_delete = []
to_update = {}
d = self.dictionary
for k in self.keys:
if k in d:
to_update[k] = d[k]
else:
to_delete.append(k)
self.to_delete = to_delete
self.to_update = to_update
def __exit__(self, *exc_info):
d = self.dictionary
for k in self.to_delete:
d.pop(k, None)
d.update(self.to_update)