Lo-Fi Python

Jul 23, 2023

There's a Linter for That! Python Linter and Formatter Libraries You Gotta Know

Linters exist for almost every kind of structured document. Python code, SQL, reStructuredText and many data formats can be improved with a linting library. Python's ecosystem has no shortage of formatters and linters.

In this post, I'll highlight the typical players and some niche linters you might not have heard of! The best quality of linters is their ability to find potential problems in your code by enforcing domain-specific rules. In return, you receive a list of hints for fixing anti-patterns, inconsistencies or unused code to remove. Many linters also offer document reformatting capabilities like the ubiquitous black library for Python code.

Python Linters and Formatters You Gotta Know

  • ruff: the lean and fast linter library that's gotten a lot of people's attention. For good reason, it's the easiest and fastest Python code linter, running rust under the hood. In my experience, using ruff has made me a more efficient Python programmer. The ruff CLI's --fix argument is a nice touch for automatically fixing up your code. In addition to linting, ruff also now includes Python's fastest built-in formatter! ruff format is a high performance drop-in replacement for black.

Run ruff on your Python script for quick and easy linting.

pip install ruff
ruff do_stuff.py
# Find Python code errors and fix them with ruff.
ruff do_stuff.py --fix

Run ruff format on your Python script for fast code formatting.

ruff format do_stuff.py
  • black: a must-mention, this Python code formatter with some linting-like qualities if your code has syntax errors. Typically, I run it on every script I write, but might consider using ruff format instead!

Reformat your code with black.

pip install black
python -m black do_stuff.py
sqlfluff SQL linting CLI tool
  • sqlfluff: "The SQL linter for humans", sqlfluff is a linter and code reformatting tool to tidy up your database queries. sqlfluff does the little things like uppercase your keywords, add whitespace where appropriate, check syntax and in general clean up your scripts. The CLI is configurable for nearly all dialects from DuckDB, T-SQL, Redshift, MySQL, to SQLlite and more. Check the sqlfluff Github repo for all their supported SQL dialects or use the sqlfluff dialects command to list them in your shell. This is the library I want to tell every Python programmer about right now, along with ruff. SQL is everywhere, we all use it. SQL linters are not something most people even know exist. Next time you need to fix a broken SQL script or clean up some legacy code, enter this into your shell:
pip install sqlfluff
# Lint your SQL code.
sqlfluff lint stuff.sql
# Fix your SQL file in the PostgreSQL dialect.
sqlfluff fix stuff.sql --dialect postgres
# Check available SQL dialects.
sqlfluff dialects
  • json.tool: a Python standard library CLI tool with JSON validation abilities. If you're working with json, remember this stock Python tool.

Validate JSON with a built-in python CLI tool.

echo '{1.2:3.4}' | python -m json.tool
  • pylint: commonly used static code analyser that enforces PEP-8 and other rules in your code.

Use pylint to improve to improve your Python scripts.

pip install pylint
pylint do_stuff.py
  • yamllint: YAML is unavoidable as a configration staple in tons of modern software. It gets heaps of praise for its readability. I appreciated yamllint's instrospective linter when trying to figure out why my YAML config was broken.

Lint your YAML files.

pip install --user yamllint
yamllint config.yaml
yamllint YAML linting CLI tool
  • rstfmt and restructuredtext-lint (read more): Both of these reStructuredText format linter libaries offer code reformatting and linting abilities for reStructuredText files (.rst). I favored restructuredtext-lint, due to its rst-lint CLI tool. I used it to fix and tested it on old posts from this blog. Beware that using a reformatter might surface buried errors found by linting the RST, which you'll need to resolve by reading somewhat cryptic RST error messages given by your linter like "hyperlink mismatch, 1 reference but 0 targets". At least the line number is provided so you have a relative scope of where the error is coming from. rstfmt is another Python CLI tool in this space. One note of using these tools is to watch out for unwanted changes. One effect I saw was having code blocks auto-converted from Python formatting to regular code formatting.

Lint and reformat your .rst documents.

pip install restructuredtext-lint
rst-lint post.rst

Pelican + .rst or .md

RST is one of two pelican-import command line tool conversion options by the Pelican static site generator library, along with Markdown (.md). RST is the format this blog is composed in. Pelican has linting-like functionality when you run its pelican content command to compile your static site.

Although I haven't used them personally, it's worth mentioning popular libraries like pyflakes and flake8 for linting Python code. ruff supports some of these libraries also. Check out pymarkdownlint for linting Markdown documents. While researching for this post, I even stumbled upon an HTML linting command line tool that exists. html-linter applies linting to your HTML code. Starting to think that behind every seasoned Python programmer is a thick stack of linters! When it comes to fixing and refactoring old documents and code, linters and auto-formatters go hand in hand as invaluable tools.

Lint your Markdown documents.

pip install pymarkdownlnt
pymarkdown scan example.md

Lint your HTML documents.

pip install html-linter
html_lint.py filename.html

Supplementary Reading + Documentation

7 Python libraries for more maintainable code

reStructuredText documentation

sqlfluff CLI documentation reference