Friday, August 31, 2012

Python development with Sublime Text 2 tips and tricks

For quite some time I have used Eclipse + PyDev for Python development. Pydev makes definitively Eclipse a good IDE for Python, it has a great debugger and build system, the autocompletion works well, it is mature and read out of the box.

I decided to change searching for a more lightweight IDE and because I became simply addicted to the huge editing capabilities of Sublime Text 2, like selection management or editing several regions at the same time. The outline on the right is simply great... basically I find sublime extremely productive.

Now besides the (relatively not) interesting reasons why I started using sublime for python development, the goal of this post is to explain what and how to install to ease python development providing sublime things like python autocompletion, lint support, pdb support, etc, etc....

Python developmnt with Sublime Text alone

The first nice surprise with Sublime is that it is already a somewhat reasonable python IDE (without autocompletion). We already have syntax highlighting (quite common indeed), and a flexible build system.

The build system (discussed in bigger detail later) allows to un simple python scripts with no configuration at all just choosing python build system from Tools menu and build. It is easy to configure a your proper build system as discussed later on.

One of the most interesting out of the box features related with python is the presence of code templates as Sublime commands, thus reachable from the menu with cmd+shift+P.
By the way, the amount of languages Sublime provides snippets for is huge, just check Preferences - Browse Packages menu.

Now let's see what can we install as packages to provide python autocompletion, debugger support etc. Just to start with, a good way to install packages is through Sublime Package Control (downloadable here: http://wbond.net/sublime_packages/package_control) This provides a full package manager and helps discoverin, installing and updating packages.

Python autocompletion

