3 points par GN⁺ 2024-04-28 | 1 commentaires | Partager sur WhatsApp

PEP 686 - Le mode UTF-8 sera activé par défaut à partir de Python 3.15

  • L’UTF-8 est en train de devenir de facto l’encodage de texte standard
    • L’encodage par défaut des fichiers source Python est l’UTF-8
    • JSON, TOML et YAML utilisent l’UTF-8
    • La plupart des éditeurs de texte, comme Visual Studio Code et le Bloc-notes de Windows, utilisent l’UTF-8 par défaut
    • La majorité des sites web et des données textuelles sur Internet utilisent l’UTF-8
    • De nombreux autres langages de programmation populaires, comme Node.js, Go, Rust et Java, utilisent eux aussi l’UTF-8 par défaut
  • Le passage de l’encodage par défaut à l’UTF-8 facilite l’interopérabilité de Python avec les autres langages
  • Beaucoup de développeurs Python sur Unix oublient que l’encodage par défaut varie selon la plateforme
    • Ils ne précisent pas encoding="utf-8" lorsqu’ils lisent des fichiers texte encodés en UTF-8 (JSON, TOML, Markdown, fichiers source Python, etc.)
    • Cet encodage par défaut incohérent est à l’origine de nombreux bugs

Principaux changements de la PEP 686

  • À partir de Python 3.15, le mode UTF-8 sera activé par défaut
    • Les utilisateurs pourront toujours désactiver le mode UTF-8 avec PYTHONUTF8=0 ou -X utf8=0
  • Ajout de locale.getencoding()
    • Une API pour obtenir l’encodage de la locale, indépendamment du mode UTF-8
    • Si l’option warn_default_encoding est définie, locale.getpreferredencoding() émettra un EncodingWarning comme open() (voir PEP 597)
  • Modification de l’option encoding="locale"
    • TextIOWrapper devra utiliser l’encodage de la locale même en mode UTF-8 lorsque encoding="locale" est spécifié

Compatibilité descendante

  • La plupart des systèmes Unix utilisent une locale UTF-8, et Python active déjà le mode UTF-8 lorsque la locale est C ou POSIX, donc ce changement affectera surtout les utilisateurs de Windows
  • Si un programme Python dépend de l’encodage par défaut, ce changement peut provoquer des UnicodeError, du texte illisible ou une corruption silencieuse des données
  • Recommandations pour résoudre les problèmes de compatibilité descendante :
    1. Désactiver le mode UTF-8
    2. Utiliser EncodingWarning (PEP 597) pour repérer tous les endroits affectés par le mode UTF-8
      • Si l’option encoding est omise, envisager d’utiliser encoding="utf-8" ou encoding="locale"
      • Si locale.getpreferredencoding() est utilisé, envisager d’utiliser "utf-8" ou locale.getencoding()
    3. Tester l’application en mode UTF-8

L’avis de GN⁺

  • Cette PEP vise à unifier l’encodage par défaut de Python autour de l’UTF-8 afin d’améliorer l’interopérabilité avec les autres langages et systèmes. Cela devrait permettre à Python d’être utilisé plus fluidement dans un environnement de développement global
  • Cependant, ce changement peut affecter la compatibilité descendante des programmes Python existants. Une attention particulière est nécessaire, surtout pour les programmes exécutés sous Windows
  • Les développeurs devront s’appuyer sur EncodingWarning pour identifier les zones concernées, et réagir en explicitant l’option encoding, entre autres mesures
  • À long terme, ce changement devrait avoir un impact positif sur l’écosystème Python. À court terme, toutefois, certains projets pourraient devoir supporter un coût de migration
  • Les développeurs qui prévoient une mise à niveau vers Python 3.15 devront prendre ce changement en compte et, si nécessaire, mettre en place des mesures adaptées pour préserver la compatibilité descendante

1 commentaires

 
GN⁺ 2024-04-28
Avis Hacker News
  • Le fait que l’encodage par défaut des fichiers texte de Python varie selon la plateforme est un problème depuis longtemps
  • Les problèmes d’encodage du système de fichiers sont distincts et ne sont pas traités par ce changement
  • Il n’est pas bon de dépendre de la valeur par défaut du système, car elle peut être différente de ce qu’on suppose
  • Il y a eu des problèmes autrefois avec Ubuntu et les scripts init.d. Des scripts de lancement Java exécutés en tant que root utilisaient un encodage différent de celui des utilisateurs ordinaires, ce qui causait des problèmes
  • C’est moins problématique aujourd’hui, mais il faut éviter de laisser cela à l’OS. L’utilisation d’un encodage autre que l’UTF-8 est probablement non intentionnelle
  • Ce n’est pas une bonne idée de ne rien spécifier explicitement et de dépendre des réglages de l’OS
  • Ce changement va dans le bon sens. Mieux vaut corriger simplement le code qui casse
  • C’est préférable à laisser subsister un risque de bug de corruption des données

Règle empirique devenue de plus en plus vraie au cours des dernières décennies : si le paramètre "charset" n’est pas UTF-8, alors il est erroné

  • Python 2 fonctionnait toujours bien sans se soucier du charset, mais les améliorations de Python 3 ont été plus qu’une simple amélioration

  • Façon de distinguer un script Python 3 d’un script Python 2 :

    • s’il contient la chaîne "utf-8", c’est du Python 3
    • s’il ne fonctionne que dans la locale C.UTF-8, c’est du Python 3
  • Ce changement est bienvenu et semble devoir "améliorer" Python 3

  • Je pensais que c’était la valeur par défaut depuis Python 3

De nombreux langages populaires, dont Node.js, Go, Rust et Java, utilisent UTF-8 par défaut

  • Je ne savais pas que Java était passé de l’UTF-16 à l’UTF-8

  • Je ne sais pas si l’encodage interne de CPython est l’UTF-8

  • Les chaînes Python sont indexables, mais l’accès aléatoire est rare, donc il vaudrait peut-être mieux faire une indexation paresseuse quand c’est nécessaire

  • Si l’on ne fait que se déplacer d’un caractère à l’autre, dans un sens ou dans l’autre, il n’y a pas besoin d’index

  • Il semble donc qu’une représentation interne en UTF-8 soit possible

  • Pourquoi pas utf-8-sig ? C’est utile car cela gère le BOM de manière optionnelle

  • Concernant l’UTF-8, le framebuffer Linux aurait dû disposer d’un vrai support UTF-8 depuis longtemps

  • GNU Hurd avait un meilleur "terminal console" prenant en charge l’UTF-8 dès 2007 environ

  • Et ce n’est qu’en 2024 que ce genre de changement arrive

  • Bon changement. Il ne reste plus qu’à faire passer JS à l’UTF-8, mais c’est difficile à améliorer puisqu’il faut rester compatible avec du code écrit en 1995

Beaucoup de développeurs Python sous Unix oublient que l’encodage par défaut diffère selon les plateformes et n’indiquent pas encoding="utf-8" lorsqu’ils lisent des fichiers texte UTF-8

  • Plus qu’un "oubli", j’ai l’impression qu’ils n’en ont tout simplement pas bien conscience
  • Je pensais que Python n’utiliserait que l’UTF-8 partout, sauf demande explicite contraire