Artificial truth

The more you see, the less you believe.

[archives] [latest] | [homepage] | [atom/rss/twitter]

AttributeError: 'NoneType' object has no attribute 'cancel' with Calibre
Thu 08 October 2020 — download

As I was trying to run Calibre 4.99.4 today, I got the following error:

$ calibre 
Traceback (most recent call last):
  File "/usr/bin/calibre", line 20, in <module>
    sys.exit(calibre())
  File "/usr/lib/calibre/calibre/gui_launch.py", line 73, in calibre
    main(args)
  File "/usr/lib/calibre/calibre/gui2/main.py", line 543, in main
    listener = create_listener()
  File "/usr/lib/calibre/calibre/gui2/main.py", line 514, in create_listener
    return Listener(address=gui_socket_address())
  File "/usr/lib/calibre/calibre/utils/ipc/server.py", line 110, in __init__
    self._listener._unlink.cancel()
AttributeError: 'NoneType' object has no attribute 'cancel'
zsh: exit 1     calibre
$

This is fixed by 7b6416ac652 in May 2020, with a shitty commit message: "...".

The root cause being that Python 3.8.3 is now making abstract socket namespaces playing nice with multiprocess, obsoleting Calibre's dirty hack to work around this issue.

The proper way to get the crash fixed is to upgrade to Calibre 4.15.0, the stupid one is to downgrade your Python version, and the gross one is to backport this patch:

+++ src/calibre/utils/ipc/server.py
@@ -107,7 +107,8 @@ def __init__(self, *args, **kwargs):
            Listener.__init__(self, *args, **kwargs)
            # multiprocessing tries to call unlink even on abstract
            # named sockets, prevent it from doing so.
-           self._listener._unlink.cancel()
+           if self._listener._unlink is not None:
+               self._listener._unlink.cancel()
            # Prevent child processes from inheriting this socket
            # If we dont do this child processes not created by calibre, will
            # inherit this socket, preventing the calibre GUI from being restarted.