...

Ruff: The Fast All-in-One Python Code Quality Tool

Ruff: The Fast All-in-One Python Code Quality Tool

Motivation

Code quality tools are essential for maintaining Python projects, but managing multiple tools creates unnecessary complexity in development workflows. Each tool requires separate installation, configuration, and execution.

Installing and maintaining multiple tools creates overhead:

# requirements-dev.txt
flake8==6.1.0
black==23.7.0
isort==5.12.0
pycodestyle==2.12.1

This setup requires remembering multiple commands:

isort .
black .
flake8 .
pycodestyle .

Introduction to Ruff

Ruff is a blazing-fast Python linter written in Rust that combines multiple code quality tools into a single package. Install it using pip:

pip install ruff

Unified Code Quality Checks

Let’s see how Ruff handles various code quality issues. First, configure Ruff in pyproject.toml:

[tool.ruff]
line-length = 88

# Exclude files and directories
exclude = [
    ".git",
    ".venv",
    "__pycache__",
]

[tool.ruff.lint]
select = [
    "E", # pycodestyle
    "F", # pyflakes
    "I", # isort
]

The selected rules include:

  • "E": Style and PEP 8 compliance (from pycodestyle)
  • "F": Python logical errors (from pyflakes)
  • "I": Import sorting and organization (from isort)

Let’s check a Python file with various issues:

# my_code.py
import pandas as pd
import numpy as np

def calculate_something(x, y):
    result = undefined_variable + np.array([1, 2])
    unused = "This variable is never used"
    return result+y

very_long_string = "This is an extremely long string that will definitely exceed the 88 character limit that was specified in your pyproject.toml file"

Running Ruff identifies several issues:

ruff check my_code.py

Output:

my_code.py:1:1: I001 [*] Import block is un-sorted or un-formatted
  |
1 | / import pandas as pd
2 | | import numpy as np
  | |__________________^ I001
3 |
4 |   def calculate_something(x, y):
  |
  = help: Organize imports

my_code.py:1:18: F401 [*] `pandas` imported but unused
  |
1 | import pandas as pd
  |                  ^^ F401
2 | import numpy as np
  |
  = help: Remove unused import: `pandas`

my_code.py:5:14: F821 Undefined name `undefined_variable`
  |
4 | def calculate_something(x, y):
5 |     result = undefined_variable + np.array([1, 2])
  |              ^^^^^^^^^^^^^^^^^^ F821
6 |     
7 |     unused = "This variable is never used"
  |

my_code.py:7:5: F841 Local variable `unused` is assigned to but never used
  |
5 |     result = undefined_variable + np.array([1, 2])
6 |     
7 |     unused = "This variable is never used"
  |     ^^^^^^ F841
8 |     return result+y
  |
  = help: Remove assignment to unused variable `unused`

my_code.py:10:89: E501 Line too long (151 > 88)
   |
 8 | …
 9 | …
10 | …t will definitely exceed the 88 character limit that was specified in your pyproject.toml file"
   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E501
   |

Found 5 errors.
[*] 2 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).

After running Ruff with automatic fixes:

ruff check --fix my_code.py

Output:

Found 5 errors (2 fixed, 3 remaining).

Some issues are automatically fixed, while others require manual intervention:

import numpy as np
import pandas as pd # This is removed automatically

def calculate_something(x, y):
    result = undefined_variable + np.array([1, 2]) # Needs to be fixed manually
    unused = "This variable is never used" # Needs to be fixed manually
    return result + y

# Needs to be fixed manually
very_long_string = "This is an extremely long string that will definitely exceed the 88 character limit that was specified in your pyproject.toml file"

The final, clean code after manually editing:

import numpy as np


def calculate_something(x, y):
    result = np.array([1, 2])
    return result + y

very_long_string = (
    "This is an extremely long string that will definitely exceed the "
    "88 character limit that was specified in your pyproject.toml file"
)

Conclusion

Ruff simplifies Python code quality management by replacing multiple tools with a single, faster solution. Its unified approach not only reduces configuration complexity but also provides clear guidance on which issues can be fixed automatically and which require manual intervention.

Link to Ruff

Search

Related Posts

Leave a Comment

Your email address will not be published. Required fields are marked *

Related Posts

Scroll to Top

Work with Khuyen Tran

Work with Khuyen Tran

Seraphinite AcceleratorOptimized by Seraphinite Accelerator
Turns on site high speed to be attractive for people and search engines.