Trying Out PyCharm, Part 2

In which I actually use the editor to write code

Previously, I attempted to write up my experiences with the new beta of the PyCharm editor for Python, from JetBrains, makers of IntelliJ IDEA. By the time I got a basic installation working and started a Django project, I ran out of time. This time around, I actually wrote a little bit of code using PyCharm, so I have a few more things to say.

Things I like

It defaults to spaces, not tabs. This is correct.

Ctrl-space does menu completion, and this works very well. If you’re used to Intellisense, this does what you expect. Any IDE worth its salt should be able to accomplish this basic task.

Overriding methods get a little icon in the left gutter that takes you to the source code for the methods they override, and similarly, overridden methods allow you to navigate up and down the hierarchy. This is neat, and not something I’ve seen any Python editor do before.

The Structure panel is great. It updates as you code, and uses icons to distinguish between variables, functions, and methods.

You can duplicate a line with Ctrl+D, comment a line with Ctrl+/, and indent/dedent a line with Tab/Shift-Tab. If there is an active selection, these commands work on the selection instead. These are super-handy and very intuitive features.

Entire blocks can be easily rearranged by the Move Statement Up / Move Statement Down (Ctrl+Shift+Up/Down) commands. This seems like it would be really handy for code reorganization.

Ctrl+B will jump to the definition of the symbol under the cursor, and if it’s ambiguous it pops up a menu where you can pick which definition you mean. Likewise, Ctrl+N lets you type a class name to jump to, searches as you type, and lets you refine your choice with a pop-up menu. I can see this being a huge time saver.

The basic refactorings are all there: Rename, Change Signature, Move, Copy, Safe Delete, Inline, Pull Up, Push Down, Extract Interface, Extract Superclass. I’m not sure what Extract Interface does, since Python doesn’t really have interfaces (third-party implementations aside), but Extract Superclass has a nice interface where you can check which methods you want to move into the new base class. If the current class already extends a class, it will use multiple inheritance. This isn’t Java!

Out of the box, PyCharm supports CVS, Subversion, Git, and Mercurial. Not too shabby!

Editor windows can be split horizontally and vertically, and each split pane can have its own tabs. The tabs don’t currently support drag’n'drop, which is a bummer, but I bet they’ll have that working soon, since everyone expects that to work with web browsers nowadays.

Things I’m on the fence about

The real-time syntax checking is slightly distracting, just as I recall it being with IDEA. As I type, various things get underlined with red squigglies to notify me that my syntax is invalid. It’s invalid, usually, because I haven’t finished typing yet.

Code folding works great, if you’re into that sort of thing. I seem to be the odd one out – I can’t stand it. It just creates a bunch of noise, and I feel like if your program is so big and deeply nested that you need to collapse sections of it, you should fix your program. But anyway, PyCharm does folding just fine.

Things I don’t like

Introspection doesn’t always work too well. When I tried to create a models.CharField for a model, it popped up with the hint that CharField takes the arguments (self, *args, **kwargs). I’m sure there’s some fancy footwork going on in Django that makes this difficult, but it would be really helpful to have argument hints about basic stuff like this if PyCharm is to claim any sort of Django support.

One of the more amazing refactorings that IDEA can do, which I think is called Replace Inheritance With Delegation, is not available in PyCharm. I think this is a great tool, and hopefully it will get integrated with PyCharm someday. Python’s support for multiple inheritance makes it less necessary, perhaps (since the big benefit with Java is to be able to pick a different base class without breaking anything, since Java only allows single-inheritance).

By default, you can click anywhere and it will put the cursor at that point, even if it’s 50 characters to the right of the text. This really bothers me, but fortunately it’s easy to disable: File->Settings->IDE Settings->Editor->Virtual Space->Allow placement of caret after end of line.

PyCharm follows the convention that many Windows-style programs do these days, where Ctrl-Left/Right moves between words but Alt-Up/Down moves between paragraphs. I don’t know who came up with this, but I really prefer Ctrl-Up/Down for symmetry, and so that I can keep Ctrl held down and easily move around. Ctrl-Up/Down works like a mouse wheel, which is a nice feature but I wish it had a different shortcut. Alt-Left/Right switches between tabs, which is handy but also weird to me. But I’m really nitpicking here.

Indexing takes a long time. After opening the editor, you’ll want to grab some coffee or what-have-you.

Thumbs Up

This is really just a superficial evaluation of PyCharm, since I would have to use it for much longer to really critique it properly. It appears to be well-implemented, full-featured, and artfully designed. I think I could be happy using PyCharm. I don’t know if it’s compelling enough to break my Emacs addiction, but it’s certainly a worthy contender. I recommend giving it a try!

