Skip to main content

An extremely fast Python linter and code formatter, written in Rust.

Project description

Ruff

Ruff image image image Actions status Discord

Docs | Playground

An extremely fast Python linter and code formatter, written in Rust.

Shows a bar chart with benchmark results.

Linting the CPython codebase from scratch.

  • ⚡️ 10-100x faster than existing linters (like Flake8) and formatters (like Black)
  • 🐍 Installable via pip
  • 🛠️ pyproject.toml support
  • 🤝 Python 3.12 compatibility
  • ⚖️ Drop-in parity with Flake8, isort, and Black
  • 📦 Built-in caching, to avoid re-analyzing unchanged files
  • 🔧 Fix support, for automatic error correction (e.g., automatically remove unused imports)
  • 📏 Over 700 built-in rules, with native re-implementations of popular Flake8 plugins, like flake8-bugbear
  • ⌨️ First-party editor integrations for VS Code and more
  • 🌎 Monorepo-friendly, with hierarchical and cascading configuration

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 dozens of plugins), Black, isort, pydocstyle, pyupgrade, autoflake, and more, all while executing tens or hundreds of times faster than any individual tool.

Ruff is extremely actively developed and used in major open-source projects like:

...and many more.

Ruff is backed by Astral. Read the launch post, or the original project announcement.

Testimonials

Sebastián Ramírez, creator of FastAPI:

Ruff is so fast that sometimes I add an intentional bug in the code just to confirm it's actually running and checking the code.

Nick Schrock, founder of Elementl, co-creator of GraphQL:

Why is Ruff a gamechanger? Primarily because it is nearly 1000x faster. Literally. Not a typo. On our largest module (dagster itself, 250k LOC) pylint takes about 2.5 minutes, parallelized across 4 cores on my M1. Running ruff against our entire codebase takes .4 seconds.

Bryan Van de Ven, co-creator of Bokeh, original author of Conda:

Ruff is ~150-200x faster than flake8 on my machine, scanning the whole repo takes ~0.2s instead of ~20s. This is an enormous quality of life improvement for local dev. It's fast enough that I added it as an actual commit hook, which is terrific.

Timothy Crosley, creator of isort:

Just switched my first project to Ruff. Only one downside so far: it's so fast I couldn't believe it was working till I intentionally introduced some errors.

Tim Abbott, lead developer of Zulip:

This is just ridiculously fast... ruff is amazing.

Table of Contents

For more, see the documentation.

  1. Getting Started
  2. Configuration
  3. Rules
  4. Contributing
  5. Support
  6. Acknowledgements
  7. Who's Using Ruff?
  8. License

Getting Started

For more, see the documentation.

Installation

Ruff is available as ruff on PyPI:

pip install ruff

You can also install Ruff via Homebrew, Conda, and with a variety of other package managers.

Usage

To run Ruff as a linter, try any of the following:

