# Ruff [![image](https://img.shields.io/pypi/v/ruff.svg)](https://pypi.python.org/pypi/ruff) [![image](https://img.shields.io/pypi/l/ruff.svg)](https://pypi.python.org/pypi/ruff) [![image](https://img.shields.io/pypi/pyversions/ruff.svg)](https://pypi.python.org/pypi/ruff) [![Actions status](https://github.com/charliermarsh/ruff/workflows/CI/badge.svg)](https://github.com/charliermarsh/ruff/actions) An extremely fast Python linter, written in Rust.

Bar chart with benchmark results

Linting the CPython codebase from scratch.

- ⚡️ 10-100x faster than existing linters - 🐍 Installable via `pip` - 🤝 Python 3.10 compatibility - 🛠️ `pyproject.toml` support - 📦 Built-in caching, to avoid re-analyzing unchanged files - 🔧 `--fix` support, for automatic error correction (e.g., automatically remove unused imports) - 👀 `--watch` support, for continuous file monitoring - ⚖️ [Near-parity](#how-does-ruff-compare-to-flake8) with the built-in Flake8 rule set - 🔌 Native re-implementations of popular Flake8 plugins, like [`flake8-docstrings`](https://pypi.org/project/flake8-docstrings/) ([`pydocstyle`](https://pypi.org/project/pydocstyle/)) Ruff aims to be orders of magnitude faster than alternative tools while integrating more functionality behind a single, common interface. Ruff can be used to replace Flake8 (plus a variety of plugins), [`isort`](https://pypi.org/project/isort/), [`pydocstyle`](https://pypi.org/project/pydocstyle/), [`yesqa`](https://github.com/asottile/yesqa), and even a subset of [`pyupgrade`](https://pypi.org/project/pyupgrade/) and [`autoflake`](https://pypi.org/project/autoflake/) all while executing tens or hundreds of times faster than any individual tool. (Coming from Flake8? Try [`flake8-to-ruff`](https://pypi.org/project/flake8-to-ruff/) to automatically convert your existing configuration.) Ruff is actively developed and used in major open-source projects like [FastAPI](https://github.com/tiangolo/fastapi), [Zulip](https://github.com/zulip/zulip), [pydantic](https://github.com/pydantic/pydantic), and [Saleor](https://github.com/saleor/saleor). Read the [launch blog post](https://notes.crmarsh.com/python-tooling-could-be-much-much-faster). ## Table of Contents 1. [Installation and Usage](#installation-and-usage) 1. [Configuration](#configuration) 1. [Supported Rules](#supported-rules) 1. [Pyflakes (F)](#pyflakes) 1. [pycodestyle (E)](#pycodestyle) 1. [isort (I)](#isort) 1. [pydocstyle (D)](#pydocstyle) 1. [pyupgrade (U)](#pyupgrade) 1. [pep8-naming (N)](#pep8-naming) 1. [flake8-bandit (S)](#flake8-bandit) 1. [flake8-comprehensions (C)](#flake8-comprehensions) 1. [flake8-bugbear (B)](#flake8-bugbear) 1. [flake8-builtins (A)](#flake8-builtins) 1. [flake8-tidy-imports (I25)](#flake8-tidy-imports) 1. [flake8-print (T)](#flake8-print) 1. [flake8-quotes (Q)](#flake8-quotes) 1. [flake8-annotations (ANN)](#flake8-annotations) 1. [flake8-2020 (YTT)](#flake8-2020) 1. [flake8-blind-except (BLE)](#flake8-blind-except) 1. [flake8-boolean-trap (FBT)](#flake8-boolean-trap) 1. [mccabe (C90)](#mccabe) 1. [Ruff-specific rules (RUF)](#ruff-specific-rules) 1. [Meta rules (M)](#meta-rules) 1. [Editor Integrations](#editor-integrations) 1. [FAQ](#faq) 1. [Development](#development) 1. [Releases](#releases) 1. [Benchmarks](#benchmarks) 1. [License](#license) 1. [Contributing](#contributing) ## Installation and Usage ### Installation Available as [`ruff`](https://pypi.org/project/ruff/) on PyPI: ```shell pip install ruff ``` ### Usage To run Ruff, try any of the following: ```shell ruff path/to/code/to/check.py ruff path/to/code/ ruff path/to/code/*.py ``` You can run Ruff in `--watch` mode to automatically re-run on-change: ```shell ruff path/to/code/ --watch ``` Ruff also works with [pre-commit](https://pre-commit.com): ```yaml repos: - repo: https://github.com/charliermarsh/ruff-pre-commit rev: v0.0.116 hooks: - id: ruff ``` _Note: prior to `v0.0.86`, `ruff-pre-commit` used `lint` (rather than `ruff`) as the hook ID._ ## Configuration Ruff is configurable both via `pyproject.toml` and the command line. If left unspecified, the default configuration is equivalent to: ```toml [tool.ruff] line-length = 88 # Enable Flake's "E" and "F" codes by default. select = ["E", "F"] ignore = [] # Exclude a variety of commonly ignored directories. exclude = [ ".bzr", ".direnv", ".eggs", ".git", ".hg", ".mypy_cache", ".nox", ".pants.d", ".ruff_cache", ".svn", ".tox", ".venv", "__pypackages__", "_build", "buck-out", "build", "dist", "node_modules", "venv", ] per-file-ignores = {} # Allow unused variables when underscore-prefixed. dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" # Assume Python 3.10. target-version = "py310" ``` As an example, the following would configure Ruff to (1) avoid checking for line-length violations (`E501`) and (2) ignore unused import rules in `__init__.py` files: ```toml [tool.ruff] select = ["E", "F"] # Never enforce `E501`. ignore = ["E501"] # Ignore `F401` violations in any `__init__.py` file, and in `path/to/file.py`. per-file-ignores = {"__init__.py" = ["F401"], "path/to/file.py" = ["F401"]} ``` Plugin configurations should be expressed as subsections, e.g.: ```toml [tool.ruff] # Add "Q" to the list of enabled codes. select = ["E", "F", "Q"] [tool.ruff.flake8-quotes] docstring-quotes = "double" ``` Alternatively, common configuration settings can be provided via the command-line: ```shell ruff path/to/code/ --select F401 --select F403 ``` See `ruff --help` for more: ```shell Ruff: An extremely fast Python linter. Usage: ruff [OPTIONS] ... Arguments: ... Options: --config Path to the `pyproject.toml` file to use for configuration -v, --verbose Enable verbose logging -q, --quiet Only log errors -s, --silent Disable all logging (but still exit with status code "1" upon detecting errors) -e, --exit-zero Exit with status code "0", even upon detecting errors -w, --watch Run in watch mode by re-running whenever files change --fix Attempt to automatically fix lint errors -n, --no-cache Disable cache reads --select