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.77
    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.

Pyflakes

Code Name Message
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
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
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 NoBlankLineAfterSummary 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
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
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 classmethod should be named cls
N805 InvalidFirstArgumentNameForMethod first argument of a method should be named self

flake8-comprehensions

Code Name Message
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
B011 DoNotAssertFalse Do not assert False (python -O removes these calls), raise AssertionError()
B014 DuplicateHandlerException Exception handler with duplicate exception: ValueError
B025 DuplicateTryBlockException try-except block with duplicate exception Exception

flake8-builtins

Code Name Message
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
T201 PrintFound print found
T203 PPrintFound pprint found

Meta rules

Code Name Message
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.77.tar.gz (190.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

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

Uploaded Python 3Windows x86-64

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

Uploaded Python 3Windows x86

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

Uploaded Python 3musllinux: musl 1.2+ x86-64

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

Uploaded Python 3musllinux: musl 1.2+ i686

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

Uploaded Python 3musllinux: musl 1.2+ ARMv7l

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

Uploaded Python 3musllinux: musl 1.2+ ARM64

ruff-0.0.77-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.77-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl (2.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ s390x

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

Uploaded Python 3manylinux: glibc 2.17+ ppc64le

ruff-0.0.77-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl (2.6 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ppc64

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

Uploaded Python 3manylinux: glibc 2.17+ i686

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

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

ruff-0.0.77-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (6.1 MB view details)

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

ruff-0.0.77-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.77.tar.gz.

File metadata

  • Download URL: ruff-0.0.77.tar.gz
  • Upload date:
  • Size: 190.0 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.77.tar.gz
Algorithm Hash digest
SHA256 56f0b0d999dc8707fe29c85365b12cffb4e52220cbffdb4d257805e737469fee
MD5 626558e5bd0236ea07cd9d297095720f
BLAKE2b-256 a8bf76ef29a507b9cab9e4dfb8115df1673d8dc00256a778c5d217566992dffd

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ruff-0.0.77-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.77-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 a430c7eb7e95dd799b6e8a5001adcc8ccc85f069edf88019a3dd4bca2041cb02
MD5 7a360a3d02cc528fa1761af4209566fe
BLAKE2b-256 a6d8e3eb8bdbd8f7edf89d6f6172fbd11ab4188fcf360a032ebfa93179a08c84

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ruff-0.0.77-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.77-py3-none-win32.whl
Algorithm Hash digest
SHA256 fff8a7510799ca01de800bd254ed5d83fcd00147a80ed6ef0a5b82eefda1c0ff
MD5 a73393065e72c9ec45bc0f5bf156bbed
BLAKE2b-256 f97d86104629bbdf5cdd02126a451574f7287cd382668d2cf71a9a45114f4d0f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 52fc7dcc332754e68e0ecce4ed8d687c682c1fbdd95e863f80f65eae8ea5662f
MD5 6e44f2760c73859e645a47ae64666086
BLAKE2b-256 a185d0242921223dcd075f572d7cd69ff6ac69e965b70ccdd4afd6c834aa6a67

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ruff-0.0.77-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.77-py3-none-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 9f65b583e46e6260d274c62d5fa6168ea77f5351ac2dbc0cbedf3307d40bb831
MD5 cc62a1f61a6e5a6892edfaf6a8bfa1e9
BLAKE2b-256 6a1d9e4465d6e86af61c5ecc3d98ccb5f2ddd27a738c5bc74aa3e53284e984a7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 7cc0c7e90397bb604c9bb198b64bd47447f389a294d12d59140fe2f01358116e
MD5 759d40b25bcd5fd45df4cc146d978cd5
BLAKE2b-256 e6e612256069e98619d8e2e9851cab5f43c2a33ee0cb4e4e5675a7746feeb30f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 abfa22a03ea08e1859f13fd6299c85cc7358b44fc782c43114afc64c618214d2
MD5 e141574f0dbaf5565b56afd29d9ce00f
BLAKE2b-256 3af340473872bc298d0f2c8156742007d76a7d17a2b8dd4b416fa5e61fdfa417

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a649d231b9cecc76b6f40a46590ec9102e99a7912d373a672fcb68e844b6050e
MD5 08b5bf74c24b0f525b1dbe76fc8039aa
BLAKE2b-256 b5eac1cfba5cd1c5e226559b4e055487be84cf62704fd9d0dcba4b356f37c6a1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 102ac92712208149a93629a11a738fde1790782ee1573c7c00b41a9684fe6997
MD5 66ec7b6bc9e0e65236a97233a66f1e2d
BLAKE2b-256 141591ca2b6b7ecc41474b5a8279a5586442a346ac88034f17d0bc4fcd621c71

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 1d72179eded5d90604013378111739e53cba7437b31c79d3fab1a155e881ac31
MD5 454664ca1839eef6bea52ddbb556b2b9
BLAKE2b-256 b882c0744f8d64f85a7a91a9b7c72e1c7cb7f74640b3f8b8364328f18cb051d7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl
Algorithm Hash digest
SHA256 c9d1dcea4ba2433ee649b7e202367fac99c294d9117ba54504270418cb3ff93c
MD5 a933b58c37ce72aaf37e8190ab39fb26
BLAKE2b-256 d73971ae5565945008c17c7f65c831575d05a0f05cb13bac3f6e7a0a2f81efbb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 acca70d0c766e28a6331843c98c95f37513d9bb6f475bfe121ea5ed955f2352c
MD5 aeb3d0c64464adb7aef3e10e6e3449e4
BLAKE2b-256 6c2c3498fc56b88883992576f0848c4ccca2c15783b363c8bdb48f1fcb4518f6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 a01ad3098fb9ab03cc7a6187f09e8c7a06d64dd53f580ad34856178903f0f143
MD5 b7317de37e380fe781a22cd620a1258c
BLAKE2b-256 a2fb093857703dc617260196434b7212e37d844371928a1b4dfb4859e4e13847

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 27ea37c6578d2661460d69beff6fbede7238d9dc6bc526e481f2963983b0d8dd
MD5 182a65f05abc3ea8004d2f2085bf32b5
BLAKE2b-256 6764a456e89755f6ec08c2577dc7c02d25f2a721ad191ecfb77e7c1c0941969b

See more details on using hashes here.

File details

Details for the file ruff-0.0.77-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.77-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 fcd4aaaae9fb592acafec1d1df7ae3fb337ebb045af8929a9c980e123c6139ec
MD5 6c8d5084456389fc96befa828524ddf2
BLAKE2b-256 f819703226318b03c0cc6838d5852f13f0e41c4ddc944f417513ba08c0aab7f1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ruff-0.0.77-py3-none-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 6d2c1d4905c9c0b46cfe435d9992a93ac91bd7fdacefc357bd76c8dabd35cd69
MD5 822d1c090e219cfb9dc76f88d7a6c201
BLAKE2b-256 448a5b5f11cfa9becf76b54a45292864f7ba98f857e00bdf47ee1aa6d7a92979

See more details on using hashes here.

Supported by

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