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.