Skip to main content

An extremely fast Python linter, written in Rust.

Project description

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
  • ๐Ÿ“ฆ ESLint-inspired cache support
  • ๐Ÿ”ง ESLint-inspired autofix support (e.g., automatically remove unused imports)
  • ๐Ÿ‘€ TypeScript-inspired --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), pydocstyle, yesqa, and even a subset of pyupgrade and autoflake all while executing tens or hundreds of times faster than any individual tool.

Read the launch blog post.

Table of Contents

  1. Installation and Usage
  2. Configuration
  3. Supported 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.83
    hooks:
      - id: lint

Configuration

Ruff is configurable both via pyproject.toml and the command line.

For example, you could configure Ruff to only enforce a subset of rules with:

[tool.ruff]
line-length = 88
select = [
    "F401",
    "F403",
]

Alternatively, on 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
          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
  -f, --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
      --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

By default, Ruff enables all E, W, 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

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/method
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

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

pydocstyle

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

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) ๐Ÿ› 

pep8-naming

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
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 ...
N817 CamelcaseImportedAsAcronym Camelcase ... imported as acronym ...

flake8-comprehensions

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

Code Name Message Fix
B002 UnaryPrefixIncrement Python does not support the unary prefix increment.
B011 DoNotAssertFalse Do not assert False (python -O removes these calls), raise AssertionError() ๐Ÿ› 
B014 DuplicateHandlerException Exception handler with duplicate exception: ValueError ๐Ÿ› 
B017 NoAssertRaisesException assertRaises(Exception): should be considered evil.
B025 DuplicateTryBlockException try-except block with duplicate exception Exception

flake8-builtins

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

Code Name Message Fix
T201 PrintFound print found ๐Ÿ› 
T203 PPrintFound pprint found ๐Ÿ› 

Meta rules

Code Name Message Fix
M001 UnusedNOQA Unused noqa directive ๐Ÿ› 

