Pular para o conteúdo
LatchkeyLatchkey home

mypy vs Pyright: Qual type checker Python para CI?

O mypy é o type checker de referência do Python; o Pyright é um checker rápido e rigoroso que também alimenta o Pylance no VS Code.

O mypy é o type checker estático original e amplamente usado para Python, mantido junto aos padrões de tipagem. O Pyright (da Microsoft) é um checker implementado em TypeScript conhecido por forte inferência, velocidade e integração estreita com o VS Code via Pylance.

mypy vs Pyright at a glance

mypyPyright
VelocidadeModeradaRápida (incremental, watch mode)
InferênciaBoaForte
Integração com editorVia plugins/LSPNativa (Pylance/VS Code)
Controles de rigorFlags granularesGranular, strict mode
Status de referênciaImplementação de referência de tipagemIndependente, amplamente usado
Language serverNãoSim, alimenta o Pylance no VS Code
Escrito emPython, compilado com mypycTypeScript
Configuraçãomypy.ini, setup.cfg, pyproject.tomlpyrightconfig.json, pyproject.toml

No CI

Ambos rodam como um gate de CI que falha em erros de tipo. O Pyright geralmente é mais rápido e tem forte inferência, o que pode pegar problemas que o mypy deixa passar e dá feedback rápido; rodar o mesmo checker no editor (Pylance) e no CI mantém os resultados consistentes. O mypy é a implementação de referência e a correspondência mais próxima da semântica oficial de tipagem, com um grande corpo de configs e stubs existentes. Alguns projetos rodam os dois para maximizar a cobertura.

Comparing like for like
# mypy, checking what Pyright checks by default
mypy --check-untyped-defs src/

# or go all the way
mypy --strict src/

# Pyright at its default (already checks everything)
pyright src/

# Pyright at basic, if the default is too much to adopt at once
pyright --level basic src/

Escolhendo para pipelines

Quer velocidade e paridade com o editor VS Code/Pylance: Pyright. Quer o checker de referência e o alinhamento mais próximo aos padrões de tipagem: mypy. Fixe a versão e as flags de rigor no CI para que os resultados sejam reproduzíveis.

  • Joins versus unions. When merging types across branches, mypy joins to a common supertype while Pyright forms a union. Pyright documentation states that joins discard valuable type information and lead to many false positive errors.
  • Literal preservation. (1, "stop") gives Pyright Literal["stop"] and gives mypy str. If you use literal types for state machines or discriminated unions, mypy widening them costs you the checking you wanted.
  • Variable declarations. mypy treats a first assignment as an implicit declaration; Pyright infers a union across assignments. mypy behaviour is the more surprising of the two when a variable legitimately holds different types over its life.

Velocidade: a afirmação padrão hoje é contestada

A documentação do Pyright afirma que ele é 3x a 5x mais rápido que o mypy em bases de código grandes, e isso foi a sabedoria aceita por anos. Vale tratar com mais cuidado em 2026.

  • Esse número é anterior à distribuição do mypy como binários compilados com mypyc e anterior ao trabalho de otimização da 1.18, que melhorou bastante o mypy na sua própria base de código.
  • Comparações independentes recentes encontram o mypy atual competitivo e, em alguns casos, mais rápido que o Pyright.
  • Ambos hoje ficam bem atrás dos entrantes mais novos. O Pyrefly, da Meta, chegou ao 1.0 estável em maio de 2026 e reporta 10-50x sobre os dois. O ty, da Astral, ainda estava em alfa.

Plugins são a única coisa que o Pyright não faz

Este é o ou-um-ou-outro mais claro da comparação. O mypy suporta plugins; o Pyright não tem sistema de plugins e seus mantenedores disseram que não terá.

  • Modelos do Django geram atributos dinamicamente. Sem o django-stubs e seu plugin de mypy, um type checker não consegue acompanhar isso, e o Pyright não consegue carregar o plugin.
  • Modelos declarativos do SQLAlchemy têm o mesmo formato de problema.
  • Se a sua base de código depende de algum dos dois, o suporte a plugins do mypy é um requisito rígido e não uma preferência, diga o que disser o resto desta comparação.

Rodando qualquer um deles em CI

.github/workflows/ci.yml
# mypy
- run: pip install mypy
- run: mypy --strict src/

