Sigil-Ebook / Sigil

Sigil is a multi-platform EPUB ebook editor
GNU General Public License v3.0
5.99k stars 578 forks source link

[Bug]: Plugins stopped working on Linux with Python 3.12 and system hunspell [solution found] #741

Closed mihailim closed 9 months ago

mihailim commented 9 months ago

Bug Description

On Linux, when using Python 3.12 as the Sigil Python interpreter (24.04 changed to 3.12 as the default recently) while using the system hunspell, all plugins stopped working with backtrace similar to the testplugin one posted below due to a backtrace in the hunspell plugin loader.

It's trivial to reproduce on Linux, just switch the interpreter to 3.12 then run the testplugin (or any other plugin, for that matter), since the affected pluginhunspell.py code path runs for all of them.

Turns out that this is happening because of a cdll object behavior change introduced in this commit as a response to this issue: In 3.12.0a4 or newer, a key lookup when treating cdll as a dict no longer raises an OSError, but instead raises an AttributeError.

This was very badly documented in the Python changelog as "bpo-34816: hasattr(ctypes.windll, 'nonexistant') now returns False instead of raising OSError." in the Windows (!!) section of the 3.12.0 alpha 4 release notes -- not even a clairvoyant would figure out it would impact Linux in this manner...

The fix is trivial, also catch AttributeError in addition to OSError in pluginhunspell.py. Backwards compatible PR submitted at #742 .

Platform (OS)

Linux

OS Version / Specifics

Ubuntu 24.04 daily

What version of Sigil are you using?

2.0.1

Any backtraces or crash reports

Traceback (most recent call last):
  File "/usr/lib/python3.12/ctypes/__init__.py", line 450, in __getattr__

    dll = self._dlltype(name)
          ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/ctypes/__init__.py", line 379, in __init__
    self._handle = _dlopen(self._name, mode)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: /usr/lib/x86_64-linux-gnu/sigil/libhunspell.so: cannot open shared object file: No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/share/sigil/plugin_launchers/python/launcher.py", line 317, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/share/sigil/plugin_launchers/python/launcher.py", line 277, in main
    bc = BookContainer(rk)
         ^^^^^^^^^^^^^^^^^
  File "/usr/share/sigil/plugin_launchers/python/bookcontainer.py", line 42, in __init__
    self.hspell = HunspellChecker(wrapper.get_hunspell_path())
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/sigil/plugin_launchers/python/pluginhunspell.py", line 49, in __init__
    self.hunspell = cdll[hunspell_dllpath]
                    ~~~~^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/ctypes/__init__.py", line 457, in __getitem__
    return getattr(self, name)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/ctypes/__init__.py", line 452, in __getattr__
    raise AttributeError(name)
AttributeError: 
/usr/lib/x86_64-linux-gnu/sigil/libhunspell.so