Skip to content

Instantly share code, notes, and snippets.

@paxcodes
Last active December 19, 2023 12:05
Show Gist options
  • Save paxcodes/012262b82e64b73eefd2f4f10cfc951b to your computer and use it in GitHub Desktop.
Save paxcodes/012262b82e64b73eefd2f4f10cfc951b to your computer and use it in GitHub Desktop.
Configuring a Python Workspace (Ubuntu, VS Code)

🛠 Python Workspace in VS Code

Goals

To automatically

  • remove unused imports
  • order our imports alphabetically (isort)
  • detect basic security guidelines using Bandit
  • autoformat our code (line length, etc.)

And have other support for development like refactoring and code quality metrics.

✨ Steps

  • Install pipx
  • Install packages with pipx: bandit, pylama, black, isort, autoflake
  • Install VS Code extensions: python, pylance, conventional commits, git graph, gitlens, markdown all in one, jumpy, python docstring generator, Sourcery, Code Spell Checker, indent-rainbow

Settings

{
    "python.formatting.blackPath": "~/.local/bin/black",
    "terminal.integrated.tabs.enabled": false,
    "diffEditor.ignoreTrimWhitespace": false,
    "python.sortImports.path": "~/.local/bin/isort",
    "python.linting.banditPath": "~/.local/bin/bandit",
    "python.linting.pylamaPath": "~/.local/bin/pylama",
    "terminal.integrated.sendKeybindingsToShell": true,
    "terminal.integrated.allowChords": false,
    "git.enableSmartCommit": true,
    "terminal.integrated.fontSize": 12,
    "terminal.integrated.lineHeight": 1.2,
    "editor.fontSize": 12.5,
    "editor.lineHeight": 2,
    "editor.minimap.enabled": false,
    "python.linting.banditEnabled": true,
    "python.linting.pylamaEnabled": true,
    "python.formatting.provider": "black",
    "editor.formatOnSave": true,
    "python.analysis.typeCheckingMode": "basic",
    "gitlens.currentLine.enabled": false,
    "files.trimTrailingWhitespace": true,
    "diffEditor.renderSideBySide": false,
    "python.analysis.completeFunctionParens": true,
    "editor.tabSize": 3,
    "[python]": {
        "editor.tabSize": 4,
    },
    "editor.fontFamily": "'Fira Code', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback'",
    "editor.fontLigatures": true,
    "editor.rulers": [
        88
    ]
}

Notes

  • Disable Format on Paste --- Black does not support the "Format Selection" command Issue #1883 · microsoft/vscode-python · GitHub
  • Set pylance.typeCheckingMode to strict. Or set to basic if using 3rd-party libraries with no type-hinting and no time to create your own stubs.

Configuring Bandit

Problem: I am getting Use of assert detected...bandit(B101) reports on my tests.
Solution:

// settings.json or .code-workspace file
 "python.linting.banditArgs": [
    "--exclude",
    "/tests"
  ]

This will exclude ALL bandit rules in tests. Issues to specifically exclude only B101 in tests is in GitHub. PyCQA/bandit#346

🛠 Automatically Run iSort and autoflake on Save

  • Install VS Code extension pucelle.run-on-save
  • In settings.json or .code-workspace file
"runOnSave.statusMessageTimeout": 3000,
  "runOnSave.commands": [
        {
            "match": ".*\\.py$",
            "command": "autoflake -i --remove-all-unused-imports --remove-unused-variables ${file}",
            "runIn": "backend",
            "runningStatusMessage": "Removing unused imports and variables in ${fileBasename}",
            "finishStatusMessage": "${fileBasename} cleaned. 🍰 ✨"
        },
        {
            "match": ".*\\.py$",
            "command": "isort ${file}",
            "runIn": "backend",
            "runningStatusMessage": "Sorting imports in ${fileBasename}",
            "finishStatusMessage": "Imports in ${fileBasename} has been sorted. 🍰 ✨"
        },
  ]

This assumes isort and autoflake has been installed "globally". I installed them using pipx

Keybinding for Jumpy

{
    "key": "ctrl+cmd+enter",
    "command": "extension.jumpy-word",
    "when": "editorTextFocus"
}

Project-specific Steps

Configuring iSort

In pyproject.toml,

[tool.isort]
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
ensure_newline_before_comments = true
line_length = 88

Configuring Pylama

In pylama.ini

[pylama:pycodestyle]
max_line_length = 88

Other ideas

Setting autoflake as a task

// tasks.json
  {
      "label": "autoflake",
      "type": "process",
      "command": "autoflake",
      "args": ["-i", "${file}"],
      "presentation": {
        "reveal": "silent",
        "panel": "shared",
        "showReuseMessage": false
      }
    }
// keybindings.json
  {
    "key": "ctrl+shift+backspace",
    "command": "workbench.action.tasks.runTask",
    "args": "autoflake"
  }

💡 VS Code Tasks

Tasks in Visual Studio Code

They would rather run a watcher, than have a task run on every save:

Watching tasks should be implemented using watch support of exist task runners. Always starting a task on save is not very performant nor battery friendly. —Run task on save? · Issue #2159 · microsoft/vscode · GitHub

💡 emeraldwalk/RunOnSave ?

VS Code Extension

❗️Low rating ❕Not maintained so much in the past year

Note on "Organize Imports"

  "editor.codeActionsOnSave": {
    "source.organizeImports": true
  }

Python Refactor: Sort Imports or Organize Imports does not have the same output as running isort {file} in the command line, for some reason I don't know.

Original:

from my_project.main import app
from fastapi.testclient import TestClient

"Organize Imports" code action:

from fastapi.testclient import TestClient
from my_project.main import app

isort {file} in the command line:

from fastapi.testclient import TestClient

from my_project.main import app

🔨 Manual Tools

  • To use mccabe, you can run pylama -l mccabe manually against the project using the terminal

📝 Notes

What actual linters should I use?

💡 Our own mix

  • Pylama
    • pycodestyle (formerly pep8)
    • pydocstyle (formerly pep257)
    • PyFlakes - Analyzes programs and detects various errors
    • Mccabe - Analytical Checks McCabe complexity1
    • Pylint - Checks for errors, tries to enforce a coding standard, looks for code smells
    • Radon - Analyzes code for various metrics (lines of code, complexity, and so on)
    • gjslint - irrelevant - a javascript linter?
  • Bandit
  • Black---as formatter
  • isort---to sort and organize imports
  • Pyright---for typechecking
  • autoflake---to remove unused imports and variables

🥰 Inspiration

Footnotes

  1. Cyclomatic complexity is a software metric used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program's source code. It was developed by Thomas J. McCabe, Sr. in 1976.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment