Escrever e fazer lint em Python em escala

O trabalho da Meta no Fixit 2, um linter Python com auto-correção construído sobre libcst, leva a uma análise mais ampla de como fazer Python funcionar em grande escala por meio de ferramentas mais fortes, anotações de tipo e transformação automática de código. Os comentaristas contrastam o ecossistema crescente de tipagem estática e linters do Python (incluindo Ruff e Fixit) com linguagens como TypeScript e C#, debatendo se linguagens dinâmicas são bases adequadas para sistemas grandes ou apenas sustentadas por ferramentas “paliativas”. Outros se concentram em trocas práticas: a facilidade de depuração e o desenvolvimento rápido do Python versus seus limites de desempenho, problemas de threading e a qualidade desigual de type hints e bibliotecas em bases de código reais.

Contexto & Ferramentas Discutidas

  • A discussão se concentra no linter Python Fixit 2 da Meta, construído sobre libcst, e em experiências mais amplas com linting e tipagem em Python em escala.
  • A característica notável do Fixit 2: regras de lint que podem aplicar mudanças de código automaticamente, e não apenas reportar problemas.

Confiança e Fluxo de Trabalho para Linters com Auto-Correção

  • Alguns desconfiam de linters que alteram o código automaticamente além de formatação/imports.
  • Outros apontam para ecossistemas como C#/.NET, ESLint e Rubocop, onde o auto-fix é padrão e produtivo, especialmente quando:
    • As correções são aplicadas após o commit ou via revisão de código com aceitação explícita.
    • Apenas categorias “seguras” de correções são aplicadas automaticamente.
  • Fluxo de trabalho sugerido: faça o commit primeiro, execute o auto-fix e então inspecione o diff.

Ruff vs Flake8 e Outros Linters

  • Ruff é elogiado por:
    • Velocidade muito alta.
    • Consolidar formatação, linting e ordenação de imports em uma única ferramenta.
    • Detectar problemas que alguns plugins do flake8 deixam passar.
  • Críticas:
    • Inconsistência com os plugins originais do flake8 em bases de código legadas, grandes e bagunçadas.
    • Alguns auto-fixes antes introduziam novos problemas; versões mais recentes do Ruff distinguem correções “seguras” de “inseguras”.
  • Os mantenedores do Ruff (na discussão) dizem:
    • O objetivo é igualar ou superar a correção dos plugins e eles acolhem relatórios de bugs.
    • O processo de lint/fix é iterativo até que não restem mais problemas corrigíveis.
  • Vários comentaristas relatam adoção bem-sucedida do Ruff em muitos projetos com poucos problemas.

Python em Escala: Tipagem Dinâmica vs Estática

  • Há forte discordância sobre se Python (e linguagens “dinâmicas de script” semelhantes) são adequadas para sistemas grandes:
    • Críticos: empresas grandes acabam recriando tipagem estática e ferramentas pesadas; linguagens estáticas hoje prototipam rápido o suficiente para que começar com linguagens dinâmicas seja um erro.
    • Defensores: o sistema de tipos opcional do Python, tipos soma, pattern matching e verificadores externos o tornam viável e cada vez mais “seguro”.
  • Uma longa subdiscussão debate a terminologia (“linguagem dinâmica”, “tipagem dinâmica”) e detalhes de teoria dos tipos: tipos recursivos (JSON), generics variádicos, concatenação de tuplas e comparação com TypeScript e Haskell.

Forças e Fraquezas do Python

  • Os defensores destacam:
    • Facilidade de depuração e erros de runtime claros.
    • Boa sintaxe e adequação ao ensino.
    • Anotações de tipo melhorando a escalabilidade de bases de código grandes.
  • Os críticos argumentam:
    • Python nunca é a “melhor” ferramenta em termos de mérito de engenharia; popularidade e ferramentas paliativas dominam.
    • Desempenho e threading (GIL) continuam sendo limites reais de escala; as soluções alternativas muitas vezes envolvem subprocessos.

Desejo por Ferramentas Unificadas

  • Alguns querem uma única ferramenta para formatação, linting, ordenação e verificações de pre-commit, valorizando mais a consistência do que detalhes de estilo.
  • Ruff é visto como um candidato promissor; seu financiamento é considerado um possível acelerador rumo à coerência de “uma ferramenta só”, inclusive possivelmente substituindo o atual ecossistema fragmentado de pre-commit.