3 pontos por GN⁺ 2024-04-28 | 1 comentários | Compartilhar no WhatsApp

PEP 686 - Definindo o modo UTF-8 como padrão a partir do Python 3.15

  • O UTF-8 está se tornando de fato a codificação de texto padrão
    • A codificação padrão dos arquivos-fonte Python é UTF-8
    • JSON, TOML e YAML usam UTF-8
    • A maioria dos editores de texto, como Visual Studio Code e o Bloco de Notas do Windows, usa UTF-8 por padrão
    • A maioria dos sites e dos dados textuais na internet usa UTF-8
    • Muitas outras linguagens de programação populares, como Node.js, Go, Rust e Java, também usam UTF-8 por padrão
  • Alterar a codificação padrão para UTF-8 facilita a interoperabilidade do Python com outras linguagens
  • Muitos desenvolvedores Python que usam Unix esquecem que a codificação padrão varia de acordo com a plataforma
    • Ao ler arquivos de texto codificados em UTF-8 (JSON, TOML, Markdown, arquivos-fonte Python etc.), não especificam encoding="utf-8"
    • Muitas falhas ocorrem por causa da inconsistência da codificação padrão

Principais mudanças do PEP 686

  • A partir do Python 3.15, o modo UTF-8 será ativado por padrão
    • Os usuários ainda poderão desativar o modo UTF-8 definindo PYTHONUTF8=0 ou -X utf8=0
  • Adição de locale.getencoding()
    • API para obter a codificação do locale independentemente do modo UTF-8
    • Se a opção warn_default_encoding for especificada, locale.getpreferredencoding() emitirá EncodingWarning, assim como open() (consulte o PEP 597)
  • Ajuste da opção encoding="locale"
    • TextIOWrapper deve usar a codificação do locale mesmo no modo UTF-8 quando encoding="locale" for especificado

Compatibilidade retroativa

  • Como a maioria dos sistemas Unix usa locale UTF-8 e o Python ativa o modo UTF-8 quando o locale é C ou POSIX, essa mudança afeta principalmente usuários do Windows
  • Se um programa Python depende da codificação padrão, essa mudança pode causar UnicodeError, texto corrompido ou corrupção silenciosa de dados
  • Diretrizes para resolver problemas de compatibilidade retroativa:
    1. Desativar o modo UTF-8
    2. Usar EncodingWarning (PEP 597) para encontrar todos os pontos afetados pelo modo UTF-8
      • Quando a opção encoding for omitida, considerar usar encoding="utf-8" ou encoding="locale"
      • Quando locale.getpreferredencoding() for usado, considerar usar "utf-8" ou locale.getencoding()
    3. Testar a aplicação com o modo UTF-8

Opinião do GN⁺

  • Este PEP tem como objetivo padronizar a codificação padrão do Python em UTF-8 para aumentar a interoperabilidade com outras linguagens e sistemas. Isso deve ajudar o Python a ser usado de forma mais fluida em ambientes de desenvolvimento globais
  • No entanto, essa mudança pode afetar a compatibilidade retroativa de programas Python existentes. É preciso atenção especial, sobretudo em programas executados em ambientes Windows
  • Os desenvolvedores devem usar EncodingWarning para identificar as partes afetadas e responder a isso explicitando a opção encoding, entre outras medidas
  • No longo prazo, espera-se que essa mudança tenha um impacto positivo no ecossistema Python. Porém, no curto prazo, alguns projetos podem ter custos de migração
  • Ao planejar a atualização para o Python 3.15, os desenvolvedores devem considerar essa mudança e, se necessário, adotar medidas adequadas para manter a compatibilidade retroativa

1 comentários

 
GN⁺ 2024-04-28
Comentários do Hacker News
  • O fato de a codificação padrão de arquivos de texto do Python variar conforme a plataforma é um problema há muito tempo
  • A questão da codificação do sistema de arquivos é separada e não é tratada nesta mudança
  • Depender do padrão do sistema não é uma boa ideia, porque ele pode ser diferente do que se supõe
  • Houve problemas no passado com Ubuntu e scripts init.d. Scripts de execução Java rodando como root usavam uma codificação diferente da de usuários comuns, causando problemas
  • Hoje isso é menos problemático, mas ainda assim deve-se evitar deixar isso a cargo do sistema operacional. Usar uma codificação diferente de UTF-8 provavelmente não é intencional
  • Não é bom não especificar isso explicitamente e depender da configuração do sistema operacional
  • Esta mudança vai na direção certa. É melhor corrigir de forma simples o código que quebrar
  • Parece melhor do que deixar as coisas como estão, com a possibilidade de bugs de corrupção de conteúdo

Regra prática que, ao longo das últimas décadas, tem se tornado cada vez mais verdadeira: se a configuração de "charset" não for UTF-8, ela está errada

  • O Python 2 sempre funcionava bem por não se importar com charset, mas as melhorias do Python 3 foram mais do que apenas melhorias

  • Como distinguir um script Python 3 de um script Python 2:

    • se tiver a string "utf-8", é Python 3
    • se só funcionar no locale C.UTF-8, é Python 3
  • Esta mudança é bem-vinda e parece que vai "melhorar" o Python 3

  • Eu achava que isso já era o padrão desde o Python 3

Muitas linguagens populares, incluindo Node.js, Go, Rust e Java, usam UTF-8 por padrão

  • Eu não sabia que o Java tinha migrado de UTF-16 para UTF-8

  • Não sei se a codificação interna do CPython é UTF-8

  • Strings em Python podem ser indexadas, mas acesso aleatório é raro, então talvez faça sentido indexar sob demanda quando necessário

  • Se só for preciso avançar ou retroceder um caractere por vez, não é necessário índice

  • Portanto, parece possível usar uma representação interna em UTF-8

  • Por que não utf-8-sig? Ele trata BOM de forma opcional, o que é útil

  • Já que estamos falando de UTF-8, o framebuffer do Linux já deveria ter suporte adequado a UTF-8 há muito tempo

  • O GNU Hurd já tinha um 'terminal console' melhor com suporte a UTF-8 por volta de 2007

  • E só agora, em 2024, uma mudança dessas acontece

  • Boa mudança. Agora só falta o JS migrar para UTF-8, mas é difícil melhorar isso porque precisa manter compatibilidade com código escrito em 1995

Muitos desenvolvedores Unix de Python esquecem que a codificação padrão varia de plataforma para plataforma e não especificam encoding="utf-8" ao ler arquivos de texto em UTF-8

  • Em vez de "esquecem", parece mais que não percebem isso corretamente
  • Eu achava que, a menos que se pedisse explicitamente outra coisa, o Python usaria UTF-8 em todo lugar