Trying out PyCharm, Part 1

One of the things in our goodie bags at DjangoCon 2010 was a quick reference card for PyCharm, a new (still beta) IDE for Python designed by JetBrains, the makers of IntelliJ IDEA. I’m not a big fan of IDEs in general, but I did use IDEA for a little over a year when I was writing a lot of Java, and I was very impressed with the quality of that product. So, when I found out about PyCharm, I figured I should at least try it out and see how well it works. I’m pretty much an Emacs die-hard at this point, so I don’t expect to be wooed, but I’m trying to keep an open mind about it anyway. Here is a summary of my first experiences with it.

When I first tried to run PyCharm, I got an error about how no JDK was installed, which made me remember that I had completely purged Java from my system. I do this about every six months to save disk space, I think.

I was unsure about whether I actually needed a JDK or just a JRE, so I decided to try just installing the JRE. PyCharm still complains about wanting environment variables to be set, but I just symlinked /usr/bin/java to /bin/java, and it starts up fine despite the error message.

The initial interface is colorful and welcoming. I couldn’t help but notice that the fonts and toolbar buttons all look very Java. I guess this is to be expected, but it feels a bit foreign. It doesn’t look bad, however; it looks professional. It’s just a tiny reminder that this is a Java program.

I read something about Django integration on the PyCharm website, so I figured a good test would be to try creating a new Django hello-world project. The first option under “Quick Start” is “Create NewProject”, so that’s where I went. It popped up a simple dialog asking for a project name and location, and I could choose between a “Empty project”, “Django project”, and “Google App Engine” project. I picked “Django project” and a new project was created – for Python 3.1. Whaaaaaaaat?

I then saw a second popup titled “Django Project Settings”. The only available choice for “Python Interpreter” was the “Python 3.1.2″ it picked, This definitely was not going to work, so I hit the “…” button, where I could add and remove Python Interpreters. It was able to locate the Python 2.6 I had installed, and after a lengthy scan of libraries for that version, my project settings were ready to go.

Also on the “Django Project Settings” panel was an “Application name” field, which was a little bit confusing because projects normally consist of multiple applications. I went ahead and entered an application name anyway, even though it appeared to be optional. There was also a templates directory, which was already filled in and located at the project level.

Once I confirmed the project settings, a progress bar dialog titled “Loading Project” popped up, with messages reading “Generating skeletons of binary libs for interpreter /usr/bin/python2.6″. I thought it already scanned all the libraries once, but I guess it wasn’t building “skeletons” that time. I assume this is for metadata to enable completion in the editor. I think their Java bias is showing in the way they repeatedly refer to Python installations as “interpreters”. Do they not know that Python runs on a bytecode compiler too?

The scan finished after a few minutes, and I was dropped into the main editor window. A progress bar at the bottom of the window indicated that there was still more indexing to be done, with a tooltip reading “Updating project indices… Refactorings, usage search, and some other featuers will become available after indexing is complete.” A red icon with an esclamation mark blinked sporadically, and mousing over this icon caused a message to briefly display about an internal error that should be reported to their beta program. Once the indexing stopped, the red icon went away, so I guess there isn’t much I can do here.

Oh wait, it’s back. It says something about an internal error: a null pointer from com.intellij.ide.projectView.BaseProjectTreeBuilder.expandNodeChildren. I was wondering how long it would take before I saw a Java stack trace.

There were initially two frames to the main window, a project panel and a gray area where the editor goes. The project panel appeared to be empty, which may be a result of the exception that occurred earlier. When I clicked “View as” in the project sidebar, I could change the view from “Project” to… well, just “Project”. So I did that, and it reloaded and this time I could see all the files in the directory tree it created.

The initial project looked more or less like the results of a standard Django “startproject” and “startapp”.

I clicked the green “Run” button in the toolbar to see what would happen. It opened a Run panel at the bottom and executed “/usr/bin/python2.6 manage.py runserver 8000″, which succeeded in getting a Django development server instance up and running. I popped open a web browser and went to localhost:8000, hoping to see Django’s welcoming first page, but instead I got an error about how “/” could not be found, since the only defined url pattern is “^admin/”. I guess this is to be expected since I asked for an admin site, though it was kind of a bummer to not get the usual pretty blue “it works!” page.

I next tried “/admin/” and got an ugly Python stack trace with the message “ImproperlyConfigured: You haven’t set the database ENGINE setting yet.” I guess this is my cue to set up a database of some sort. Unfortunately, I ran out of time to play with PyCharm, so I didn’t get a chance to kick the tires of the editor itself. I’ll try to write a “Part 2″ about the editor experience soon.