Improving your Python workflow with Visual Studio Code

Configuring Visual Studio Code for Python Development

Estimated reading time

When writing code, everyone has a preference for their favourite editor of choice. I've been a massive fan of Sublime Text for years now, and although I switched across to Atom earlier this year for a bit of a trial, there were a lot of things I just missed from my setup in Sublime. The debugging package that was suggested stopped working randomly. Responsiveness became an issue the larger the project became (particularly from an autocomplete standpoint), and numerous other niggles. Still, the interface was extremely slick, and the theme support was great, so I persevered with it. That was until a new challenger appeared...

Enter Visual Studio Code...

Visual Studio Code reached it's version 1.0 milestone not long ago, and is starting to prove itself to be quite a powerful replacement for either Sublime Text or Atom, particularly for Python development.

Today we'll be looking at how we can optimise the editor with a number of different extensions (or plugins if you're coming from Sublime) that will make writing Python a more enjoyable experience. Extensions are all installed simply by bringing up the command palette (cmd + shift + p) and typing ext install <name>.

Python specific extensions

1. Python

This is the go to extension for all things Python related. As an overview it provides:

2. Jinja

This extension adds support for the Jinja2 template language support to VS Code. This can then be set either via the status bar, or the command palette with Change Language Mode.

3. MagicPython

MagicPython improves the highlighting for Python 3 (in particular 3.5) syntax features including type annotations, string formatting, and regular expressions.

General extensions

The following extensions are not specific to Python, but add some great features to VS Code.

1. Project Manager

Manage projects directly from the command palette.

2. Trailing Spaces

Highlights trailing spaces at the end of the line, and can remove them if configured to do so on save.

3. Visual Studio Code Settings Sync

Synchronize Settings, Snippets, launch, keybindings files and extensions Across Multiple Machines using Github GIST.

4. Status Bar Tasks

Displays any tasks that you've configured in the Status Bar (down the bottom left), which can then be run just by clicking on them.

5. VS Code Icons

Brings file icons to the Explorer pane.

Configuring the Python extension

There are a couple of changes in your user preferences that you'll want to make to get VS Code working as best as possible. Open up your Preferences (Code > Preferences > User Settings) and then modify the values to the following:

Note: VIRTUALENV_PATH points to whatever directory your preferred virtualenv is located in and must be an absolute path. It's helpful to have a virtualenv in each project, which will allow you to utilise ${workspaceRoot} for tasks.json and launch.json, however this cannot be used in settings.json.


{
    // Python specific

    "python.pythonPath": "VIRTUALENV_PATH/bin/python3",
    "python.autoComplete.extraPaths": [
        "VIRTUALENV_PATH/lib/python3.5/site-packages"
    ],
    "python.devOptions": [
        "DEBUG"
    ],
    "python.linting.pylintEnabled": false,
    "python.linting.flake8Enabled": true,
    "python.formatting.provider": "autopep8",
    "python.unitTest.unittestEnabled": true,
    "python.unitTest.pyTestEnabled": true,
    "python.unitTest.nosetestsEnabled": false,

    // Extension and editor preferences

    "files.insertFinalNewline": true,
    "editor.fontFamily": "Fira Mono",
    "editor.fontSize": 14,
    "editor.rulers": [79],
    "editor.roundedSelection": false,
    "explorer.openEditors.visible": 0,
    "trailing-spaces.trimOnSave": true,
    "files.exclude": {
        "**/.git": true,
        "**/.DS_Store": true,
        ".vscode": true,
        "**/__pycache__": true,
        "**/**/*.pyc": true
    }
}

Note: Tabs have been added to the latest update (1.3.0), which is why the explorer.openEditors.visible setting has been added.

Once you've correctly configured the extension as above, you'll find that everything will just start working nicely, such as the code signatures that are displayed on hover.

Debugging

Working with a proper debugger is far more efficient than printing out variables to your console or to a log file, and thankfully VS Code provides great debugging. The Python extension that you've already installed has several templates for different web frameworks that will help you get started (including Watson). Switch across to the debugging tab and then click on the settings icon to choose Python from the list of environments. Additional options will be added to your launch.json file, and will look similar to this:


{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Watson",
            "type": "python",
            "request": "launch",
            "stopOnEntry": false,
            "program": "${workspaceRoot}/console.py",
            "pythonPath": "VIRTUALENV_PATH/bin/python",
            "exceptionHandling": {
                "ignore": ["ImportError"]
            },
            "args": [
                "dev",
                "runserver",
                "--noreload=True"
            ],
            "debugOptions": [
                "WaitOnAbnormalExit",
                "WaitOnNormalExit",
                "RedirectOutput"
            ]
        }
    ]
}

There are a couple of non standard settings in that snippet above such as pythonPath and exceptionHandling. pythonPath will use the specified virtualenv, where as exceptionHandling allows you to ignore specific exceptions that are raised.

Unit Testing (and running tasks)

Switching across to your console to run your unit tests after writing them can also be quite annoying. Luckily, it's easy to setup a task (or several) to run the relevant tests. Bring up the command palette and search for Tasks: Configure task runner then select Other from the list. Copy and paste the below snippet in place of the supplied template and you're good to go.


{
    "version": "0.1.0",
    "isShellCommand": true,
    "command": "sh",
    "args": ["-c"],
    "tasks": [
        {
            "taskName": "py.test",
            "isTestCommand": true,
            "suppressTaskName": true,
            "args": [
                "VIRTUALENV_PATH/bin/py.test"
            ]
        }
    ]
}

You can now run your test task with Cmd+Shift+T (or whatever keybinding you've set workbench.action.tasks.test to) or click on the task name if you've installed the Status Bar Tasks extension.

The Python extension does come with the ability to run tests directly from the command palette. Though I feel that going this route gives you more flexibility with keeping all your tasks located in a single place.

Conclusion

The editor war is still raging pretty hard out there, and there definitely isn't a clear victor yet. That said, Visual Studio Code is a much welcomed addition to the fold, particularly for Python developers it provides a robust and fast editing experience, and with the number of extensions for it growing daily, there's no reason not to give it a try.