Ruff: Linter e Formatador Mais Rápido para Python | Python Brasil

Conheça o Ruff, o linter e formatador Python escrito em Rust. Aprenda a configurar, usar e substituir flake8, black e isort em um só comando.

7 min de leitura Equipe Python Brasil

Se você trabalha com Python profissionalmente, já deve ter configurado uma combinação de flake8, black, isort e talvez pylint nos seus projetos. Cada ferramenta tem seu arquivo de configuração, suas dependências e seu tempo de execução. E se eu te dissesse que existe uma única ferramenta que substitui todas elas e roda 10 a 100 vezes mais rápido?

Essa ferramenta é o Ruff — um linter e formatador Python escrito em Rust que está revolucionando o ecossistema de qualidade de código Python. Neste artigo, vamos explorar tudo sobre o Ruff: instalação, configuração, migração e exemplos práticos.

O que é o Ruff?

O Ruff é um linter e formatador de código Python extremamente rápido, criado por Charlie Marsh e mantido pela Astral (a mesma empresa por trás do uv). Ele é escrito em Rust, o que explica sua velocidade impressionante.

  • Velocidade absurda: processa milhares de arquivos em milissegundos
  • Tudo em um: substitui flake8, black, isort, pylint, pyupgrade e mais
  • 700+ regras incluídas, compatíveis com plugins populares do flake8
  • Auto-fix: corrige automaticamente a maioria dos problemas encontrados
  • Configuração unificada: tudo no pyproject.toml
  • Drop-in replacement: migração quase transparente de projetos existentes

Instalação do Ruff

Existem várias formas de instalar o Ruff. A mais recomendada em 2026 é usando o uv:

# Com uv (recomendado)
uv tool install ruff

# Com pip
pip install ruff

# Com pipx
pipx install ruff

# No macOS com Homebrew
brew install ruff

Verifique a instalação:

ruff --version
# ruff 0.9.x

Usando o Ruff como Linter

O uso mais básico do Ruff é como linter. Basta apontar para um arquivo ou diretório:

# Verificar um arquivo
ruff check main.py

# Verificar todo o projeto
ruff check .

# Verificar e corrigir automaticamente
ruff check --fix .

Exemplo prático

Vamos criar um arquivo Python com alguns problemas comuns:

# exemplo.py
import os
import sys
import json
from typing import List, Dict

def calcular_media(numeros: List[int]) -> float:
    soma = 0
    for n in numeros:
        soma += n
    media = soma / len(numeros)
    return media

def processar_dados(dados: Dict[str, any]):
    resultado = dict()
    for chave in dados.keys():
        if type(dados[chave]) == str:
            resultado[chave] = dados[chave].strip()
        elif type(dados[chave]) == int:
            resultado[chave] = dados[chave] * 2
    return resultado

x = lambda a, b: a + b

nome = "Python"
print(f"Olá, {nome}!")

Rodando ruff check exemplo.py, o Ruff identifica:

exemplo.py:1:8: F401 [*] `os` imported but unused
exemplo.py:2:8: F401 [*] `sys` imported but unused
exemplo.py:3:8: F401 [*] `json` imported but unused
exemplo.py:4:21: UP006 Use `list` instead of `List` for type annotation
exemplo.py:4:28: UP006 Use `dict` instead of `Dict` for type annotation
exemplo.py:15:17: C408 Unnecessary `dict` call (rewrite as a literal)
exemplo.py:16:9: SIM118 Use `key in dict` instead of `key in dict.keys()`
exemplo.py:17:12: E721 Do not compare types, use `isinstance()`
exemplo.py:19:14: E721 Do not compare types, use `isinstance()`
exemplo.py:22:5: E731 Do not assign a `lambda` expression, use a `def`

Com ruff check --fix exemplo.py, o Ruff corrige automaticamente a maioria desses problemas:

# exemplo.py (após ruff check --fix)
from typing import Dict

def calcular_media(numeros: list[int]) -> float:
    soma = 0
    for n in numeros:
        soma += n
    media = soma / len(numeros)
    return media

def processar_dados(dados: dict[str, any]):
    resultado = {}
    for chave in dados:
        if isinstance(dados[chave], str):
            resultado[chave] = dados[chave].strip()
        elif isinstance(dados[chave], int):
            resultado[chave] = dados[chave] * 2
    return resultado

def x(a, b): return a + b

nome = "Python"
print(f"Olá, {nome}!")

Observe como o Ruff removeu imports não usados, modernizou as type annotations, simplificou o dict(), removeu .keys() desnecessário e converteu type() para isinstance().

Usando o Ruff como Formatador

Desde a versão 0.1.2, o Ruff também funciona como formatador de código, substituindo o Black:

# Formatar um arquivo
ruff format main.py

# Formatar todo o projeto
ruff format .

# Verificar formatação sem alterar (útil em CI)
ruff format --check .

O formatador do Ruff é compatível com o Black em mais de 99,9% dos casos, mas roda 30x mais rápido.

Configuração no pyproject.toml

A configuração do Ruff fica toda no pyproject.toml, eliminando a necessidade de múltiplos arquivos de configuração:

[tool.ruff]
# Versão mínima do Python alvo
target-version = "py312"

# Tamanho máximo da linha
line-length = 88

# Diretórios a ignorar
exclude = [
    ".git",
    ".venv",
    "__pycache__",
    "migrations",
]