# Pyright, with machine-readable output for annotations
- run: pip install pyright
- run: pyright --outputjson src/ > pyright.json

# Adopting gradually: fail only on files already clean
- run: mypy src/ --strict --exclude "src/legacy/.*"

Dá para usar os dois?

Sim, e algumas bases de código grandes fazem isso, embora o retorno seja mais estreito do que parece. Pyright como experiência de editor via Pylance e mypy como portão de CI é uma divisão comum, porque entrega a inferência do Pyright enquanto você digita e a cobertura de plugins do mypy onde a correção é imposta.

  • O custo é manter duas configurações que precisam concordar, ou aceitar que o seu editor e o seu CI vão discordar.
  • As discordâncias não são hipotéticas: as diferenças de inferência acima significam vereditos genuinamente diferentes sobre o mesmo código.
  • Para a maioria das equipes, um checker bem configurado supera dois configurados por aproximação.

Benchmark on your repository before choosing

Build-tool benchmarks published by vendors use repositories chosen to show a difference. Yours is the only one that matters, and both a cold and a warm measurement are needed because CI mostly runs cold.

Terminal
# cold: no cache, the CI condition
rm -rf node_modules/.cache dist && time <tool> build

# warm: the local development condition
time <tool> build

# and the one people forget: incremental after a one-line change
echo "// touch" >> src/index.ts && time <tool> build

The verdict

Quer checagens rápidas e paridade com o editor: Pyright. Quer o checker de referência alinhado aos padrões de tipagem: mypy. Ambos servem como bons gates de CI - fixe versões e o nível de rigor, e considere rodar os dois para cobertura máxima.

Perguntas frequentes

Por que o Pyright reporta mais erros que o mypy?
Principalmente por causa dos padrões, não de rigor. O mypy pula funções sem anotação a menos que você passe --check-untyped-defs ou --strict, enquanto o Pyright verifica todo o código por padrão e infere tipos de retorno onde o mypy assume Any. Rode mypy --check-untyped-defs e a diferença encolhe muito.
O Pyright é mais rápido que o mypy?
A documentação do Pyright diz 3x a 5x mais rápido em bases grandes, mas esse número é anterior aos builds do mypy compilados com mypyc e ao seu trabalho de otimização da 1.18, e comparações independentes recentes encontram o mypy atual competitivo. Faça benchmark no seu repositório em vez de confiar em qualquer das duas afirmações.
O Pyright suporta plugins do mypy?
Não. O Pyright não tem sistema de plugins algum. Se você depende do django-stubs ou de plugins de mypy do SQLAlchemy para entender atributos de modelo gerados dinamicamente, esse requisito decide a comparação sozinho.
O que o modo strict do Pyright muda de fato?
Ele habilita cerca de 30 regras adicionais sobre um padrão que já verifica tudo, incluindo exigir anotações em todos os parâmetros e retornos de função. Equipes costumam ver um aumento de cerca de 10x nos erros reportados, então habilite por diretório em vez de no repositório inteiro.
Devo usar mypy ou Pyright em um projeto novo?
Pyright, a menos que você esteja em Django ou SQLAlchemy. Ele verifica tudo por padrão, tem melhor comportamento de inferência em unions e tipos literais, e fornece o language server por trás do Pylance, então o seu editor e o seu checker concordam.
O que são ty e Pyrefly?
Type checkers Python mais novos, construídos para velocidade. O Pyrefly, da Meta, chegou ao 1.0 estável em maio de 2026 e reporta ser 10-50x mais rápido que mypy e Pyright em bases grandes. O ty, da Astral, ainda estava em alfa em meados de 2026. Vale acompanhar os dois; nenhum tem ainda a maturidade de ecossistema do mypy ou do Pyright.
Posso usar Pyright no editor e mypy no CI?
Sim, e é uma divisão comum: inferência do Pyright enquanto você digita via Pylance, cobertura de plugins do mypy como o portão imposto. O custo são duas configurações que precisam ser mantidas em acordo, e as diferenças de inferência significam que elas podem discordar de verdade sobre o mesmo código.
Como paro falhas de type check em código que ninguém mudou?
Fixe a versão do checker no CI. As duas ferramentas adicionam regras e refinam a inferência em releases menores, então um checker sem versão fixa faz uma atualização de dependência não relacionada deixar o build vermelho. Fixe, e atualize deliberadamente como um pull request próprio.

Guias relacionados