Pyrefly: Type Checker da Meta para Python | Python Brasil
Conheça o Pyrefly, o type checker Python da Meta escrito em Rust. Aprenda a instalar, configurar e comparar com mypy, Pyright e ty em projetos reais.
Se você já tentou adicionar tipagem estática em um projeto Python de médio ou grande porte, provavelmente esbarrou na mesma pareja: o mypy é rigoroso, mas lento em codebases grandes; o Pyright (da Microsoft, base do Pylance) é rápido, mas opinionado e atrelado ao ecossistema VS Code. Em 2025, a Meta open-sourced uma alternativa que promete juntar o melhor dos dois mundos: o Pyrefly, um type checker Python escrito em Rust.
Neste artigo, vamos explorar o Pyrefly em profundidade: o que ele é, como instalar, como configurar em projetos reais, onde ele brilha em relação aos concorrentes e quando faz sentido adotá-lo. Se você já acompanhou nosso artigo sobre o ty, o type checker da Astral, vai notar que o Pyrefly é o outro jogador importante nessa nova geração de ferramentas de tipagem para Python.
O que é o Pyrefly?
O Pyrefly é um type checker para Python desenvolvido pela Meta (antiga Facebook) e usado internamente em codebases gigantescas — incluindo o próprio Instagram, que roda uma das maiores aplicações Django do mundo. Em agosto de 2025, a Meta liberou o código sob licença MIT, tornando-o disponível para a comunidade.
A motivação oficial é direta: em escala, type checkers tradicionais se tornam um gargalo. Projetos com milhões de linhas de código não podem esperar minutos por uma checagem de tipos a cada commit. O Pyrefly foi construído do zero em Rust para entregar feedback em tempo real, mesmo em repositórios enormes, sem sacrificar a profundidade da análise.
Características principais
- Escrito em Rust: performance comparável ao Pyright, muito acima do mypy puro.
- Mode de checagem configurável: do “permissivo” (para adoção gradual) ao “estrito”.
- Language Server embutido: funciona como LSP, integrando-se a qualquer editor moderno.
- Compatível com PEP 484: lê as anotações de tipo padrão do Python.
- Suporte a features modernas: generics via
TypeVar(PEP 695),Protocol,TypedDict, sobrecargas, literais e mais. - CLI e servidor: roda em pipeline de CI ou como servidor persistente para o editor.
O Pyrefly não é um formatador nem um linter de estilo — para isso a Meta recomenda combinar com o Ruff, que cobre linting e formatação numa ferramenta só.
Instalação do Pyrefly
A forma mais simples de instalar em 2026 é via uv, que gerencia a ferramenta de forma isolada do seu ambiente:
# Com uv (recomendado)
uv tool install pyrefly
# Com pip
pip install pyrefly
# Com pipx
pipx install pyrefly
# Via npm (distribuição oficial da Meta)
npm install --global @pyrefly/pyrefly
Verifique a instalação:
pyrefly --version
# pyrefly 0.x.x
Se você ainda não usa o uv, vale a pena migrar — ele tornou-se o gerenciador de pacotes padrão da comunidade em 2026 e integra naturalmente com Ruff, Pyrefly e mypy.
Primeiros passos: checando um projeto
Para checar um projeto inteiro, basta apontar o Pyrefly para o diretório raiz:
pyrefly check .
Por padrão, o Pyrefly procura arquivos .py no caminho informado e reporta erros de tipo. Vamos criar um exemplo com alguns problemas comuns:
# exemplo.py
from typing import Optional
def saudar(nome: str) -> str:
return f"Olá, {nome}"
def processar(lista: list[int]) -> int:
return sum(lista)
def buscar(indice: int, itens: list[str]) -> Optional[str]:
if 0 <= indice < len(itens):
return itens[indice]
return None
# Erro de tipo: passando int onde se espera str
mensagem = saudar(42)
# Erro de tipo: lista com tipos misturados
processar([1, 2, "três"])
# Ok: chamada válida
resultado = buscar(0, ["a", "b"])
print(resultado.upper()) # Possível erro: resultado pode ser None
Rodando o Pyrefly:
pyrefly check exemplo.py
Saída típica:
exemplo.py:17:15: error: expected `str`, got `int`
exemplo.py:20:13: error: expected `int`, got `str`
exemplo.py:25:18: error: possibly-undefined attribute `upper`
O último erro é particularmente útil: o Pyrefly entende que buscar pode retornar None e alerta sobre o acesso a .upper() sem verificação prévia. Esse tipo de análise é exatamente onde tipagem estática previne bugs em produção.
Configuração no pyproject.toml
O Pyrefly centraliza a configuração em um bloco [tool.pyrefly] no pyproject.toml, seguindo o padrão moderno do ecossistema Python:
[tool.pyrefly]
# Nível de rigor padrão do projeto
# options: "warn", "error", "strict"
project-mode = "strict"
# Caminhos a incluir na análise
include = ["src", "tests"]
# Caminhos a ignorar
exclude = [
"src/legacy",
"src/migrations",
".venv",
"build",
]
# Versão do Python alvo
python-version = "3.12"
Para casos em que você quer afrouxar a checagem em arquivos específicos (por exemplo, código legado em migração), é possível usar comentários # pyrefly: ignore no nível do arquivo ou marcar blocos:
# pyrefly: ignore # desliga a checagem para todo o arquivo
def codigo_legado(dados):
return dados.processar()
Ou inline, para suprimir um erro específico:
valor = algo_ruido() # type: ignore[possibly-undefined]
Adoção gradual: o grande trunfo do Pyrefly
O diferencial mais comentado do Pyrefly em relação a ferramentas mais antigas é o modelo de adoção gradual. Em projetos enormes (como os da própria Meta), não é viável exigir 100% de tipagem do dia para a noite.
O Pyrefly oferece três modos principais:
warn: reporta apenas os erros mais óbvios, como atributos indefinidos. Ideal para começar.error(padrão): reporta violações de tipo em código já anotado, mas não obriga anotação em todo lugar.strict: exige anotações em todas as funções e aplica regras rígidas (equivalente ao--strictdo mypy).
Você pode definir o modo padrão no pyproject.toml e sobrescrever por diretório:
[tool.pyrefly]
project-mode = "warn"
[[tool.pyrefly.overrides]]
path = "src/core"
mode = "strict"
[[tool.pyrefly.overrides]]
path = "src/experimental"
mode = "warn"
Essa flexibilidade permite migrar módulos críticos primeiro e deixar código experimental ou legado em modo permissivo, sem poluir o CI com centenas de erros de uma vez.
Language Server: integração com editores
Além da CLI, o Pyrefly funciona como Language Server (LSP), o que significa integração em tempo real com a maioria dos editores modernos: VS Code, Neovim, Helix, Zed, Emacs e outros.
VS Code
Instale a extensão Pyrefly (publicada pela Meta) e configure no settings.json:
{
"python.languageServer": "Pyrefly",
"pyrefly.importStrategy": "fromEnvironment",
"pyrefly.warnUnsupported": true
}
Neovim (com lspconfig)
Se você usa Neovim com nvim-lspconfig:
require('lspconfig').pyrefly.setup({})
Outros editores
Como o Pyrefly implementa o protocolo LSP, qualquer editor compatível consegue usá-lo. A vantagem em relação ao mypy é a velocidade: o feedback ao digitar é quase instantâneo, mesmo em arquivos com milhares de linhas.
Comparação: Pyrefly vs mypy vs Pyright vs ty
A pergunta inevitável: qual type checker escolher? A resposta curta é “depende do contexto”, mas a tabela abaixo ajuda a situar cada ferramenta:
| Característica | mypy | Pyright | ty | Pyrefly |
|---|---|---|---|---|
| Linguagem | Python | TypeScript | Rust | Rust |
| Mantenedor | Dropbox/comm. | Microsoft | Astral | Meta |
| Velocidade | Lento | Rápido | Muito rápido | Muito rápido |
| LSP embutido | Não | Sim (Pylance) | Sim | Sim |
| Adoção gradual | Limitada | Boa | Boa | Excelente |
| Modo estrito | Sim | Sim | Sim | Sim |
| Licença | MIT | MIT | MIT | MIT |
| Maturidade | Alta | Alta | Inicial | Alta (interno) |
Quando escolher Pyrefly
O Pyrefly faz mais sentido quando:
- Sua codebase é grande (centenas de milhares de linhas ou mais) e o mypy está lento demais.
- Você precisa de adoção gradual real, com modos configuráveis por diretório.
- O time já usa VS Code, Neovim ou outro editor com suporte LSP e quer feedback instantâneo.
- Há tolerância a uma ferramenta relativamente nova no open source, mesmo que madura internamente.
Quando NÃO escolher Pyrefly
Pense duas vezes se:
- O projeto é pequeno e o mypy já atende bem — não há pressão por performance.
- Você precisa de regras muito específicas do mypy que ainda não têm equivalente no Pyrefly.
- A equipe já está deepmente integrada ao ecossistema Astral (Ruff, uv, ty) e prefere consistência.
Exemplo prático: validando tipos em uma API FastAPI
Vamos ver o Pyrefly em ação validando uma pequena API com FastAPI. Crie os arquivos:
# app/models.py
from pydantic import BaseModel
class Usuario(BaseModel):
id: int
nome: str
email: str
ativo: bool = True
class CriarUsuario(BaseModel):
nome: str
email: str
# app/repo.py
from typing import Optional
from app.models import Usuario, CriarUsuario
_usuarios: dict[int, Usuario] = {}
_proximo_id: int = 1
def criar(dados: CriarUsuario) -> Usuario:
global _proximo_id
usuario = Usuario(id=_proximo_id, **dados.model_dump())
_usuarios[usuario.id] = usuario
_proximo_id += 1
return usuario
def buscar(usuario_id: int) -> Optional[Usuario]:
return _usuarios.get(usuario_id)
def listar_ativos() -> list[Usuario]:
return [u for u in _usuarios.values() if u.ativo]
# app/api.py
from fastapi import FastAPI, HTTPException
from app.models import CriarUsuario, Usuario
from app.repo import criar, buscar, listar_ativos
app = FastAPI()
@app.post("/usuarios", response_model=Usuario)
def endpoint_criar(dados: CriarUsuario) -> Usuario:
return criar(dados)
@app.get("/usuarios/{usuario_id}", response_model=Usuario)
def endpoint_buscar(usuario_id: int) -> Usuario:
usuario = buscar(usuario_id)
if usuario is None:
raise HTTPException(status_code=404, detail="Usuário não encontrado")
return usuario
@app.get("/usuarios", response_model=list[Usuario])
def endpoint_listar() -> list[Usuario]:
return listar_ativos()
Agora rode o Pyrefly em modo estrito:
pyrefly check app/
Se houver, por exemplo, uma função que esqueça de tratar o Optional[Usuario], o Pyrefly vai apontar antes mesmo de você rodar a aplicação. Isso é especialmente útil em APIs que usam Pydantic e FastAPI, onde o fluxo de dados entre camadas é sensível a tipos.
Integrando com pre-commit e CI
Para garantir que todo commit passe pela checagem de tipos, adicione o Pyrefly ao .pre-commit-config.yaml:
repos:
- repo: local
hooks:
- id: pyrefly
name: pyrefly
entry: pyrefly check
language: system
types: [python]
pass_filenames: false
No GitHub Actions:
name: CI
on: [push, pull_request]
jobs:
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- run: uv sync
- run: uv run pyrefly check .
Como o Pyrefly é rápido, o impacto no tempo de pipeline é mínimo — mesmo em projetos grandes, a checagem costuma levar poucos segundos.
Pyrefly e features modernas do Python
O Pyrefly acompanha as novidades da linguagem. Em 2026, com o Python 3.14 consolidado e o Python 3.15 em desenvolvimento, recursos avançados de tipagem já são suportados:
Generics com PEP 695 (Python 3.12+)
def primeiro[T](itens: list[T]) -> T | None:
return itens[0] if itens else None
class Pilha[T]:
def __init__(self) -> None:
self._dados: list[T] = []
def empilhar(self, item: T) -> None:
self._dados.append(item)
def desempilhar(self) -> T | None:
return self._dados.pop() if self._dados else None
Protocols (tipagem estrutural)
Se você quer entender tipagem estrutural em profundidade, confira nosso artigo sobre Protocols em Python. Exemplo rápido:
from typing import Protocol
class Closeable(Protocol):
def close(self) -> None: ...
def fechar_todos(recursos: list[Closeable]) -> None:
for r in recursos:
r.close()
class Arquivo:
def close(self) -> None:
print("arquivo fechado")
# Arquivo não herda de Closeable, mas tem o método close()
fechar_todos([Arquivo()])
O Pyrefly valida que Arquivo satisfaz o protocolo Closeable estruturalmente, sem exigir herança explícita.
TypedDict
from typing import TypedDict
class ConfigBanco(TypedDict):
host: str
porta: int
senha: str
def conectar(config: ConfigBanco) -> None:
print(f"Conectando a {config['host']}:{config['porta']}")
# Erro: falta o campo 'senha'
conectar({"host": "localhost", "porta": 5432})
Perguntas Frequentes
O Pyrefly substitui o mypy?
Depende. Para muitos projetos novos ou em modernização, sim — especialmente se velocidade e adoção gradual forem prioridade. Para projetos que dependem de plugins específicos do mypy (como django-stubs em configurações muito customizadas), vale validar a compatibilidade antes de migrar.
O Pyrefly é estável o suficiente para produção?
Sim. A Meta usa o Pyrefly há anos internamente em codebases críticas. A versão open source é a mesma base, então a maturidade do motor é alta, mesmo sendo “nova” para a comunidade externa.
Posso usar Pyrefly junto com o Ruff?
Pode e deve. O Ruff cobre linting de estilo e formatação; o Pyrefly cobre checagem de tipos. São complementares, assim como Black + mypy eram no passado. Veja nosso guia de configuração de linters para integrar ambos.
Como o Pyrefly se compara ao ty?
Ambos são type checkers em Rust, mas têm origens diferentes: o ty vem da Astral (mesma empresa do uv e Ruff) e é mais jovem; o Pyrefly vem da Meta e é mais maduro em escala. Em performance, os dois são competitivos. A escolha costuma se resumir a ecossistema preferido (Astral vs Meta) e detalhes de ergonomia. Comparar lado a lado em um projeto real é a melhor forma de decidir.
O Pyrefly funciona com Python 2?
Não. O Pyrefly foca exclusivamente em Python 3.6+. Se você ainda mantém código Python 2, a recomendação é planejar a migração — o Python 2 está sem suporte oficial desde 2020 e representa risco de segurança.
Conclusão
O Pyrefly chega para preencher uma lacuna real do ecossistema Python: um type checker rápido, moderno e pensado para adoção gradual em larga escala. Vindo da Meta, com licença MIT e implementação em Rust, ele se posiciona como alternativa séria ao mypy e ao Pyright, especialmente para times que sofrem com lentidão em codebases grandes.
A recomendação prática para 2026 é: experimente o Pyrefly se o seu projeto já passou da fase de protótipo e a tipagem estática está virando gargalo. Combine com Ruff para linting e uv para gerenciamento de pacotes, e você terá um toolchain Python moderno, rápido e confiável.
Se você quer acompanhar o estado da arte em tipagem e ferramentas, vale conferir também nosso artigo sobre o ty, o type checker da Astral, e nosso guia de tipagem estática com mypy. O mercado de type checkers Python nunca esteve tão competitivo — e a comunidade só tem a ganhar.
O Pyrefly, assim como o ty e o Ruff, é escrito em Rust — linguagem que sustenta a nova geração de ferramentas Python de alta performance. Conhecer Rust ajuda a entender por que essas ferramentas são tão rápidas e abre portas para contribuir com o ecossistema.
Está buscando vagas Python que valorizam boas práticas e tipagem estática? Confira as oportunidades em empresas que usam Python no Brasil e destaque-se com um toolchain moderno no portfólio.
Equipe Python Brasil
Contribuidor do Python Brasil — Aprenda Python em Português