# How to ignore a Ruff rule for a directory


When [Ruff](https://pydevtools.com/handbook/reference/ruff.md) flags `assert` statements in tests, use `per-file-ignores` to allow them in the test directory while keeping the rule active in application code. For an isolated exception, use a [one-line suppression](https://pydevtools.com/handbook/how-to/how-to-suppress-a-ruff-warning-on-one-line.md) or [block suppression](https://pydevtools.com/handbook/how-to/how-to-disable-ruff-rules-for-a-block-of-code.md) instead.

## Prerequisites

Use an existing project with Ruff installed, as in the [Ruff setup tutorial](https://pydevtools.com/handbook/tutorial/set-up-ruff-for-formatting-and-checking-your-code.md). Run commands from the project root; the examples assume it contains `tests/` and `src/` directories.

## Add a path-specific exception

In the project's [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md), add the following entries, merging into any existing tables:

```toml {filename="pyproject.toml"}
[tool.ruff.lint]
extend-select = ["S101"]  # Check assert statements throughout the project.

[tool.ruff.lint.per-file-ignores]
"tests/**" = ["S101"]  # Allow assert statements in tests and their subdirectories.
```

Keep any existing `extend-select` entries. The exception suppresses `S101` only for matching paths; other enabled rules still apply there.

Choose additional patterns only where the project needs them:

| Pattern | Ignored codes | Effect |
| --- | --- | --- |
| `"tests/**"` | `["S101"]` | Allow assertions throughout the root test directory. |
| `"__init__.py"` | `["F401"]` | Allow unused imports in every file with this name. |
| `"docs/**"` | `["E402"]` | Allow imports after other statements in documentation Python files. |

Patterns containing a directory are relative to the discovered configuration file's directory. `**` includes nested directories; use `"**/tests/**"` to match test directories anywhere in the project. Use forward slashes in TOML on Windows too.

## Preserve exceptions from inherited configuration

If the project already inherits a configuration with `extend`, use `extend-per-file-ignores` instead of the earlier `per-file-ignores` table to keep inherited exceptions. For example, with an existing `ruff-base.toml` beside `pyproject.toml`:

```toml {filename="pyproject.toml"}
[tool.ruff]
extend = "ruff-base.toml"

[tool.ruff.lint.extend-per-file-ignores]
"tests/**" = ["S101"]
```

`per-file-ignores` replaces the inherited `per-file-ignores` mapping; `extend-per-file-ignores` adds to it. A nested configuration does not automatically inherit its parent: keep its explicit `extend` setting.

## Check that the exception matched

Re-run the enabled rule against both directories:

```bash
uv run ruff check --select S101 tests src
```

`uv run` executes the command inside the project's virtual environment, ensuring all dependencies are installed first.

Assertions under `tests/` produce no `S101` diagnostics; assertions under `src/` still do. If there are no assertions in `src/`, expect `All checks passed!`.

If a file still reports the ignored rule, substitute its actual path in this command:

```bash
uv run ruff check --show-settings tests/test_example.py
```

The output identifies the resolved settings file and lists `linter.per_file_ignores`. Check that Ruff loaded the intended configuration and that its resolved patterns cover the file. Then run the full check without `--select` to confirm other rules remain enforced:

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

Expect any remaining diagnostics, including `S101` in application code, or `All checks passed!` if the project is clean.
