Guia

Linters Python: Flake8, Black e Ruff

Configure linters e formatadores para Python. Guia completo de Flake8, Black e Ruff com exemplos, integração com editores e CI/CD

5 min de leitura

Introdução

Linters e formatadores são ferramentas que analisam seu código Python e garantem que ele siga padrões de qualidade e estilo. Eles detectam erros, inconsistências e problemas de legibilidade automaticamente, antes mesmo de rodar o código.

Neste guia, vamos configurar as três ferramentas mais populares: Flake8 (linter), Black (formatador) e Ruff (que substitui ambos com velocidade superior).

O que é o PEP 8?

O PEP 8 é o guia oficial de estilo para código Python. Ele define regras como:

  • Usar 4 espaços para indentação (não tabs)
  • Linhas com no máximo 79 caracteres (muitos projetos usam 88 ou 120)
  • Duas linhas em branco antes de funções e classes de nível superior
  • Espaços ao redor de operadores: x = 1 + 2 em vez de x=1+2
  • Importações organizadas por tipo (stdlib, terceiros, locais)

Seguir o PEP 8 torna o código mais legível e consistente, especialmente em equipes.

Flake8: o linter clássico

O Flake8 verifica se o código segue o PEP 8 e detecta erros comuns:

pip install flake8

Usando o Flake8

# Verificar um arquivo
flake8 app.py

# Verificar todo o projeto
flake8 src/

# Verificar com estatisticas
flake8 --statistics src/

Exemplo de saída:

app.py:5:1: E302 expected 2 blank lines, found 1
app.py:10:80: E501 line too long (95 > 79 characters)
app.py:15:1: F401 'os' imported but unused

Cada mensagem indica o arquivo, linha, coluna e o código do erro.

Configurando o Flake8

Crie um arquivo .flake8 na raiz do projeto:

[flake8]
max-line-length = 88
exclude =
    venv,
    .git,
    __pycache__,
    build,
    dist
ignore = E203, W503
per-file-ignores =
    __init__.py: F401

A configuração max-line-length = 88 é compatível com o Black. O E203 e W503 são ignorados porque conflitam com o estilo do Black.

Plugins úteis do Flake8

pip install flake8-bugbear    # Detecta bugs comuns
pip install flake8-comprehensions  # Otimiza list comprehensions
pip install flake8-docstrings  # Verifica docstrings

Black: o formatador inflexível

O Black formata o código automaticamente seguindo um estilo consistente. Ele é “inflexível” por design — oferece poucas opções de configuração, o que elimina debates sobre estilo em equipes:

pip install black

Usando o Black

# Formatar um arquivo
black app.py

# Formatar todo o projeto
black src/

# Apenas verificar (sem alterar)
black --check src/

# Mostrar as alterações que seriam feitas
black --diff src/

Exemplo de formatação

Antes do Black:

def calcular(a,b,c,d,e,f,g,h):
    resultado = a+b+c+d+e+f+g+h
    return {'soma':resultado,'media':resultado/8,'valores':[a,b,c,d,e,f,g,h]}

Depois do Black:

def calcular(a, b, c, d, e, f, g, h):
    resultado = a + b + c + d + e + f + g + h
    return {
        "soma": resultado,
        "media": resultado / 8,
        "valores": [a, b, c, d, e, f, g, h],
    }

Configurando o Black

No pyproject.toml:

[tool.black]
line-length = 88
target-version = ['py312']

O Black intencionalmente tem poucas opções. A ideia é que todos usem o mesmo estilo.

Ruff: o substituto ultrarrápido

O Ruff é um linter e formatador escrito em Rust, 10 a 100 vezes mais rápido que Flake8 e Black combinados. Ele implementa as mesmas regras e pode substituir ambos:

pip install ruff

Usando o Ruff como linter

# Verificar o codigo
ruff check src/

# Corrigir problemas automaticamente
ruff check --fix src/

Usando o Ruff como formatador

# Formatar (substitui o Black)
ruff format src/

# Verificar formatação
ruff format --check src/

Configurando o Ruff

No pyproject.toml:

[tool.ruff]
line-length = 88
target-version = "py312"

[tool.ruff.lint]
select = [
    "E",    # pycodestyle errors
    "F",    # pyflakes
    "I",    # isort (organização de imports)
    "N",    # pep8-naming
    "UP",   # pyupgrade
    "B",    # flake8-bugbear
    "SIM",  # flake8-simplify
    "C4",   # flake8-comprehensions
]
ignore = ["E501"]  # Ignorar linha longa (o formatador cuida disso)

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

Por que migrar para o Ruff?

O Ruff oferece várias vantagens sobre Flake8 e Black:

  • Velocidade: verifica projetos grandes em milissegundos
  • Tudo em um: linter, formatador e organizador de imports
  • Compatível: implementa centenas de regras do Flake8 e plugins
  • Configuração centralizada: tudo no pyproject.toml
  • Correção automática: muitas regras podem ser corrigidas com --fix

Organizando imports com isort

O isort organiza imports automaticamente em três grupos: stdlib, terceiros e locais:

pip install isort

Se você usa Ruff com a regra "I", o isort já está incluso e não precisa ser instalado separadamente.

Antes:

from flask import Flask
import os
from meu_pacote import utils
import sys
import requests

Depois:

import os
import sys

import requests
from flask import Flask

from meu_pacote import utils

Integração com editores

VS Code

Instale a extensão Ruff (ou Black + Flake8) e configure no settings.json:

{
    "[python]": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "charliermarsh.ruff"
    }
}

PyCharm

O PyCharm tem inspeções embutidas, mas você pode adicionar Ruff ou Black como External Tool em Settings > Tools > External Tools.

Pre-commit hooks

Use o pre-commit para rodar linters automaticamente antes de cada commit:

pip install pre-commit

Crie .pre-commit-config.yaml:

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

Instale os hooks:

pre-commit install

Agora, a cada git commit, o Ruff verifica e formata o código automaticamente.

Qual ferramenta escolher?

Para projetos novos, a recomendação é usar Ruff como ferramenta única. Ele substitui Flake8, Black e isort com melhor desempenho e configuração mais simples.

Para projetos existentes que já usam Flake8 e Black, a migração para Ruff é simples e geralmente requer apenas copiar as configurações para o pyproject.toml.

Conclusão

Linters e formatadores eliminam discussões sobre estilo de código e detectam problemas antes que eles cheguem à produção. O Ruff se destaca como a ferramenta mais moderna e eficiente, unificando funcionalidades que antes exigiam múltiplas ferramentas. Configure-os desde o início do projeto e integre com pre-commit hooks para que a verificação aconteça automaticamente em cada commit.