ruff check .                        # Lint all files in the current directory (and any subdirectories).
ruff check path/to/code/            # Lint all files in `/path/to/code` (and any subdirectories).
ruff check path/to/code/*.py        # Lint all `.py` files in `/path/to/code`.
ruff check path/to/code/to/file.py  # Lint `file.py`.
ruff check @arguments.txt           # Lint using an input file, treating its contents as newline-delimited command-line arguments.

Or, to run Ruff as a formatter:

ruff format .                        # Format all files in the current directory (and any subdirectories).
ruff format path/to/code/            # Format all files in `/path/to/code` (and any subdirectories).
ruff format path/to/code/*.py        # Format all `.py` files in `/path/to/code`.
ruff format path/to/code/to/file.py  # Format `file.py`.
ruff format @arguments.txt           # Format using an input file, treating its contents as newline-delimited command-line arguments.

Ruff can also be used as a pre-commit hook via ruff-pre-commit:

- repo: https://github.com/astral-sh/ruff-pre-commit
  # Ruff version.
  rev: v0.3.1
  hooks:
    # Run the linter.
    - id: ruff
      args: [ --fix ]
    # Run the formatter.
    - id: ruff-format

Ruff can also be used as a VS Code extension or alongside any other editor through the Ruff LSP.

Ruff can also be used as a GitHub Action via ruff-action:

name: Ruff
on: [ push, pull_request ]
jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: chartboost/ruff-action@v1

Configuration

Ruff can be configured through a pyproject.toml, ruff.toml, or .ruff.toml file (see: Configuration, or Settings for a complete list of all configuration options).

If left unspecified, Ruff's default configuration is equivalent to:

[tool.ruff]
# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".git-rewrite",
    ".hg",
    ".ipynb_checkpoints",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pyenv",
    ".pytest_cache",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    ".vscode",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "site-packages",
    "venv",
]

# Same as Black.
line-length = 88
indent-width = 4

# Assume Python 3.8
target-version = "py38"

[tool.ruff.lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`)  codes by default.
select = ["E4", "E7", "E9", "F"]
ignore = []

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[tool.ruff.format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"

Some configuration options can be provided via the command-line, such as those related to rule enablement and disablement, file discovery, and logging level:

ruff check path/to/code/ --select F401 --select F403 --quiet

See ruff help for more on Ruff's top-level commands, or ruff help check and ruff help format for more on the linting and formatting commands, respectively.

Rules

Ruff supports over 700 lint rules, many of which are inspired by popular tools like Flake8, isort, pyupgrade, and others. Regardless of the rule's origin, Ruff re-implements every rule in Rust as a first-party feature.

By default, Ruff enables Flake8's F rules, along with a subset of the E rules, omitting any stylistic rules that overlap with the use of a formatter, like ruff format or Black.

If you're just getting started with Ruff, the default rule set is a great place to start: it catches a wide variety of common errors (like unused imports) with zero configuration.

Beyond the defaults, Ruff re-implements some of the most popular Flake8 plugins and related code quality tools, including:

For a complete enumeration of the supported rules, see Rules.

Contributing

Contributions are welcome and highly appreciated. To get started, check out the contributing guidelines.

You can also join us on Discord.

Support

Having trouble? Check out the existing issues on GitHub, or feel free to open a new one.

You can also ask for help on Discord.

Acknowledgements

Ruff's linter draws on both the APIs and implementation details of many other tools in the Python ecosystem, especially Flake8, Pyflakes, pycodestyle, pydocstyle, pyupgrade, and isort.

In some cases, Ruff includes a "direct" Rust port of the corresponding tool. We're grateful to the maintainers of these tools for their work, and for all the value they've provided to the Python community.

Ruff's formatter is built on a fork of Rome's rome_formatter, and again draws on both API and implementation details from Rome, Prettier, and Black.

Ruff's import resolver is based on the import resolution algorithm from Pyright.

Ruff is also influenced by a number of tools outside the Python ecosystem, like Clippy and ESLint.

Ruff is the beneficiary of a large number of contributors.

Ruff is released under the MIT license.

Who's Using Ruff?

Ruff is used by a number of major open-source projects and companies, including:

Show Your Support

If you're using Ruff, consider adding the Ruff badge to your project's README.md:

[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)

...or README.rst:

.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
    :target: https://github.com/astral-sh/ruff
    :alt: Ruff

...or, as HTML:

<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff" style="max-width:100%;"></a>

License

MIT

Project details


Release history Release notifications | RSS feed

This version

0.3.1

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ruff-0.3.1.tar.gz (2.1 MB view details)

Uploaded Source

Built Distributions

ruff-0.3.1-py3-none-win_arm64.whl (7.2 MB view details)

Uploaded Python 3Windows ARM64

ruff-0.3.1-py3-none-win_amd64.whl (7.6 MB view details)

Uploaded Python 3Windows x86-64

ruff-0.3.1-py3-none-win32.whl (6.9 MB view details)

Uploaded Python 3Windows x86

ruff-0.3.1-py3-none-musllinux_1_2_x86_64.whl (7.9 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

ruff-0.3.1-py3-none-musllinux_1_2_i686.whl (7.5 MB view details)

Uploaded Python 3musllinux: musl 1.2+ i686

ruff-0.3.1-py3-none-musllinux_1_2_armv7l.whl (6.7 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARMv7l

ruff-0.3.1-py3-none-musllinux_1_2_aarch64.whl (7.3 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

ruff-0.3.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

ruff-0.3.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl (9.0 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ s390x

ruff-0.3.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (8.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ppc64le

ruff-0.3.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl (8.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ppc64

ruff-0.3.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (7.8 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ i686

ruff-0.3.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (6.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

ruff-0.3.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

ruff-0.3.1-py3-none-macosx_10_12_x86_64.whl (7.7 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

ruff-0.3.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (15.0 MB view details)

Uploaded Python 3macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file ruff-0.3.1.tar.gz.

File metadata

  • Download URL: ruff-0.3.1.tar.gz
  • Upload date:
  • Size: 2.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for ruff-0.3.1.tar.gz
Algorithm Hash digest
SHA256 d30db97141fc2134299e6e983a6727922c9e03c031ae4883a6d69461de722ae7
MD5 47f92728f74e1318a05c189164d5ff84
BLAKE2b-256 34c6db775c2364481569dc240efad15da4cc48698484751bd4c469c39a53e099

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-win_arm64.whl.

File metadata

  • Download URL: ruff-0.3.1-py3-none-win_arm64.whl
  • Upload date:
  • Size: 7.2 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for ruff-0.3.1-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 d3b60e44240f7e903e6dbae3139a65032ea4c6f2ad99b6265534ff1b83c20afa
MD5 fd17129942772774ce82795141d048a4
BLAKE2b-256 6946f848efd374c98729e3c56a12e47f0ca346740145c11d895e72eb9f3f98fe

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: ruff-0.3.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 7.6 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for ruff-0.3.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 c0318a512edc9f4e010bbaab588b5294e78c5cdc9b02c3d8ab2d77c7ae1903e3
MD5 8f85eee58346611cc021d278c32c8c40
BLAKE2b-256 fe3b5ba9e5e57046922e4b252a665e210ca315396c4164ceb5da2f404e477ef9

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-win32.whl.

File metadata

  • Download URL: ruff-0.3.1-py3-none-win32.whl
  • Upload date:
  • Size: 6.9 MB
  • Tags: Python 3, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for ruff-0.3.1-py3-none-win32.whl
Algorithm Hash digest
SHA256 d937f9b99ebf346e0606c3faf43c1e297a62ad221d87ef682b5bdebe199e01f6
MD5 8895e632768409f1bf193eadfa276917
BLAKE2b-256 f8f4ef9529212a1e847201b62b5fe16436bf75ebc6468c8ff418e17190087cf0

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: ruff-0.3.1-py3-none-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 7.9 MB
  • Tags: Python 3, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for ruff-0.3.1-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 09c7333b25e983aabcf6e38445252cff0b4745420fc3bda45b8fce791cc7e9ce
MD5 32bfdfc1954c6975795a3f7a464a8635
BLAKE2b-256 7687c21afc336f56ccbe49e89cc6a13e3d1181a13d930b871fe0ca45ef4f7015

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-musllinux_1_2_i686.whl.

File metadata

  • Download URL: ruff-0.3.1-py3-none-musllinux_1_2_i686.whl
  • Upload date:
  • Size: 7.5 MB
  • Tags: Python 3, musllinux: musl 1.2+ i686
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for ruff-0.3.1-py3-none-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 951efb610c5844e668bbec4f71cf704f8645cf3106e13f283413969527ebfded
MD5 9e8a39f6d6c2ae68a06864fb4cfa8074
BLAKE2b-256 31ca7077ca35abec45b1b3501afcfba5e0f7c3742628d8eb4d36951b7ce6adb8

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-musllinux_1_2_armv7l.whl.

File metadata

  • Download URL: ruff-0.3.1-py3-none-musllinux_1_2_armv7l.whl
  • Upload date:
  • Size: 6.7 MB
  • Tags: Python 3, musllinux: musl 1.2+ ARMv7l
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for ruff-0.3.1-py3-none-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 54e5dca3e411772b51194b3102b5f23b36961e8ede463776b289b78180df71a0
MD5 659ff1a3462d7cfef73cd04213d6a933
BLAKE2b-256 5fe83d1ae6a128d9d3d59a6cdb472a06760c594fc26dd53f9e72e9a0179012c9

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 11b5699c42f7d0b771c633d620f2cb22e727fb226273aba775a91784a9ed856c
MD5 8be6c3bf7be0f5561412cac1b30a8fb9
BLAKE2b-256 319e16d9c50df43dedcd3983639e328adc240a500e1af0d17039a76457d876a1

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 52b02bb46f1a79b0c1fa93f6495bc7e77e4ef76e6c28995b4974a20ed09c0833
MD5 da9f230567e59448fc6239f1696132d0
BLAKE2b-256 b21494dcb1943449178e1343a5a8651986beea24128934fcfb3b3711317b4e54

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 78a7025e6312cbba496341da5062e7cdd47d95f45c1b903e635cdeb1ba5ec2b9
MD5 79a446074ea41335c60e380fbddc6792
BLAKE2b-256 d58ca490bd9407eaf91a7c1e2347f22836cf7db236aeafb59358ae2fbea851c5

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 434c3fc72e6311c85cd143c4c448b0e60e025a9ac1781e63ba222579a8c29200
MD5 c01d7f66c9cf7f07b2275873b55b33ac
BLAKE2b-256 380ba053235e27ef193e4d0360bb07e1d2b9f847db7c95e17858c6cf5ec71125

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl
Algorithm Hash digest
SHA256 5f0c21b6914c3c9a25a59497cbb1e5b6c2d8d9beecc9b8e03ee986e24eee072e
MD5 7adbf7e60882a7167bc9784047a5292a
BLAKE2b-256 886c1ddf088642398427b391d8821524f21592da7974d96b0d5c731a4fd3a81d

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d6abaad602d6e6daaec444cbf4d9364df0a783e49604c21499f75bb92237d4af
MD5 6e1a206c419daa01448f9aa555ab4fef
BLAKE2b-256 00edde025fd51d2441ed3aba915cf32a22f40d9ef808fef8acb9cbdeee8718cd

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 c78bfa85637668f47bd82aa2ae17de2b34221ac23fea30926f6409f9e37fc927
MD5 b1da7ba9d9183b3a08834397b08c473d
BLAKE2b-256 9e7e62c95020bb4bded1b28fc4de3c0bf3323cc23cc2af82502baa81f19dffa5

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6b730f56ccf91225da0f06cfe421e83b8cc27b2a79393db9c3df02ed7e2bbc01
MD5 8d086ea70b6a5a71dbfd31e713e93e60
BLAKE2b-256 2782b4f37b841ad686af83bc5df322d35f0a372201954e9b94793b9d8dce32a8

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ae7954c8f692b70e6a206087ae3988acc9295d84c550f8d90b66c62424c16771
MD5 8e0e2bf10911aafd02e38d2f987946c0
BLAKE2b-256 a7c11ad1802a8beb9f091591fca4cb09cfc20afba31dd45f67890cc7f277082f

See more details on using hashes here.

File details

Details for the file ruff-0.3.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for ruff-0.3.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 6b82e3937d0d76554cd5796bc3342a7d40de44494d29ff490022d7a52c501744
MD5 91a065e0ebfeffeb3b0d743ed8d882f9
BLAKE2b-256 c4820bbad8b278a39a17dda94fe81efa6e5f3570d7552ceccceb6a1b680b9c81

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page