Editor Integrations

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

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?

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 also implements the functionality that you get from yesqa, and a subset of the rules implemented in pyupgrade (8/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.

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 = [
    "D100",
    "D101",
    "D102",
    "D103",
    "D104",
    "D105",
    "D106",
    "D200",
    "D201",
    "D202",
    "D204",
    "D205",
    "D206",
    "D207",
    "D208",
    "D209",
    "D210",
    "D211",
    "D214",
    "D215",
    "D300",
    "D400",
    "D402",
    "D403",
    "D404",
    "D405",
    "D406",
    "D407",
    "D408",
    "D409",
    "D410",
    "D411",
    "D412",
    "D413",
    "D418",
    "D419",
]

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

[tool.ruff]
extend-select = [
    "D100",
    "D101",
    "D102",
    "D103",
    "D104",
    "D105",
    "D106",
    "D107",
    "D200",
    "D201",
    "D202",
    "D205",
    "D206",
    "D207",
    "D208",
    "D209",
    "D210",
    "D211",
    "D212",
    "D214",
    "D300",
    "D402",
    "D403",
    "D405",
    "D410",
    "D411",
    "D412",
    "D414",
    "D415",
    "D416",
    "D417",
    "D418",
    "D419",
]

Development

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

Assuming you have cargo installed, you can run:

cargo run resources/test/fixtures
cargo fmt
cargo clippy
cargo 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.

Project details


Release history Release notifications | RSS feed

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.0.83.tar.gz (199.7 kB view details)

Uploaded Source

Built Distributions

ruff-0.0.83-py3-none-win_amd64.whl (3.0 MB view details)

Uploaded Python 3Windows x86-64

ruff-0.0.83-py3-none-win32.whl (2.9 MB view details)

Uploaded Python 3Windows x86

ruff-0.0.83-py3-none-musllinux_1_2_x86_64.whl (3.3 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

ruff-0.0.83-py3-none-musllinux_1_2_i686.whl (3.2 MB view details)

Uploaded Python 3musllinux: musl 1.2+ i686

ruff-0.0.83-py3-none-musllinux_1_2_armv7l.whl (2.9 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARMv7l

ruff-0.0.83-py3-none-musllinux_1_2_aarch64.whl (3.0 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

ruff-0.0.83-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

ruff-0.0.83-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl (2.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ s390x

ruff-0.0.83-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (2.6 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ppc64le

ruff-0.0.83-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl (2.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ppc64

ruff-0.0.83-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (3.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ i686

ruff-0.0.83-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (2.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

ruff-0.0.83-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.0 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

ruff-0.0.83-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (6.2 MB view details)

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

ruff-0.0.83-py3-none-macosx_10_7_x86_64.whl (3.2 MB view details)

Uploaded Python 3macOS 10.7+ x86-64

File details

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

File metadata

  • Download URL: ruff-0.0.83.tar.gz
  • Upload date:
  • Size: 199.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.10

File hashes

Hashes for ruff-0.0.83.tar.gz
Algorithm Hash digest
SHA256 5ae288e73cd410014d0e0076a41ec18f5937a22c5349dc57105e4c7a370f8877
MD5 4ba1b7be0a9467e5f7ab56e0ba5edbd0
BLAKE2b-256 a94d966244bccd700a91f892de80b482de2a6411a77ef6157244366a9b18f84d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ruff-0.0.83-py3-none-win_amd64.whl
  • Upload date:
  • Size: 3.0 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.10

File hashes

Hashes for ruff-0.0.83-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 25cb151b82c92c00dd6a2827e780bcb6af78ecf0d7a4f2c183e1240eed8d8b5d
MD5 41104801077661dffa6fbcf6673b5920
BLAKE2b-256 1b219d212cd8afc56a123843ea70a11c906ec88aa7ebbe305e06e683f721f271

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ruff-0.0.83-py3-none-win32.whl
  • Upload date:
  • Size: 2.9 MB
  • Tags: Python 3, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.10

File hashes

Hashes for ruff-0.0.83-py3-none-win32.whl
Algorithm Hash digest
SHA256 e9782e5aeb86ae3080e29222828b946c0d80bce6123936ab9322670d9ba7d310
MD5 01f07c5ff455c1531cbb21e634a7086d
BLAKE2b-256 0aefa0cecda601a6a0c7c7c2df1dbafd6134cc9b7d0fc9c1aec7ce4584d8c80d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f2a1376292961b8ee2067fda67fa470b6eeefd3b164b0e209e60d8596befa7cf
MD5 3334fce8094088be8150ee4f0df1b75f
BLAKE2b-256 55204dcb15980d69181843050bec3666dea690fe19c087298a3f944b440f6535

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ruff-0.0.83-py3-none-musllinux_1_2_i686.whl
  • Upload date:
  • Size: 3.2 MB
  • Tags: Python 3, musllinux: musl 1.2+ i686
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.10

File hashes

Hashes for ruff-0.0.83-py3-none-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 0fe77010e7c117366ce712e0363d5c6b95a20675e7e388085118f592b5f82a50
MD5 1dfe0a4ad1442a94faec24d5464ffde7
BLAKE2b-256 33201f5eb5ce92ff11fc634e9e8822d8f2a15f9c6bd2099f6a1d4ae9652d996f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 58b52e5f34612290f172323f8703728b216c6c54b70a9b9389d6ea3ecc138bcb
MD5 7fc5919275d317d1d39ea8fb759e39e8
BLAKE2b-256 00c4bda83270d0b8bfe23637df5b996a43864c1e81cc046175f4522e20dbd2e4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 62bfe452cc84da0441c42dfcfc940f27dfc826a034058136e9c02e16d06416bc
MD5 3b7daf33827113a3dcad74d644484cf0
BLAKE2b-256 746dc4acd6894cc82b0c9a2ed941b42c4c0062caeca9f7fb3ecb5fe0ea3232e8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 664ce3e30c602bbb2e979063418b20927301ae509e97c846d1a452681b6725e7
MD5 83baef98932072f5a08b43916742aff2
BLAKE2b-256 a2b0473b9f83ef33c855ed6df78fe44302084e985d00a8eb028d26bf910ef723

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 bf095f9bceb59d162d283706c7055fbfb9e993a9bf58602f8c4c260d725dc6e9
MD5 ebb130a1030665ec4f0d273e70b6e8f2
BLAKE2b-256 084499438701e42076cc71a9d4d1b1d850175d11cd343016a7dcbde5a19e4a46

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 260d76878b23a705bad1e6153ba4ca123048718811443d207c90a72fabdbfeec
MD5 d74c461def5968ed675ef965e13a41cc
BLAKE2b-256 ab9495c9802156c5d15904f560d5e11fe491d90c63d0dcd9c4920ec581636aee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl
Algorithm Hash digest
SHA256 6dd676edce72bbb3ae34d5462150c16dd2dfb82fa9d15cb1242f0da3c6b5807d
MD5 f715945086ea840feb76abb9d3312840
BLAKE2b-256 dc5249472c489411c8bf9f1cad5f6a5b5483c7b0241a877c934f8472f5f23307

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 b28f2cc118f51760918ff2661a844b8c381d1aecf5e4de761d4184b82d5c8653
MD5 819f43b09cc0adb93e14f3ed2ec66cd4
BLAKE2b-256 2e3918516c6adec08bef12233678f4f4639dd1152b29d66142e0a783c029a2fa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 ced79717418416709f6bea2902caf66a5274721eaa5cea671c2012bd65e39b01
MD5 047b4a6c0108f6433cc37bd2625fd3ea
BLAKE2b-256 e373c9102202a73a772f77fa422445c9ed52ce33981a3699395821b4d11b7bc4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 afdf5ec4ae4e2aba72b5670f1d89bf30ee4b598f22fbd002d29f42e3cccef204
MD5 f31bdca55580f1ae479d866f3530d7dd
BLAKE2b-256 0da5686ccc756d22ff8f4da4dbe10aee92451dca76a7ddb6e8738110167e5e61

See more details on using hashes here.

File details

Details for the file ruff-0.0.83-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 d4f57e89e3fff0c444c2a2f1a22ba795d1ba10c07af8f175ffd8b331b4e89071
MD5 052e5785516a7b9f8a22a1dbf40f54c4
BLAKE2b-256 8752d907fa5545a915891bb4bd88239b140a81180b973473cf2c7aa30d52da64

See more details on using hashes here.

File details

Details for the file ruff-0.0.83-py3-none-macosx_10_7_x86_64.whl.

File metadata

File hashes

Hashes for ruff-0.0.83-py3-none-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 0543d39eeddb47329e01297c6ab1609e6bfd1b3ee9fc4e8a7d25b7863a456104
MD5 b4fe9a59001a31acd814b99b8b4d5f38
BLAKE2b-256 45c337a4ba1f0c535941ebe1319fb4b6255d344f756e8099da13465431effd55

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