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: C0103Applying 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.