View Single Post
Old 03-29-2014, 09:39 PM   #1
trying
Member
trying doesn't littertrying doesn't litter
 
Posts: 21
Karma: 104
Join Date: Oct 2013
Device: none
Getting PyCharm code completion while writing Calibre plugins

First of all, I am a complete newbie when it comes to writing Calibre plugins. All I've done so far is take kiwidude's Count Pages plugin and blast in the ability to also count the # of occurrences of a (weighted) list of words. (To show how lame my implementation is my weighted list is just a dict of regexs with the weights as the values written directly in his statistics.py file. I didn't bother to write a GUI for this since it's easy enough for me to just edit the source and reload the plugin )

Anyway, I've discovered a way to use the very nice (and free) JetBrains PyCharm 3.1.1 Community Edition IDE that lets you see code completion for Calibre objects while writing plugins. Unfortunately, I don't know how to use the PyCharm Debugger on a Calibre plugin (it's probably impossible?).

The basic idea is to download the source to Calibre, extract the src\Calibre directory --- or even all the subfolders of src --- into a .zip file, and then setup a PyCharm Python Interpreter to have that zip file in its path.

(For whatever reason, I couldn't directly use C:\Program Files\calibre2\pylib.zip? I couldn't even in unpack it correctly since it seems to be some weird zip that doesn't let you unpack while preserving its relative paths?)

Then you'll get code completion for anything in the calibre module. For example, typing "from calibre." will show things like:
constants
db
ebooks
gui2
utils
in a popup. And of course PyCharm already supports PyQt4 so you get code completion when writing your QWidget derived class.

Here's the details for those interested. Assuming you have calibre.zip (just the src\Calibre --- or maybe src if you also want completions of odf, cherrypy, regex, etc? --- tree of calibre-1.29.0.tar.xz) do this:
  1. Set up a PyCharm project for the plugin by choosing File | New Project...

    The location should just be the location of your plugins source files. For the Interpreter I use Python 2.7.x but it really doesn't matter since you won't be able to debug anyway.

    You'll see a message about "The directory blah is not empty. Would you like to create a project from existing sources instead?" Click on Yes.
  2. Click File | Settings. In the Project Settings section, click on Project Interpreter and then Python Interpreters (You might have to click on the "Configure Interpreters" link first?). Pick a Python 2.7.x interpreter rather than a Python 3.x one (probably doesn't matter?).

    In the lower pane, click on the Paths tab. Click on the + button and then set the path to your calibre.zip file.

    You might want to select all the Lib\site-packages entries and click the - button, since those modules won't be available within the Calibre pylib.zip file. However, keep Python27\Lib to get code completion for the Python Standard Library (here's where it *does* matter that you pick Python2x rather than Python3x since Calibre uses Python2x).
  3. Click the "Reload lists of paths" icons.
  4. Click Okay to close the Settings dialog.
That's it. You should no longer see the red error squiggles underneath Calibre module objects. One remaining problem is that the following doesn't work (or any other of your plugin's packages):

Code:
   from calibre_plugins.count_pages.common_utils import (get_library_uuid, CustomColumnComboBox,
                                     KeyboardConfigDialog, KeyValueComboBox, PrefsViewerDialog)
presumbably because the plugin's packages are dynamically loaded. A
workaround is to change this to just:

Code:
   from common_utils import (get_library_uuid, CustomColumnComboBox,
                             KeyboardConfigDialog, KeyValueComboBox, PrefsViewerDialog)
and maybe somehow use the correct from statement by checking some Calibre specific variable that lets you know when you are running inside Calibre?

Hope this is of some interest to people

Last edited by trying; 03-29-2014 at 10:03 PM. Reason: fix error
trying is offline   Reply With Quote