##// END OF EJS Templates
Fix use of pyside6 >= 6.7.0 (#14510)...
Fix use of pyside6 >= 6.7.0 (#14510) Fixes #14463. Using `pyside6 >= 6.7.0` as the `qt6` gui loop gives the following error: ``` In [1]: %gui qt6 In [2]: Traceback (most recent call last): File "/Users/iant/micromamba/envs/temp/bin/ipython", line 8, in <module> sys.exit(start_ipython()) ^^^^^^^^^^^^^^^ File "/Users/iant/github/ipython/IPython/__init__.py", line 130, in start_ipython return launch_new_instance(argv=argv, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/iant/micromamba/envs/temp/lib/python3.12/site-packages/traitlets/config/application.py", line 1075, in launch_instance app.start() File "/Users/iant/github/ipython/IPython/terminal/ipapp.py", line 317, in start self.shell.mainloop() File "/Users/iant/github/ipython/IPython/terminal/interactiveshell.py", line 917, in mainloop self.interact() File "/Users/iant/github/ipython/IPython/terminal/interactiveshell.py", line 902, in interact code = self.prompt_for_code() ^^^^^^^^^^^^^^^^^^^^^^ File "/Users/iant/github/ipython/IPython/terminal/interactiveshell.py", line 845, in prompt_for_code text = self.pt_app.prompt( ^^^^^^^^^^^^^^^^^^^ File "/Users/iant/micromamba/envs/temp/lib/python3.12/site-packages/prompt_toolkit/shortcuts/prompt.py", line 1035, in prompt return self.app.run( ^^^^^^^^^^^^^ File "/Users/iant/micromamba/envs/temp/lib/python3.12/site-packages/prompt_toolkit/application/application.py", line 978, in run result = loop.run_until_complete(coro) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/iant/micromamba/envs/temp/lib/python3.12/asyncio/base_events.py", line 674, in run_until_complete self.run_forever() File "/Users/iant/micromamba/envs/temp/lib/python3.12/asyncio/base_events.py", line 641, in run_forever self._run_once() File "/Users/iant/micromamba/envs/temp/lib/python3.12/asyncio/base_events.py", line 1948, in _run_once event_list = self._selector.select(timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/iant/micromamba/envs/temp/lib/python3.12/site-packages/prompt_toolkit/eventloop/inputhook.py", line 150, in select self.inputhook(InputHookContext(self._r, input_is_ready)) File "/Users/iant/github/ipython/IPython/terminal/pt_inputhooks/qt.py", line 50, in inputhook _appref = app = QtGui.QApplication([" "]) ^^^^^^^^^^^^^^^^^^ AttributeError: module 'PySide6.QtPrintSupport' has no attribute 'QApplication' If you suspect this is an IPython 8.28.0.dev bug, please report it at: https://github.com/ipython/ipython/issues or send an email to the mailing list at ipython-dev@python.org You can print a more detailed traceback right now with "%tb", or use "%debug" to interactively debug it. Extra-detailed tracebacks for bug-reporting purposes can be enabled via: %config Application.verbose_crash=True ``` This is because we use the imported module's `__dict__` to get the classes and functions available in the module here: https://github.com/ipython/ipython/blob/9b8cd4a397e5894ffeadad52477bb53e0fb664fc/IPython/external/qt_loaders.py#L309-L311 This no longer works as not all the classes and functions are in the `__dict__`. The solution in this PR is to use `dir(module)` instead. I have tested this locally using `pyside6` 6.6.3.1, 6.7.0, 6.7.1 and 6.7.2 and it works for me. It also successfully creates Matplotlib plots using for example ``` In [1]: %matplotlib qt6 In [2]: import matplotlib.pyplot as plt In [3]: plt.plot([1,3,2]) ``` It would be good to get independent confirmation that this fixes other downstream libraries as I tend to work directly with IPython and IPyKernel.

File last commit:

r26723:f03bb325
r28842:e5d1a069 merge
Show More
test_backgroundjobs.py
85 lines | 2.6 KiB | text/x-python | PythonLexer
/ IPython / lib / tests / test_backgroundjobs.py
"""Tests for pylab tools module.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2011, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
# Stdlib imports
import time
# Our own imports
from IPython.lib import backgroundjobs as bg
#-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------
t_short = 0.0001 # very short interval to wait on jobs
#-----------------------------------------------------------------------------
# Local utilities
#-----------------------------------------------------------------------------
def sleeper(interval=t_short, *a, **kw):
args = dict(interval=interval,
other_args=a,
kw_args=kw)
time.sleep(interval)
return args
def crasher(interval=t_short, *a, **kw):
time.sleep(interval)
raise Exception("Dead job with interval %s" % interval)
#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------
def test_result():
"""Test job submission and result retrieval"""
jobs = bg.BackgroundJobManager()
j = jobs.new(sleeper)
j.join()
assert j.result["interval"] == t_short
def test_flush():
"""Test job control"""
jobs = bg.BackgroundJobManager()
j = jobs.new(sleeper)
j.join()
assert len(jobs.completed) == 1
assert len(jobs.dead) == 0
jobs.flush()
assert len(jobs.completed) == 0
def test_dead():
"""Test control of dead jobs"""
jobs = bg.BackgroundJobManager()
j = jobs.new(crasher)
j.join()
assert len(jobs.completed) == 0
assert len(jobs.dead) == 1
jobs.flush()
assert len(jobs.dead) == 0
def test_longer():
"""Test control of longer-running jobs"""
jobs = bg.BackgroundJobManager()
# Sleep for long enough for the following two checks to still report the
# job as running, but not so long that it makes the test suite noticeably
# slower.
j = jobs.new(sleeper, 0.1)
assert len(jobs.running) == 1
assert len(jobs.completed) == 0
j.join()
assert len(jobs.running) == 0
assert len(jobs.completed) == 1