Summary

The lintquarto package enables you to run a range of linters, formatters, static type checkers and code analysis tools on python code in Quarto .qmd files.

This page provides an overview of the available tools.

Use the sidebar to explore ready-to-run examples and detailed usage for each tool.


General linters

Tool Description
flake8 Lightweight tool focused on PEP-8 style, basic errors, and code complexity.
pycodestyle Checks against PEP-8 style guidelines.
pydoclint Docstring linter.
pyflakes Checks for logical errors like undefined names and unused imports.
pylint Detailed linter that detects errors, bugs, variable naming issues, and other code problems.
ruff Modern, ultra-fast linter that implements checks from Flake8 and some other popular plugins.

Formatters

Tool Description
ruff Modern, ultra-fast formatter that implements checks from Flake8 and some other popular plugins.

Static type checkers

Tool Description
basedpyright Community fork of pyright with extra checks.
mypy Python’s popular static type checker.
pyrefly Meta’s Rust-based static type checker (successor to Pyre).
pyright Microsoft’s static type checker.
pytype Google’s static type checker.

Code analysis tools

Tool Description
vulture Finds unused/dead code.
radon Calculates complexity, maintainability, raw statistics, and Halstead metrics.


Known limitation: config files

Config files are supported, but they have a limitation similar to nbqa: filenames must use the .py extension.

When lintquarto runs, it creates a temporary .py copy of each file - for example, mypage.qmd becomes mypage.py. If a file with the same name already exists, it creates a variant like mypage_1.py (via the get_unique_filename() function). In the config file, entries should use a pattern that matches possible duplicates using *.py.

For example, to run flake8 on mypage.qmd but disable the C0103 (invalid-name) warning, the .flake8 file must be written as:

[flake8]
per-file-ignores =
    mypage*.py: C0103


Applying rules only to .qmd files

If you want linting rules to apply only to code extracted from Quarto .qmd files (and not to your other .py files), organise them by directory.

Place your Quarto files in a dedicated directory and configure your linter to apply specific rules to that directory. For example:

[tool.ruff]
lint.per-file-ignores."docs/*" = [
    "E402"
]

lintquarto does not support passing tool-specific flags (as used in nbqa). This is a deliberate design choice to keep the interface simple and consistent across tools, as not all linters support inline flags. Instead, configuration should be handled via standard linter config files using directory-based rules. See discussion: https://github.com/lintquarto/lintquarto/issues/136.