Segmentation fault on signal disconnect after module reload

Phil Thompson phil at riverbankcomputing.com
Wed Aug 14 09:21:32 BST 2024


On 13/08/2024 21:31, bers at gmx.net wrote:
> Hi,
> I managed to reproduce a segmentation fault in PyQt.
> 
> This is bug.py:
> ```
> from importlib import reload
> from pathlib import Path
> 
> 
> def test_reload() -> None:
>     mod_folder = Path("mod_folder")
>     mod_folder.mkdir(exist_ok=True)
> 
>     with open(mod_folder / "mod_file.py", "w") as f:
>         f.write("from PyQt6.QtCore import QObject, pyqtSignal, 
> pyqtSlot\n")
>         f.write("class Class(QObject):\n")
>         f.write("    signal = pyqtSignal()\n")
>         f.write("    @pyqtSlot()\n")  # <-- this line crashes, try 
> removing it!
>         f.write("    def slot(self): ...")
> 
>     from mod_folder import mod_file
> 
>     instance = mod_file.Class()
>     instance.signal.connect(instance.slot)
> 
>     reload(mod_file)
>     instance.__class__ = mod_file.Class
> 
>     instance.signal.disconnect(instance.slot)
> ```
> 
> Python 3.12.4 on Windows 11
> pip install pytest==8.3.2 PyQt6==6.7.1
> pytest bug.py
> 
> Context:
> https://github.com/pyqtgraph/pyqtgraph/pull/3123#issuecomment-2284538600
> 
> Stack trace:
> 
> ```
> bug.py Windows fatal exception: access violation
> 
> Current thread 0x000049bc (most recent call first):
>   File "C:\Code\bug.py", line 24 in test_reload
>   File "C:\Code\.venv\Lib\site-packages\_pytest\python.py", line 159
> in pytest_pyfunc_call
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_callers.py", line 103
> in _multicall
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_manager.py", line 120
> in _hookexec
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_hooks.py", line 513 in 
> __call__
>   File "C:\Code\.venv\Lib\site-packages\_pytest\python.py", line 1627 
> in runtest
>   File "C:\Code\.venv\Lib\site-packages\_pytest\runner.py", line 174
> in pytest_runtest_call
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_callers.py", line 103
> in _multicall
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_manager.py", line 120
> in _hookexec
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_hooks.py", line 513 in 
> __call__
>   File "C:\Code\.venv\Lib\site-packages\_pytest\runner.py", line 242 in 
> <lambda>
>   File "C:\Code\.venv\Lib\site-packages\_pytest\runner.py", line 341
> in from_call
>   File "C:\Code\.venv\Lib\site-packages\_pytest\runner.py", line 241
> in call_and_report
>   File "C:\Code\.venv\Lib\site-packages\_pytest\runner.py", line 132
> in runtestprotocol
>   File "C:\Code\.venv\Lib\site-packages\_pytest\runner.py", line 113
> in pytest_runtest_protocol
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_callers.py", line 103
> in _multicall
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_manager.py", line 120
> in _hookexec
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_hooks.py", line 513 in 
> __call__
>   File "C:\Code\.venv\Lib\site-packages\_pytest\main.py", line 362 in
> pytest_runtestloop
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_callers.py", line 103
> in _multicall
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_manager.py", line 120
> in _hookexec
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_hooks.py", line 513 in 
> __call__
>   File "C:\Code\.venv\Lib\site-packages\_pytest\main.py", line 337 in 
> _main
>   File "C:\Code\.venv\Lib\site-packages\_pytest\main.py", line 283 in
> wrap_session
>   File "C:\Code\.venv\Lib\site-packages\_pytest\main.py", line 330 in
> pytest_cmdline_main
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_callers.py", line 103
> in _multicall
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_manager.py", line 120
> in _hookexec
>   File "C:\Code\.venv\Lib\site-packages\pluggy\_hooks.py", line 513 in 
> __call__
>   File "C:\Code\.venv\Lib\site-packages\_pytest\config\__init__.py",
> line 175 in main
>   File "C:\Code\.venv\Lib\site-packages\_pytest\config\__init__.py",
> line 201 in console_main
>   File "c:\Code\.venv\Scripts\pytest.exe\__main__.py", line 8 in 
> <module>
>   File "<frozen runpy>", line 88 in _run_code
>   File "<frozen runpy>", line 198 in _run_module_as_main
> ```
> 
> Kind regards

Sorry, but SIP generated code completely ignores the possibility that a 
module might be reloaded. This is a bug not a feature. It's in the plan 
to implement support for PEP 489 multi-phase module initialisation 
(which would solve the problem) prior to supporting multiple 
sub-interpreters. This work should start before the end of the year.

Phil


More information about the PyQt mailing list