For python autocompletion I installed a Sublime adaptation of Rope library: SublimeRope (https://github.com/JulianEberius/SublimeRope).

In terms of autocompletion, this package plugs into default Sublime default completion system adding python symbols at the default ones.

The easiest way to install it is through package control, Shift-Cmd-P,  choose Package Control: Install Package command and select SublimeRope. The installation won't require Sublime Text to be restarted.

Once Rope installed, each python file will profit of autocompletion. As it is at this stage, autocompletion will search for symbols declared in the file you are editing, all default python symbols and all installed modules and python symbols accessible from PYTHONPATH.

Still Rope won't be able to find symbols declared in separate files of the same project. To fix this issue, a Rope project needs to be created explicitly. This can be done through Rope: New Project command from the command palette.

Refactor and source management

Every reasonable IDE provides some kind of support for refactoring and some abilities to navigate through the sources of a project. SublimeRope provides these capabilities as well.

Once you install SublimeRope you have three commands for source navigation:
  • Rope: Go  to definition. Which opens the definition of the symbol under the cursor
  • Rope: Show Documentaiton. Shows python documentation for the symbol under the cursor:
  • Rope: Jump to Global.
Show Documentation output
SublimeRope provides an access through Sublime command palette to most of refactoring provided by Rope library like method extraction, inlining or extraction of variables, etc.

These functionalities come without a dedicated set of key bindings. These can be easily added modifying Sublime keybindings through Preferences - User Keybindings menu.
For example this maps "show documentation" on cmd + R +D:
 //Rope key bindings
    { "keys": ["super+r", "super+d"], "command": "python_get_documentation", "context":
        [
            { "key": "selector", "operator": "equal", "operand": "source.python" }
        ]
    }


Python lint

There are several python linters, for pyflakes and pep8 there is a Sublime package (SublimeLint) that highlights potential issues in your code while editing. It can be installed from Package manager while source and documentation can be found here: https://github.com/SublimeLinter/SublimeLinter.
Issues are highlighted directly in the code while a description is present on the status bar.

Sometimes for (more or less) good reasons we want to disable some of linter checks (personally I found the limitation to 86 characters to max line width a bit too strict). This can be done with sublimeLint by editing Sublimelinter.sublime-settings (Preferences - Package Settings - SublimeLinter - Settings - User menu). Pay attention always to modify user settings and not default ones which will be overwritten at every update.

Here are my settings:
{
    //I don't want to be bothered by issues on spaces around oeprators
    "pep8_ignore":
    [
        "E251","E501","W191","E303"
    ]
}

Debugging

What I miss most about Eclipse + PyDev is the great Eclipse debugger. Which is perfectly integrated with pdb  through PyDev.

Still pdb is not that hard to use alone, what is needed is a proper integration in Sublime Text. I found a good one in Sublime REPL (https://github.com/wuub/SublimeREPL) which allows running a lot of interactive interpreters into a Sublime Text buffer.

These interpreters include pdb (a command is ready out of the box to run the current python file with pdb - REPL: PDB current file command):
At this point you are running a classical pdb session.

A couple of words about build systems

For simple scripts, out of the box build systems are great as it is the scrupt ran through REPL. What happens instead when we want to provide input parameters to our script or change environemnt variables?

For running the scripts Subilme Text allows you to configure your own build system in a very flexible way, documented here: http://sublime-text-unofficial-documentation.readthedocs.org/en/latest/reference/build_systems.html.

I find useful adding the root of the project to PYTHONPATH in order to allow test scripts access the modules of my project no matter if they are in different directories and they are not yet installed in my python distribution.

To do so I created my build systems inside my project configuration instead of making them available to the whole IDE: in PROJECTNAME.sublime-project:

"build_systems":
    [
        {
            "cmd": ["python","${file}","command1"],
            "env": {"PYTHONPATH":"/Users/pyppo/Documents/workspacepython/pyCmdLiner/"},
            "name": "pythonProjectTestBase"
        }
    ]

creates a build system called pythonProjectTestBase that invokes python on the currently open file, passing a command argument (command1) and adding project root directory to PYTHONPATH before running the project.

Things are a bit more complex when debugging with REPL. I am not aware as of today of a project specific way to provide REPL configuration.

As a workaround I provided my PYTHONPATH as REPL user configuration in sublimeREPL.sublime-settings:

{
    "default_extend_env": {"PYTHONPATH":"/Users/pyppo/Documents/workspacepython/pyCmdLiner/"}
}

This is accessible from Preferences - Package settings - SublimeREPL - Settings User menu.

For additional flexibility it is always possible to modify SublimeREPL command definition or to create additional ones. This configuration is accessible from Preferences - Browse Packages - SublimeREPL menu, under python directory:
  • Default.sublime-commands lists the commands and points to the definition file
  • Main.sublime-menu contains commands definition.
Run python script with pdb is defined by default in this way:
{"command": "repl_open",
                     "caption": "Python - PDB current file",
                     "id": "repl_python_pdb",
                     "mnemonic": "d",
                     "args": {
                        "type": "subprocess",
                        "encoding": "utf8",
                        "cmd": ["python", "-i", "-u", "-m", "pdb", "$file_basename"],
                        "cwd": "$file_path",
                        "syntax": "Packages/Python/Python.tmLanguage",
                        "external_id": "python"
                        }
                    }

I never tried to provide a user based command configuration for REPL instead of tweaking the default one, so I cannot say if it is possible or not.

Conclusion

Here are my 2 cents on how to set up a python development environment with Sublime Text. I am pretty sure there are plenty of other useful packages to be installed to have a better IDE, this is just a starting point .....

21 comments:

  1. you have very nice posts in your blog. I also have a blog and a web directory, would you like to exchange links? let me know on emily.kovacs14@gmail.com

    ReplyDelete
  2. excellent post! already added to my evernote :DD

    thank you!

    ReplyDelete
  3. I am using enthought python and I had changed the right path in python.sublime-build but sublimerepl still uses the original python came with mac os x. I tried to put like this
    {
    "default_extend_env": {"PYTHONPATH":"/Users/pyppo/Documents/workspacepython/pyCmdLiner/"}
    }
    in sublimeREPL.sublime-settings but no luck. Any suggestion please?

    ReplyDelete
    Replies
    1. Hello,
      sorry for the late answer, I was travelling.

      I do not fully understand what you are trying to do:
      if you want to change python installation sublime will use to run your scripts the variable to change is not PYTHONPATH, in that python path is the search path for modules: http://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH

      To change python installation, I think you will have to change PATH variable and eventually PYTHONHOME, and not only on sublimeREPL.sublime-settings but also on build system configuration.

      Does this answer your question?

      Delete
  4. Just wanted to say thanks for a great blog post!

    ReplyDelete
  5. Thanks a lot, this post has been extremely useful to get started with SublimeText and python.

    ReplyDelete
  6. so i have this problem, which i can't figure out: rope should add me the autocomplete. good. but after importing module os, and writing os.wa, and pressing ctrl+space(autocomplete) none of the functions in os show up. how should i fix this? please help me.

    ReplyDelete
  7. Hello! Did you exploit some professional tricks to attract more followers your portal? Thank you so much in advance for your answer.

    ReplyDelete
    Replies
    1. Hi,
      no I didn't do anything. Seems someone linked this post on http://www.pythonweekly.com/ in september. I had followers since then.

      Delete
  8. Speaking about useful Python plugins, I found the following two VERY handy:

    Python Path To Clipboard and Python Open Module (New)

    ReplyDelete
  9. Excelent buddy, I've been trying to find a good IDE with intellisense for python and now I have it.

    ReplyDelete
  10. Since you seem to know about customising Python build systems in Sublime I was wondering if you can help me with mine.

    I currently use the PyNPP plugin for Notepad++ which enables me to run the current file in an interactive Python interpreter that is opened in a fresh command-prompt/terminal/shell window.

    Sublime seems to insist on using it's built-in panel/shell - which does not accept input - even if "shell": "true" is set in the build file.
    i.e
    {
    "cmd": ["C:\\python27\\python.exe", "-i", "$file"],
    "shell": "true"
    }
    does the same with or without the shell line

    Any advice?

    Screenshots of what I am trying to achieve can be seen here: http://www.sublimetext.com/forum/viewtopic.php?f=3&t=7815#p44745

    ReplyDelete
  11. This interesting topic is discussed with great seriousness, I learned a lot from these few lines in any case, thank you give time to your readers.

    ReplyDelete
  12. Thank you for this post, it helped a lot!

    ReplyDelete
  13. Wonderful great going, I love your work and look forward for more work from your side. I am a regular visitor of this site and by now have suggested many people

    ReplyDelete
  14. This is nice post which I was awaiting for such an article and I have gained some useful information from this site. Thanks for sharing this information.

    Web Applications Developer London

    ReplyDelete