Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
Filter by Categories
About Article
Analyze Data
Archive
Best Practices
Better Outputs
Blog
Code Optimization
Code Quality
Command Line
Daily tips
Dashboard
Data Analysis & Manipulation
Data Engineer
Data Visualization
DataFrame
Delta Lake
DevOps
DuckDB
Environment Management
Feature Engineer
Git
Jupyter Notebook
LLM
LLM
Machine Learning
Machine Learning
Machine Learning & AI
Manage Data
MLOps
Natural Language Processing
NumPy
Pandas
Polars
PySpark
Python Tips
Python Utilities
Python Utilities
Scrape Data
SQL
Testing
Time Series
Tools
Visualization
Visualization & Reporting
Workflow & Automation
Workflow Automation

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

Table of Contents

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

Leave a Comment

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

0
    0
    Your Cart
    Your cart is empty
    Scroll to Top

    Work with Khuyen Tran

    Work with Khuyen Tran