# How to configure recommended Ruff defaults

{{< callout type="warning" >}}
This guide assumes you have a Python project set up. If you haven't created a project yet, see the [project creation tutorial](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md) before proceeding.
{{< /callout >}}

This guide shows how to configure [Ruff](https://pydevtools.com/handbook/reference/ruff.md) with a curated set of linting rules that extend beyond the defaults. When starting a new project, it's easier to enable a comprehensive set of rules from the beginning and selectively disable any that don't fit the project's needs, rather than gradually adding rules later when there's already code to fix.

## Adding the Configuration

Add the following to the project's `pyproject.toml` file:

```toml
[tool.ruff.lint]
extend-select = [
    "F",        # Pyflakes rules
    "W",        # PyCodeStyle warnings
    "E",        # PyCodeStyle errors
    "I",        # Sort imports properly
    "UP",       # Warn if certain things can changed due to newer Python versions
    "C4",       # Catch incorrect use of comprehensions, dict, list, etc
    "FA",       # Enforce from __future__ import annotations
    "ISC",      # Good use of string concatenation
    "ICN",      # Use common import conventions
    "RET",      # Good return practices
    "SIM",      # Common simplification rules
    "TID",      # Some good import practices
    "TC",       # Enforce importing certain types in a TYPE_CHECKING block
    "PTH",      # Use pathlib instead of os.path
    "TD",       # Be diligent with TODO comments
    "NPY",      # Some numpy-specific things
    "FURB",     # Suggest more idiomatic Python patterns
]
```

## Running the Linter

Check the project for issues:

```bash
uv run ruff check .
```

Automatically fix violations where possible:

```bash
uv run ruff check --fix .
```

## Understanding the Rule Categories

### [Pyflakes (F)](https://docs.astral.sh/ruff/rules/#pyflakes-f)
Detects logical errors that would cause runtime failures, including undefined variables, unused imports, and invalid string formatting.

### [PyCodeStyle Errors (E)](https://docs.astral.sh/ruff/rules/#error-e) and [Warnings (W)](https://docs.astral.sh/ruff/rules/#warning-w)
Enforces [PEP 8](https://pydevtools.com/handbook/explanation/what-is-pep-8.md) conventions, catching indentation errors, incorrect comparisons (`if x == None`), and whitespace issues.

### [Import Sorting (I)](https://docs.astral.sh/ruff/rules/#isort-i)
Ensures imports follow a consistent ordering convention, grouping standard library, third-party, and local imports predictably.

### [Python Upgrades (UP)](https://docs.astral.sh/ruff/rules/#pyupgrade-up)
Modernizes code syntax to use newer Python features, suggesting f-strings over older formatting and updated type hint syntax.

### [Comprehensions (C4)](https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4)
Identifies inefficient iteration patterns, flagging unnecessary list comprehensions wrapped in constructors and suggesting simpler alternatives.

### [Future Annotations (FA)](https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa)
Encourages adding `from __future__ import annotations`, which simplifies forward references in type hints and reduces runtime overhead.

### [String Concatenation (ISC)](https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc)
Detects implicit string concatenation of adjacent literals, making concatenation explicit and preventing bugs from missing commas.

### [Import Conventions (ICN)](https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn)
Enforces standard import aliases (`numpy` as `np`, `pandas` as `pd`, `matplotlib.pyplot` as `plt`).

### [Return Practices (RET)](https://docs.astral.sh/ruff/rules/#flake8-return-ret)
Improves function return patterns by flagging unnecessary `return None` statements and suggesting removal of superfluous else blocks.

### [Simplifications (SIM)](https://docs.astral.sh/ruff/rules/#flake8-simplify-sim)
Suggests more elegant code patterns, including combined `isinstance()` checks, natural comparison order, and cleaner boolean logic.

### [Tidy Imports (TID)](https://docs.astral.sh/ruff/rules/#flake8-tidy-imports-tid)
Manages import quality by encouraging absolute imports and helping establish import conventions.

### [Type Checking Imports (TC)](https://docs.astral.sh/ruff/rules/#flake8-type-checking-tc)
Optimizes type-only imports by moving them into `if TYPE_CHECKING:` blocks, reducing import overhead while maintaining type-checking capability.

### [Pathlib Usage (PTH)](https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth)
Recommends `pathlib.Path` over `os.path` functions for more object-oriented, cross-platform file handling.

### [TODO Discipline (TD)](https://docs.astral.sh/ruff/rules/#flake8-todos-td)
Enforces conventions for TODO comments, requiring proper formatting and meaningful descriptions.

### [NumPy Conventions (NPY)](https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy)
Flags deprecated NumPy type aliases and APIs, guiding migration to modern NumPy patterns.

### [Refurb (FURB)](https://docs.astral.sh/ruff/rules/#refurb-furb)
Suggests more idiomatic Python patterns, such as replacing set-add loops with `set.update()`, using `str.removeprefix()` instead of hand-rolled slicing, rewriting conditional expressions as `min()`/`max()` calls, and replacing `open()`/`read()` with `Path.read_text()`. All FURB rules include auto-fix support.

## Selective Rule Disabling

To disable specific rules that conflict with existing practices, add them to the `ignore` list:

```toml
[tool.ruff.lint]
extend-select = [
    # ... rules from above
]
ignore = [
    "TD003",  # Example: disable missing TODO link requirement
]
```