[tool.ruff.lint]
# Regras ativadas
select = [
    "E",    # pycodestyle errors
    "W",    # pycodestyle warnings
    "F",    # pyflakes
    "I",    # isort
    "N",    # pep8-naming
    "UP",   # pyupgrade
    "B",    # flake8-bugbear
    "SIM",  # flake8-simplify
    "C4",   # flake8-comprehensions
    "DTZ",  # flake8-datetimez
    "RUF",  # ruff-specific rules
]

# Regras ignoradas
ignore = [
    "E501",  # line too long (formatador cuida disso)
]

# Permitir auto-fix para todas as regras habilitadas
fixable = ["ALL"]

[tool.ruff.lint.isort]
known-first-party = ["meu_projeto"]

[tool.ruff.format]
# Usar aspas duplas (compatível com Black)
quote-style = "double"
# Usar vírgula final
skip-magic-trailing-comma = false

Migrando de flake8 + black + isort

Se você já usa essas ferramentas, a migração é simples:

Passo 1: Remover ferramentas antigas

pip uninstall flake8 black isort pylint pyupgrade

Passo 2: Instalar o Ruff

uv tool install ruff

Passo 3: Converter configuração existente

O Ruff oferece um comando para converter configurações do flake8:

ruff check --show-settings

Passo 4: Atualizar scripts de CI/CD

Antes (múltiplas ferramentas):

# Antigo - lento e complexo
- run: |
    black --check .
    isort --check .
    flake8 .
    pylint src/

Depois (só Ruff):

# Novo - rápido e simples
- run: |
    ruff check .
    ruff format --check .

Integração com editores de código

VS Code

Instale a extensão oficial Ruff (charliermarsh.ruff) e adicione ao settings.json:

{
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.fixAll.ruff": "explicit",
            "source.organizeImports.ruff": "explicit"
        }
    }
}

Se você usa o VS Code para Python, essa configuração vai transformar sua experiência de desenvolvimento.

Pre-commit

Adicione o Ruff ao seu .pre-commit-config.yaml:

repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.9.6
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format

Ruff vs outras ferramentas: benchmark

Aqui está uma comparação de tempo de execução em um projeto com 1.000 arquivos Python:

FerramentaTempoMultiplicador
Pylint45.2s1x
flake88.3s5.4x mais rápido
Ruff0.12s376x mais rápido

Para formatação:

FerramentaTempoMultiplicador
Black6.1s1x
Ruff format0.19s32x mais rápido

Essa diferença é ainda mais impactante em pipelines de CI/CD e em projetos grandes como o Django ou projetos com muitos microsserviços.

Regras mais úteis do Ruff

O Ruff implementa regras de dezenas de plugins do flake8. Algumas das mais úteis:

# UP006: Use built-in types para annotations (Python 3.9+)
# Antes:
from typing import List, Dict, Optional
def func(items: List[str]) -> Dict[str, int]: ...

# Depois:
def func(items: list[str]) -> dict[str, int]: ...

# SIM110: Use any() ao invés de loop manual
# Antes:
for item in lista:
    if item.ativo:
        return True
return False

# Depois:
return any(item.ativo for item in lista)

# C4: Use comprehensions ao invés de map/filter
# Antes:
resultado = list(map(lambda x: x * 2, numeros))

# Depois:
resultado = [x * 2 for x in numeros]

# B006: Não use objetos mutáveis como argumento padrão
# Antes:
def func(items: list = []):  # Bug!
    items.append(1)

# Depois:
def func(items: list | None = None):
    if items is None:
        items = []
    items.append(1)

Para mais detalhes sobre boas práticas Python, confira nosso guia atualizado.

Perguntas Frequentes

O Ruff substitui completamente o Pylint?

O Ruff implementa muitas regras do Pylint, mas não todas. Para a maioria dos projetos, o Ruff é suficiente. Se você precisa de análise estática mais profunda (como verificação de tipos), combine o Ruff com o mypy.

O Ruff funciona com Python 2?

Não. O Ruff foca exclusivamente em Python 3. Se você ainda mantém código Python 2, considere migrar — o Python 2 está sem suporte desde 2020.

Posso usar o Ruff junto com o Black?

Pode, mas não há necessidade. O formatador do Ruff (ruff format) é compatível com o Black e muito mais rápido. A recomendação é usar apenas o Ruff.

O Ruff é seguro para usar em produção?

Sim. O Ruff é usado em projetos como FastAPI, Pandas, Apache Airflow, SciPy e muitos outros projetos de grande porte. É uma ferramenta madura e confiável.

Como o Ruff se compara ao uv?

O Ruff e o uv são ferramentas complementares da mesma empresa (Astral). O Ruff cuida da qualidade de código (linting e formatação), enquanto o uv cuida do gerenciamento de pacotes e ambientes virtuais. Juntos, formam o toolkit Python mais moderno disponível.

Conclusão

O Ruff é, sem dúvida, a ferramenta de qualidade de código mais importante do ecossistema Python em 2026. Sua velocidade, abrangência e facilidade de uso tornam difícil justificar continuar usando múltiplas ferramentas separadas.

Se você está começando um projeto novo ou quer modernizar um existente, o Ruff deveria ser sua primeira escolha. Combine com o uv para gerenciamento de pacotes e você terá um workflow Python moderno, rápido e eficiente.

Está buscando vagas Python que valorizam boas práticas? Confira as oportunidades em empresas que usam Python no Brasil.

E

Equipe Python Brasil

Contribuidor do Python Brasil — Aprenda Python em Português