Skip to main content

Ruff

image image image Actions status

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 with the built-in Flake8 rule set
  • 🔌 Native re-implementations of popular Flake8 plugins, like flake8-docstrings (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, pydocstyle, yesqa, and even a subset of pyupgrade and autoflake all while executing tens or hundreds of times faster than any individual tool.

(Coming from Flake8? Try flake8-to-ruff to automatically convert your existing configuration.)

Ruff is actively developed and used in major open-source projects like FastAPI, Zulip, pydantic, and Saleor.

Read the launch blog post.

Table of Contents

  1. Installation and Usage
  2. Configuration
  3. Supported Rules
    1. Pyflakes
    2. pycodestyle
    3. isort
    4. pydocstyle
    5. pyupgrade
    6. pep8-naming
    7. flake8-bandit
    8. flake8-comprehensions
    9. flake8-bugbear
    10. flake8-builtins
    11. flake8-print
    12. flake8-quotes
    13. flake8-annotations
    14. flake8-2020
    15. Ruff-specific rules
    16. Meta rules
  4. Editor Integrations
  5. FAQ
  6. Development
  7. Releases
  8. Benchmarks
  9. License
  10. Contributing

Installation and Usage

Installation

Available as ruff on PyPI:

pip install ruff

Usage

To run Ruff, try any of the following:

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:

ruff path/to/code/ --watch

Ruff also works with pre-commit:

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:

[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:

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

[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:

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

See ruff --help for more:

ruff: An extremely fast Python linter.

Usage: ruff [OPTIONS] <FILES>...

Arguments:
  <FILES>...

Options:
      --config <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 <SELECT>
          List of error codes to enable
      --extend-select <EXTEND_SELECT>
          Like --select, but adds additional error codes on top of the selected ones
      --ignore <IGNORE>
          List of error codes to ignore
      --extend-ignore <EXTEND_IGNORE>
          Like --ignore, but adds additional error codes on top of the ignored ones
      --exclude <EXCLUDE>
          List of paths, used to exclude files and/or directories from checks
      --extend-exclude <EXTEND_EXCLUDE>
          Like --exclude, but adds additional files and directories on top of the excluded ones
      --per-file-ignores <PER_FILE_IGNORES>
          List of mappings from file pattern to code to exclude
      --format <FORMAT>
          Output serialization format for error messages [default: text] [possible values: text, json]
      --show-files
          See the files ruff will be run against with the current settings
      --show-settings
          See ruff's settings
      --add-noqa
          Enable automatic additions of noqa directives to failing lines
      --dummy-variable-rgx <DUMMY_VARIABLE_RGX>
          Regular expression matching the name of dummy variables
      --target-version <TARGET_VERSION>
          The minimum Python version that should be supported
      --line-length <LINE_LENGTH>
          Set the line-length for length-associated checks and automatic formatting
      --stdin-filename <STDIN_FILENAME>
          The name of the file when passing it through stdin
  -h, --help
          Print help information
  -V, --version
          Print version information

Excluding files

Exclusions are based on globs, and can be either:

  • Single-path patterns, like .mypy_cache (to exclude any directory named .mypy_cache in the tree), foo.py (to exclude any file named foo.py), or foo_*.py (to exclude any file matching foo_*.py ).
  • Relative patterns, like directory/foo.py (to exclude that specific file) or directory/*.py (to exclude any Python files in directory). Note that these paths are relative to the project root (e.g., the directory containing your pyproject.toml).

Ignoring errors

To omit a lint check entirely, add it to the "ignore" list via --ignore or --extend-ignore, either on the command-line or in your project.toml file.

To ignore an error in-line, Ruff uses a noqa system similar to Flake8. To ignore an individual error, add # noqa: {code} to the end of the line, like so:

# Ignore F841.
x = 1  # noqa: F841

# Ignore E741 and F841.
i = 1  # noqa: E741, F841

# Ignore _all_ errors.
x = 1  # noqa

Note that, for multi-line strings, the noqa directive should come at the end of the string, and will apply to the entire body, like so:

"""Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
"""  # noqa: E501

Ruff supports several workflows to aid in noqa management.

First, Ruff provides a special error code, M001, to enforce that your noqa directives are "valid", in that the errors they say they ignore are actually being triggered on that line (and thus suppressed). You can run ruff /path/to/file.py --extend-select M001 to flag unused noqa directives.

Second, Ruff can automatically remove unused noqa directives via its autofix functionality. You can run ruff /path/to/file.py --extend-select M001 --fix to automatically remove unused noqa directives.

Third, Ruff can automatically add noqa directives to all failing lines. This is useful when migrating a new codebase to Ruff. You can run ruff /path/to/file.py --add-noqa to automatically add noqa directives to all failing lines, with the appropriate error codes.

Supported Rules

Regardless of the rule's origin, Ruff re-implements every rule in Rust as a first-party feature.

By default, Ruff enables all E and F error codes, which correspond to those built-in to Flake8.

The 🛠 emoji indicates that a rule is automatically fixable by the --fix command-line option.

Pyflakes

For more, see Pyflakes on PyPI.

Code Name Message Fix
F401 UnusedImport ... imported but unused 🛠
F402 ImportShadowedByLoopVar Import ... from line 1 shadowed by loop variable
F403 ImportStarUsed from ... import * used; unable to detect undefined names
F404 LateFutureImport from __future__ imports must occur at the beginning of the file
F405 ImportStarUsage ... may be undefined, or defined from star imports: ...
F406 ImportStarNotPermitted from ... import * only allowed at module level
F407 FutureFeatureNotDefined Future feature ... is not defined
F541 FStringMissingPlaceholders f-string without any placeholders
F601 MultiValueRepeatedKeyLiteral Dictionary key literal repeated
F602 MultiValueRepeatedKeyVariable Dictionary key ... repeated
F621 ExpressionsInStarAssignment Too many expressions in star-unpacking assignment
F622 TwoStarredExpressions Two starred expressions in assignment
F631 AssertTuple Assert test is a non-empty tuple, which is always True
F632 IsLiteral Use == and != to compare constant literals 🛠
F633 InvalidPrintSyntax Use of >> is invalid with print function
F634 IfTuple If test is a tuple, which is always True
F701 BreakOutsideLoop break outside loop
F702 ContinueOutsideLoop continue not properly in loop
F704 YieldOutsideFunction yield or yield from statement outside of a function
F706 ReturnOutsideFunction return statement outside of a function/method
F707 DefaultExceptNotLast An except block as not the last exception handler
F722 ForwardAnnotationSyntaxError Syntax error in forward annotation: ...
F821 UndefinedName Undefined name ...
F822 UndefinedExport Undefined name ... in __all__
F823 UndefinedLocal Local variable ... referenced before assignment
F831 DuplicateArgumentName Duplicate argument name in function definition
F841 UnusedVariable Local variable ... is assigned to but never used
F901 RaiseNotImplemented raise NotImplemented should be raise NotImplementedError 🛠

pycodestyle

For more, see pycodestyle on PyPI.

Code Name Message Fix
E402 ModuleImportNotAtTopOfFile Module level import not at top of file
E501 LineTooLong Line too long (89 > 88 characters)
E711 NoneComparison Comparison to None should be cond is None
E712 TrueFalseComparison Comparison to True should be cond is True
E713 NotInTest Test for membership should be not in
E714 NotIsTest Test for object identity should be is not
E721 TypeComparison Do not compare types, use isinstance()
E722 DoNotUseBareExcept Do not use bare except
E731 DoNotAssignLambda Do not assign a lambda expression, use a def
E741 AmbiguousVariableName Ambiguous variable name: ...
E742 AmbiguousClassName Ambiguous class name: ...
E743 AmbiguousFunctionName Ambiguous function name: ...
E902 IOError IOError: ...
E999 SyntaxError SyntaxError: ...
W292 NoNewLineAtEndOfFile No newline at end of file
W605 InvalidEscapeSequence Invalid escape sequence: '\c'

isort

For more, see isort on PyPI.

Code Name Message Fix
I001 UnsortedImports Import block is un-sorted or un-formatted 🛠

pydocstyle

For more, see pydocstyle on PyPI.

Code Name Message Fix
D100 PublicModule Missing docstring in public module
D101 PublicClass Missing docstring in public class
D102 PublicMethod Missing docstring in public method
D103 PublicFunction Missing docstring in public function
D104 PublicPackage Missing docstring in public package
D105 MagicMethod Missing docstring in magic method
D106 PublicNestedClass Missing docstring in public nested class
D107 PublicInit Missing docstring in __init__
D200 FitsOnOneLine One-line docstring should fit on one line
D201 NoBlankLineBeforeFunction No blank lines allowed before function docstring (found 1) 🛠
D202 NoBlankLineAfterFunction No blank lines allowed after function docstring (found 1) 🛠
D203 OneBlankLineBeforeClass 1 blank line required before class docstring 🛠
D204 OneBlankLineAfterClass 1 blank line required after class docstring 🛠
D205 BlankLineAfterSummary 1 blank line required between summary line and description 🛠
D206 IndentWithSpaces Docstring should be indented with spaces, not tabs
D207 NoUnderIndentation Docstring is under-indented 🛠
D208 NoOverIndentation Docstring is over-indented 🛠
D209 NewLineAfterLastParagraph Multi-line docstring closing quotes should be on a separate line 🛠
D210 NoSurroundingWhitespace No whitespaces allowed surrounding docstring text 🛠
D211 NoBlankLineBeforeClass No blank lines allowed before class docstring 🛠
D212 MultiLineSummaryFirstLine Multi-line docstring summary should start at the first line
D213 MultiLineSummarySecondLine Multi-line docstring summary should start at the second line
D214 SectionNotOverIndented Section is over-indented ("Returns") 🛠
D215 SectionUnderlineNotOverIndented Section underline is over-indented ("Returns") 🛠
D300 UsesTripleQuotes Use """triple double quotes"""
D400 EndsInPeriod First line should end with a period
D402 NoSignature First line should not be the function's signature
D403 FirstLineCapitalized First word of the first line should be properly capitalized
D404 NoThisPrefix First word of the docstring should not be "This"
D405 CapitalizeSectionName Section name should be properly capitalized ("returns") 🛠
D406 NewLineAfterSectionName Section name should end with a newline ("Returns") 🛠
D407 DashedUnderlineAfterSection Missing dashed underline after section ("Returns") 🛠
D408 SectionUnderlineAfterName Section underline should be in the line following the section's name ("Returns") 🛠
D409 SectionUnderlineMatchesSectionLength Section underline should match the length of its name ("Returns") 🛠
D410 BlankLineAfterSection Missing blank line after section ("Returns") 🛠
D411 BlankLineBeforeSection Missing blank line before section ("Returns") 🛠
D412 NoBlankLinesBetweenHeaderAndContent No blank lines allowed between a section header and its content ("Returns") 🛠
D413 BlankLineAfterLastSection Missing blank line after last section ("Returns") 🛠
D414 NonEmptySection Section has no content ("Returns")
D415 EndsInPunctuation First line should end with a period, question mark, or exclamation point
D416 SectionNameEndsInColon Section name should end with a colon ("Returns") 🛠
D417 DocumentAllArguments Missing argument descriptions in the docstring: x, y
D418 SkipDocstring Function decorated with @overload shouldn't contain a docstring
D419 NonEmpty Docstring is empty

pyupgrade

For more, see pyupgrade on PyPI.

Code Name Message Fix
U001 UselessMetaclassType __metaclass__ = type is implied 🛠
U002 UnnecessaryAbspath abspath(__file__) is unnecessary in Python 3.9 and later 🛠
U003 TypeOfPrimitive Use str instead of type(...) 🛠
U004 UselessObjectInheritance Class ... inherits from object 🛠
U005 DeprecatedUnittestAlias assertEquals is deprecated, use assertEqual instead 🛠
U006 UsePEP585Annotation Use list instead of List for type annotations 🛠
U007 UsePEP604Annotation Use X | Y for type annotations 🛠
U008 SuperCallWithParameters Use super() instead of super(__class__, self) 🛠
U009 PEP3120UnnecessaryCodingComment UTF-8 encoding declaration is unnecessary 🛠
U010 UnnecessaryFutureImport Unnecessary __future__ import ... for target Python version 🛠
U011 UnnecessaryLRUCacheParams Unnecessary parameters to functools.lru_cache 🛠
U012 UnnecessaryEncodeUTF8 Unnecessary call to encode as UTF-8 🛠

pep8-naming

For more, see pep8-naming on PyPI.

Code Name Message Fix
N801 InvalidClassName Class name ... should use CapWords convention
N802 InvalidFunctionName Function name ... should be lowercase
N803 InvalidArgumentName Argument name ... should be lowercase
N804 InvalidFirstArgumentNameForClassMethod First argument of a class method should be named cls
N805 InvalidFirstArgumentNameForMethod First argument of a method should be named self
N806 NonLowercaseVariableInFunction Variable ... in function should be lowercase
N807 DunderFunctionName Function name should not start and end with __
N811 ConstantImportedAsNonConstant Constant ... imported as non-constant ...
N812 LowercaseImportedAsNonLowercase Lowercase ... imported as non-lowercase ...
N813 CamelcaseImportedAsLowercase Camelcase ... imported as lowercase ...
N814 CamelcaseImportedAsConstant Camelcase ... imported as constant ...
N815 MixedCaseVariableInClassScope Variable mixedCase in class scope should not be mixedCase
N816 MixedCaseVariableInGlobalScope Variable mixedCase in global scope should not be mixedCase
N817 CamelcaseImportedAsAcronym Camelcase ... imported as acronym ...
N818 ErrorSuffixOnExceptionName Exception name ... should be named with an Error suffix

flake8-bandit

For more, see flake8-bandit on PyPI.

Code Name Message Fix
S101 AssertUsed Use of assert detected
S102 ExecUsed Use of exec detected
S104 HardcodedBindAllInterfaces Possible binding to all interfaces
S105 HardcodedPasswordString Possible hardcoded password: "..."
S106 HardcodedPasswordFuncArg Possible hardcoded password: "..."
S107 HardcodedPasswordDefault Possible hardcoded password: "..."

flake8-comprehensions

For more, see flake8-comprehensions on PyPI.

Code Name Message Fix
C400 UnnecessaryGeneratorList Unnecessary generator (rewrite as a list comprehension) 🛠
C401 UnnecessaryGeneratorSet Unnecessary generator (rewrite as a set comprehension) 🛠
C402 UnnecessaryGeneratorDict Unnecessary generator (rewrite as a dict comprehension) 🛠
C403 UnnecessaryListComprehensionSet Unnecessary list comprehension (rewrite as a set comprehension) 🛠
C404 UnnecessaryListComprehensionDict Unnecessary list comprehension (rewrite as a dict comprehension) 🛠
C405 UnnecessaryLiteralSet Unnecessary (list|tuple) literal (rewrite as a set literal) 🛠
C406 UnnecessaryLiteralDict Unnecessary (list|tuple) literal (rewrite as a dict literal) 🛠
C408 UnnecessaryCollectionCall Unnecessary (dict|list|tuple) call (rewrite as a literal) 🛠
C409 UnnecessaryLiteralWithinTupleCall Unnecessary (list|tuple) literal passed to tuple() (remove the outer call to tuple()) 🛠
C410 UnnecessaryLiteralWithinListCall Unnecessary (list|tuple) literal passed to list() (rewrite as a list literal) 🛠
C411 UnnecessaryListCall Unnecessary list call (remove the outer call to list()) 🛠
C413 UnnecessaryCallAroundSorted Unnecessary (list|reversed) call around sorted()
C414 UnnecessaryDoubleCastOrProcess Unnecessary (list|reversed|set|sorted|tuple) call within (list|set|sorted|tuple)()
C415 UnnecessarySubscriptReversal Unnecessary subscript reversal of iterable within (reversed|set|sorted)()
C416 UnnecessaryComprehension Unnecessary (list|set) comprehension (rewrite using (list|set)()) 🛠
C417 UnnecessaryMap Unnecessary map usage (rewrite using a (list|set|dict) comprehension)

flake8-bugbear

For more, see flake8-bugbear on PyPI.

Code Name Message Fix
B002 UnaryPrefixIncrement Python does not support the unary prefix increment
B003 AssignmentToOsEnviron Assigning to os.environ doesn't clear the environment
B004 UnreliableCallableCheck Using hasattr(x, '__call__') to test if x is callable is unreliable. Use callable(x) for consistent results.
B005 StripWithMultiCharacters Using .strip() with multi-character strings is misleading the reader
B006 MutableArgumentDefault Do not use mutable data structures for argument defaults
B007 UnusedLoopControlVariable Loop control variable i not used within the loop body 🛠
B008 FunctionCallArgumentDefault Do not perform function call in argument defaults
B009 GetAttrWithConstant Do not call getattr with a constant attribute value. It is not any safer than normal property access. 🛠
B010 SetAttrWithConstant Do not call setattr with a constant attribute value. It is not any safer than normal property access.
B011 DoNotAssertFalse Do not assert False (python -O removes these calls), raise AssertionError() 🛠
B012 JumpStatementInFinally return/continue/break inside finally blocks cause exceptions to be silenced
B013 RedundantTupleInExceptionHandler A length-one tuple literal is redundant. Write except ValueError instead of except (ValueError,).
B014 DuplicateHandlerException Exception handler with duplicate exception: ValueError 🛠
B015 UselessComparison Pointless comparison. This comparison does nothing but waste CPU instructions. Either prepend assert or remove it.
B016 CannotRaiseLiteral Cannot raise a literal. Did you intend to return it or raise an Exception?
B017 NoAssertRaisesException assertRaises(Exception) should be considered evil
B018 UselessExpression Found useless expression. Either assign it to a variable or remove it.
B019 CachedInstanceMethod Use of functools.lru_cache or functools.cache on methods can lead to memory leaks
B020 LoopVariableOverridesIterator Loop control variable ... overrides iterable it iterates
B021 FStringDocstring f-string used as docstring. This will be interpreted by python as a joined string rather than a docstring.
B022 UselessContextlibSuppress No arguments passed to contextlib.suppress. No exceptions will be suppressed and therefore this context manager is redundant
B024 AbstractBaseClassWithoutAbstractMethod ... is an abstract base class, but it has no abstract methods
B025 DuplicateTryBlockException try-except block with duplicate exception Exception
B026 StarArgUnpackingAfterKeywordArg Star-arg unpacking after a keyword argument is strongly discouraged
B027 EmptyMethodWithoutAbstractDecorator ... is an empty method in an abstract base class, but has no abstract decorator

flake8-builtins

For more, see flake8-builtins on PyPI.

Code Name Message Fix
A001 BuiltinVariableShadowing Variable ... is shadowing a python builtin
A002 BuiltinArgumentShadowing Argument ... is shadowing a python builtin
A003 BuiltinAttributeShadowing Class attribute ... is shadowing a python builtin

flake8-print

For more, see flake8-print on PyPI.

Code Name Message Fix
T201 PrintFound print found 🛠
T203 PPrintFound pprint found 🛠

flake8-quotes

For more, see flake8-quotes on PyPI.

Code Name Message Fix
Q000 BadQuotesInlineString Single quotes found but double quotes preferred
Q001 BadQuotesMultilineString Single quote multiline found but double quotes preferred
Q002 BadQuotesDocstring Single quote docstring found but double quotes preferred
Q003 AvoidQuoteEscape Change outer quotes to avoid escaping inner quotes

flake8-annotations

For more, see flake8-annotations on PyPI.

Code Name Message Fix
ANN001 MissingTypeFunctionArgument Missing type annotation for function argument ...
ANN002 MissingTypeArgs Missing type annotation for *...
ANN003 MissingTypeKwargs Missing type annotation for **...
ANN101 MissingTypeSelf Missing type annotation for ... in method
ANN102 MissingTypeCls Missing type annotation for ... in classmethod
ANN201 MissingReturnTypePublicFunction Missing return type annotation for public function ...
ANN202 MissingReturnTypePrivateFunction Missing return type annotation for private function ...
ANN204 MissingReturnTypeMagicMethod Missing return type annotation for magic method ...
ANN205 MissingReturnTypeStaticMethod Missing return type annotation for staticmethod ...
ANN206 MissingReturnTypeClassMethod Missing return type annotation for classmethod ...
ANN401 DynamicallyTypedExpression Dynamically typed expressions (typing.Any) are disallowed in ...

flake8-2020

For more, see flake8-2020 on PyPI.

Code Name Message Fix
YTT101 SysVersionSlice3Referenced sys.version[:3] referenced (python3.10), use sys.version_info
YTT102 SysVersion2Referenced sys.version[2] referenced (python3.10), use sys.version_info
YTT103 SysVersionCmpStr3 sys.version compared to string (python3.10), use sys.version_info
YTT201 SysVersionInfo0Eq3Referenced sys.version_info[0] == 3 referenced (python4), use >=
YTT202 SixPY3Referenced six.PY3 referenced (python4), use not six.PY2
YTT203 SysVersionInfo1CmpInt sys.version_info[1] compared to integer (python4), compare sys.version_info to tuple
YTT204 SysVersionInfoMinorCmpInt sys.version_info.minor compared to integer (python4), compare sys.version_info to tuple
YTT301 SysVersion0Referenced sys.version[0] referenced (python10), use sys.version_info
YTT302 SysVersionCmpStr10 sys.version compared to string (python10), use sys.version_info
YTT303 SysVersionSlice1Referenced sys.version[:1] referenced (python10), use sys.version_info

Ruff-specific rules

Code Name Message Fix
RUF001 AmbiguousUnicodeCharacterString String contains ambiguous unicode character '𝐁' (did you mean 'B'?) 🛠
RUF002 AmbiguousUnicodeCharacterDocstring Docstring contains ambiguous unicode character '𝐁' (did you mean 'B'?) 🛠
RUF003 AmbiguousUnicodeCharacterComment Comment contains ambiguous unicode character '𝐁' (did you mean 'B'?)

Meta rules

Code Name Message Fix
M001 UnusedNOQA Unused noqa directive 🛠

Editor Integrations

VS Code (Official)

Download the Ruff VS Code extension.

PyCharm

Ruff can be installed as an External Tool in PyCharm. Open the Preferences pane, then navigate to "Tools", then "External Tools". From there, add a new tool with the following configuration:

Install Ruff as an External Tool

Ruff should then appear as a runnable action:

Ruff as a runnable action

Vim & Neovim (Unofficial)

Ruff is available as part of the coc-pyright extension for coc.nvim.

Ruff can also be integrated via efm in just a few lines.

Language Server Protocol (Unofficial)

ruffd is a Rust-based language server for Ruff that implements the Language Server Protocol (LSP).

GitHub Actions

GitHub Actions has everything you need to run Ruff out-of-the-box:

name: CI
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install ruff
      - name: Run Ruff
        run: ruff .

FAQ

Is Ruff compatible with Black?

Yes. Ruff is compatible with Black out-of-the-box, as long as the line-length setting is consistent between the two.

As a project, Ruff is designed to be used alongside Black and, as such, will defer implementing stylistic lint rules that are obviated by autoformatting.

How does Ruff compare to Flake8?

(Coming from Flake8? Try flake8-to-ruff to automatically convert your existing configuration.)

Ruff can be used as a (near) drop-in replacement for Flake8 when used (1) without or with a small number of plugins, (2) alongside Black, and (3) on Python 3 code.

Under those conditions Ruff is missing 14 rules related to string .format calls, 1 rule related to docstring parsing, and 1 rule related to redefined variables.

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

Beyond rule-set parity, Ruff suffers from the following limitations vis-à-vis Flake8:

  1. Ruff does not yet support a few Python 3.9 and 3.10 language features, including structural pattern matching and parenthesized context managers.
  2. Flake8 has a plugin architecture and supports writing custom lint rules. (To date, popular Flake8 plugins have been re-implemented within Ruff directly.)

Which tools does Ruff replace?

Today, Ruff can be used to replace Flake8 when used with any of the following plugins:

Ruff can also replace isort, yesqa, and a subset of the rules implemented in pyupgrade (15/34).

If you're looking to use Ruff, but rely on an unsupported Flake8 plugin, free to file an Issue.

Do I need to install Rust to use Ruff?

Nope! Ruff is available as ruff on PyPI:

pip install ruff

Ruff ships with wheels for all major platforms, which enables pip to install Ruff without relying on Rust at all.

Can I write my own plugins for Ruff?

Ruff does not yet support third-party plugins, though a plugin system is within-scope for the project. See #283 for more.

How does Ruff's import sorting compare to isort?

Ruff's import sorting is intended to be nearly equivalent to isort when used profile = "black". (There are some minor differences in how Ruff and isort break ties between similar imports.)

Like isort, Ruff's import sorting is compatible with Black.

Ruff is less configurable than isort, but supports the known-first-party, known-third-party, extra-standard-library, and src settings, like so:

[tool.ruff]
select = [
    # Pyflakes
    "F",
    # Pycodestyle
    "E",
    "W",
    # isort
    "I"
]
src = ["src", "tests"]

[tool.ruff.isort]
known-first-party = ["my_module1", "my_module2"]

Does Ruff support NumPy- or Google-style docstrings?

Yes! To enable a specific docstring convention, start by enabling all pydocstyle error codes, and then selectively disabling based on your preferred convention.

For example, if you're coming from flake8-docstrings, the following configuration is equivalent to --docstring-convention=numpy:

[tool.ruff]
extend-select = ["D"]
extend-ignore = [
    "D107",
    "D203",
    "D212",
    "D213",
    "D402",
    "D413",
    "D415",
    "D416",
    "D417",
]

Similarly, the following is equivalent to --docstring-convention=google:

[tool.ruff]
extend-select = ["D"]
extend-ignore = [
    "D203",
    "D204",
    "D213",
    "D215",
    "D400",
    "D404",
    "D406",
    "D407",
    "D408",
    "D409",
    "D413",
]

Similarly, the following is equivalent to --docstring-convention=pep8:

[tool.ruff]
extend-select = ["D"]
extend-ignore = [
    "D203",
    "D212",
    "D213",
    "D214",
    "D215",
    "D404",
    "D405",
    "D406",
    "D407",
    "D408",
    "D409",
    "D410",
    "D411",
    "D413",
    "D415",
    "D416",
    "D417",
]

Development

Ruff is written in Rust (1.65.0). You'll need to install the Rust toolchain for development.

Assuming you have cargo installed, you can run:

cargo run resources/test/fixtures

For development, we use nightly Rust:

cargo +nightly fmt
cargo +nightly clippy
cargo +nightly test

Releases

Ruff is distributed on PyPI, and published via maturin.

See: .github/workflows/release.yaml.

Benchmarks

First, clone CPython. It's a large and diverse Python codebase, which makes it a good target for benchmarking.

git clone --branch 3.10 https://github.com/python/cpython.git resources/test/cpython

Add this pyproject.toml to the CPython directory:

[tool.ruff]
line-length = 88
extend-exclude = [
    "Lib/lib2to3/tests/data/bom.py",
    "Lib/lib2to3/tests/data/crlf.py",
    "Lib/lib2to3/tests/data/different_encoding.py",
    "Lib/lib2to3/tests/data/false_encoding.py",
    "Lib/lib2to3/tests/data/py2_test_grammar.py",
    "Lib/test/bad_coding2.py",
    "Lib/test/badsyntax_3131.py",
    "Lib/test/badsyntax_pep3120.py",
    "Lib/test/encoded_modules/module_iso_8859_1.py",
    "Lib/test/encoded_modules/module_koi8_r.py",
    "Lib/test/test_fstring.py",
    "Lib/test/test_grammar.py",
    "Lib/test/test_importlib/test_util.py",
    "Lib/test/test_named_expressions.py",
    "Lib/test/test_patma.py",
    "Lib/test/test_source_encoding.py",
    "Tools/c-analyzer/c_parser/parser/_delim.py",
    "Tools/i18n/pygettext.py",
    "Tools/test2to3/maintest.py",
    "Tools/test2to3/setup.py",
    "Tools/test2to3/test/test_foo.py",
    "Tools/test2to3/test2to3/hello.py",
]

Next, to benchmark the release build:

cargo build --release

hyperfine --ignore-failure --warmup 10 --runs 100 \
  "./target/release/ruff ./resources/test/cpython/ --no-cache" \
  "./target/release/ruff ./resources/test/cpython/"

Benchmark 1: ./target/release/ruff ./resources/test/cpython/ --no-cache
  Time (mean ± σ):     297.4 ms ±   4.9 ms    [User: 2460.0 ms, System: 67.2 ms]
  Range (min … max):   287.7 ms … 312.1 ms    100 runs

  Warning: Ignoring non-zero exit code.

Benchmark 2: ./target/release/ruff ./resources/test/cpython/
  Time (mean ± σ):      79.6 ms ±   7.3 ms    [User: 59.7 ms, System: 356.1 ms]
  Range (min … max):    62.4 ms … 111.2 ms    100 runs

  Warning: Ignoring non-zero exit code.

To benchmark against the ecosystem's existing tools:

hyperfine --ignore-failure --warmup 5 \
  "./target/release/ruff ./resources/test/cpython/ --no-cache" \
  "pylint --recursive=y resources/test/cpython/" \
  "pyflakes resources/test/cpython" \
  "autoflake --recursive --expand-star-imports --remove-all-unused-imports --remove-unused-variables --remove-duplicate-keys resources/test/cpython" \
  "pycodestyle resources/test/cpython" \
  "flake8 resources/test/cpython" \
  "python -m scripts.run_flake8 resources/test/cpython"

In order, these evaluate:

  • Ruff
  • Pylint
  • Pyflakes
  • autoflake
  • pycodestyle
  • Flake8
  • Flake8, with a hack to enable multiprocessing on macOS

(You can poetry install from ./scripts to create a working environment for the above.)

Benchmark 1: ./target/release/ruff ./resources/test/cpython/ --no-cache
  Time (mean ± σ):     297.9 ms ±   7.0 ms    [User: 2436.6 ms, System: 65.9 ms]
  Range (min … max):   289.9 ms … 314.6 ms    10 runs

  Warning: Ignoring non-zero exit code.

Benchmark 2: pylint --recursive=y resources/test/cpython/
  Time (mean ± σ):     37.634 s ±  0.225 s    [User: 36.728 s, System: 0.853 s]
  Range (min … max):   37.201 s … 38.106 s    10 runs

  Warning: Ignoring non-zero exit code.

Benchmark 3: pyflakes resources/test/cpython
  Time (mean ± σ):     40.950 s ±  0.449 s    [User: 40.688 s, System: 0.229 s]
  Range (min … max):   40.348 s … 41.671 s    10 runs

  Warning: Ignoring non-zero exit code.

Benchmark 4: autoflake --recursive --expand-star-imports --remove-all-unused-imports --remove-unused-variables --remove-duplicate-keys resources/test/cpython
  Time (mean ± σ):     11.562 s ±  0.160 s    [User: 107.022 s, System: 1.143 s]
  Range (min … max):   11.417 s … 11.917 s    10 runs

Benchmark 5: pycodestyle resources/test/cpython
  Time (mean ± σ):     67.428 s ±  0.985 s    [User: 67.199 s, System: 0.203 s]
  Range (min … max):   65.313 s … 68.496 s    10 runs

  Warning: Ignoring non-zero exit code.

Benchmark 6: flake8 resources/test/cpython
  Time (mean ± σ):     116.099 s ±  1.178 s    [User: 115.217 s, System: 0.845 s]
  Range (min … max):   114.180 s … 117.724 s    10 runs

  Warning: Ignoring non-zero exit code.

Benchmark 7: python -m scripts.run_flake8 resources/test/cpython
  Time (mean ± σ):     20.477 s ±  0.349 s    [User: 142.372 s, System: 1.504 s]
  Range (min … max):   20.107 s … 21.183 s    10 runs

Summary
  './target/release/ruff ./resources/test/cpython/ --no-cache' ran
   38.81 ± 1.05 times faster than 'autoflake --recursive --expand-star-imports --remove-all-unused-imports --remove-unused-variables --remove-duplicate-keys resources/test/cpython'
   68.74 ± 1.99 times faster than 'python -m scripts.run_flake8 resources/test/cpython'
  126.33 ± 3.05 times faster than 'pylint --recursive=y resources/test/cpython/'
  137.46 ± 3.55 times faster than 'pyflakes resources/test/cpython'
  226.35 ± 6.23 times faster than 'pycodestyle resources/test/cpython'
  389.73 ± 9.92 times faster than 'flake8 resources/test/cpython'

License

MIT

Contributing

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

Metadata

Release files for ruff 0.0.122

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ruff 0.0.122
File Size Uploaded
ruff-0.0.122.tar.gz 298.2 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for ruff 0.0.122
File
ruff-0.0.122-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
ruff-0.0.122-py3-none-win32.whl Python 3 none Windows x86-32 Details
ruff-0.0.122-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
ruff-0.0.122-py3-none-musllinux_1_2_i686.whl Python 3 none Linux musl 1.2+ x86-32 Details
ruff-0.0.122-py3-none-musllinux_1_2_armv7l.whl Python 3 none Linux musl 1.2+ ARMv7l Details
ruff-0.0.122-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details
ruff-0.0.122-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
ruff-0.0.122-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl Python 3 none Linux glibc 2.17+ IBM System/390x Details
ruff-0.0.122-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl Python 3 none Linux glibc 2.17+ PowerPC 64-le Details
ruff-0.0.122-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl Python 3 none Linux glibc 2.17+ PowerPC 64-be Details
ruff-0.0.122-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl Python 3 none Linux glibc 2.17+ x86-32 Details
ruff-0.0.122-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl Python 3 none Linux glibc 2.17+ ARMv7l Details
ruff-0.0.122-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
ruff-0.0.122-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl Python 3 none macOS 10.9+ universal2 (ARM64, x86-64), macOS 11.0+ ARM64, macOS 10.9+ x86-64 Details
ruff-0.0.122-py3-none-macosx_10_7_x86_64.whl Python 3 none macOS 10.7+ x86-64 Details

Total release size: 52.7 MB

Release files / ruff-0.0.122.tar.gz

Download URL ruff-0.0.122.tar.gz
Size 298.2 kB
Tags Source
SHA-256 checksum
How to use checksums
489be3996a1e7666c63c76168add60e2defa4b00db87e6714f6d2dac32410dcb
BLAKE2b-256 checksum
How to use checksums
693902338b9e4a35107a8f9115ca731b18e4297f13d79fcea21b42644f5dbbf5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-win_amd64.whl

Download URL ruff-0.0.122-py3-none-win_amd64.whl
Size 3.3 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
808985dde7a33614dbec41f508954012bf4a0de752f005e767e07f89eb3c2739
BLAKE2b-256 checksum
How to use checksums
44776dc224237744b9050217bd41325cf6a3022f2742163c499eb79d4fdda311
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-win32.whl

Download URL ruff-0.0.122-py3-none-win32.whl
Size 3.2 MB
Tags Python 3 Windows x86-32
SHA-256 checksum
How to use checksums
8da20810a4e13950a03329e53e7dfb8cb82eb9334e62e0f11f2ceba9f553e350
BLAKE2b-256 checksum
How to use checksums
46f937303d17873649d71fc67d5a1383b3aee4b44a9b9f06fbf4369f11ec43d3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-musllinux_1_2_x86_64.whl

Download URL ruff-0.0.122-py3-none-musllinux_1_2_x86_64.whl
Size 3.6 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
31ecf99b71ca7dcacfd96d61e25412d50405535bb595e5492cac3ae2288b31c7
BLAKE2b-256 checksum
How to use checksums
376c94ffa52f64be0b58d9ce2912911e366f0cd598652c68a2451a937560637c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-musllinux_1_2_i686.whl

Download URL ruff-0.0.122-py3-none-musllinux_1_2_i686.whl
Size 3.5 MB
Tags Linux musl 1.2+ x86-32 Python 3
SHA-256 checksum
How to use checksums
68aaf05595b839797d8b7cd1f631125a5a0376f3738abd6b2c6f531ad0097615
BLAKE2b-256 checksum
How to use checksums
1583939757c100ddfbd05b04e714794c69a9b3a50c860f3a4c95571173c36bf8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-musllinux_1_2_armv7l.whl

Download URL ruff-0.0.122-py3-none-musllinux_1_2_armv7l.whl
Size 3.2 MB
Tags Linux musl 1.2+ ARMv7l Python 3
SHA-256 checksum
How to use checksums
2450e72c9a663144c0b18de89b4c40d597f052ae2adec7a4569d452c83a1a6e7
BLAKE2b-256 checksum
How to use checksums
07ec67e71082d35824400ee543dbb129b3d688b94c1fcc5351a3288bb446425b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-musllinux_1_2_aarch64.whl

Download URL ruff-0.0.122-py3-none-musllinux_1_2_aarch64.whl
Size 3.3 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
0c139e0ba51e4f115955e325d4c6350afdf82da3caaf0129d671757296ef7d86
BLAKE2b-256 checksum
How to use checksums
9ed642af6b07f4b97c170242532e74abdbf98efa904dc349de8646f1a2ecabd0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL ruff-0.0.122-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.5 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
8172cff41c4c71395a7d1689e146964682601b491bb142150c8d5d9ce5438b38
BLAKE2b-256 checksum
How to use checksums
76a920d1a1adbadb568528256c361465cd60b4165a365bc9fe8b58fa3096c33c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl

Download URL ruff-0.0.122-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl
Size 3.4 MB
Tags Linux glibc 2.17+ IBM System/390x Python 3
SHA-256 checksum
How to use checksums
69ac2a9e880ab65ad386675ad64bf17620621375acc2df016eacb22df0096f15
BLAKE2b-256 checksum
How to use checksums
ceb6e0877d4019ef42696a549e4ec54e5d653eccad56208c11500874a6526137
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl

Download URL ruff-0.0.122-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Size 3.0 MB
Tags Linux glibc 2.17+ PowerPC 64-le Python 3
SHA-256 checksum
How to use checksums
fd7f98a6e8fe35672b5a249ed204072ce96759184612a0adfa256a1fb50c4df0
BLAKE2b-256 checksum
How to use checksums
039dbf3236b07eb0e78657f997262118467eacd068451f4d821278285634e279
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl

Download URL ruff-0.0.122-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl
Size 3.0 MB
Tags Linux glibc 2.17+ PowerPC 64-be Python 3
SHA-256 checksum
How to use checksums
bd60be2530702e5f9d18e27a4fb77475d7667012f7ba12004fdf3aeb5724a86f
BLAKE2b-256 checksum
How to use checksums
514c06ea409f02ad84ec251bf918ee81dc403f0935f5aa24a87522ba52305a4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl

Download URL ruff-0.0.122-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Size 3.6 MB
Tags Linux glibc 2.17+ x86-32 Python 3
SHA-256 checksum
How to use checksums
296aa2ea720577923a7d5bfe022b890f89465e32fd0a66dc1ee4ee84436a1038
BLAKE2b-256 checksum
How to use checksums
4f6bd7b3eb2f09c0909b7f1e927bbe17857fed958969b8d29eb8713ab7bbe620
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl

Download URL ruff-0.0.122-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Size 2.6 MB
Tags Linux glibc 2.17+ ARMv7l Python 3
SHA-256 checksum
How to use checksums
34e699d3a7cbbf200382f9799567e48ac01c130abafa24b22497f13a04dacaad
BLAKE2b-256 checksum
How to use checksums
5937b851865f2b6dd46dcfca435e2bbd04389be221ebe65b80a69e56eaa31a29
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL ruff-0.0.122-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 3.3 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
bb66d182a953b994fd7c3783c71bbbb2a8a8840afdb3d5ae6f915d66ae7fe130
BLAKE2b-256 checksum
How to use checksums
c48611477c59c55e2fbcbbec3f58fd3e74fce2afcf66b8c1a1fc0d8074989571
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl

Download URL ruff-0.0.122-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Size 6.7 MB
Tags Python 3 macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
966081d61f982a5f4e93a7961efdc9505709a2729e0c4ed66d8d523284476484
BLAKE2b-256 checksum
How to use checksums
271e29f151d1b5c2c7c8401d3ea85e0cbfbb88373456a5a5a43424513c557fd3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release files / ruff-0.0.122-py3-none-macosx_10_7_x86_64.whl

Download URL ruff-0.0.122-py3-none-macosx_10_7_x86_64.whl
Size 3.5 MB
Tags Python 3 macOS 10.7+ x86-64
SHA-256 checksum
How to use checksums
5b54aba68b9190c7dfb855ce54d18d82411bd471bb7dcbb6534cf1d7cb813bf7
BLAKE2b-256 checksum
How to use checksums
766f7ebce96b0c8750d66fb3c74e734132894d0a37d7ba1e2e5de850cbccf5ad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.8.10

Release history Release notifications | RSS feed

0.9.9

18 release files

0.9.8

18 release files

0.9.7

18 release files

0.9.6

18 release files

0.9.4

18 release files

0.9.3

18 release files

0.9.2

18 release files

0.9.1

18 release files

0.8.4

18 release files

0.8.3

18 release files

0.8.1

18 release files

0.8.0

18 release files

0.7.4

18 release files

0.7.1

18 release files

0.7.0

18 release files

0.6.8

18 release files

0.6.7

18 release files

0.6.6

18 release files

0.6.5

18 release files

0.6.3

18 release files

0.6.2

18 release files

0.6.1

18 release files

0.6.0

18 release files

0.5.5

18 release files

0.5.4

18 release files

0.5.3

18 release files

0.5.2

18 release files

0.5.0

18 release files

0.4.9

17 release files

0.4.7

17 release files

0.4.6

17 release files

0.4.5

17 release files

0.4.2

17 release files

0.4.1

17 release files

0.4.0

17 release files

0.3.7

17 release files

0.3.6

17 release files

0.3.4

17 release files

0.3.3

17 release files

0.3.0

17 release files

0.2.2

17 release files

0.1.9

17 release files

0.1.8

17 release files

0.1.6

17 release files

0.1.3

17 release files

0.1.2

17 release files

0.1.1

17 release files

0.1.0

17 release files

This release

0.0.122 This release

16 release files

0.0.16

9 release files

0.0.15

3 release files

0.0.14

3 release files

0.0.13

3 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page