PEP 686 - Python 3.15からUTF-8モードをデフォルトで有効化
- UTF-8が事実上の標準テキストエンコーディングになりつつある
- PythonソースファイルのデフォルトエンコーディングはUTF-8
- JSON、TOML、YAMLはUTF-8を使用
- Visual Studio Code、Windowsメモ帳など、ほとんどのテキストエディタはデフォルトでUTF-8を使用
- ほとんどのWebサイトやインターネット上のテキストデータはUTF-8を使用
- Node.js、Go、Rust、Javaなど、多くの人気プログラミング言語もデフォルトでUTF-8を使用
- デフォルトエンコーディングをUTF-8に変更すると、Pythonが他の言語と相互運用しやすくなる
- 多くのUnix系Python開発者は、デフォルトエンコーディングがプラットフォームによって異なるという事実を忘れがち
- UTF-8でエンコードされたテキストファイル(JSON、TOML、Markdown、Pythonソースファイルなど)を読むときに
encoding="utf-8" を指定しない
- 一貫しないデフォルトエンコーディングにより多くのバグが発生する
PEP 686の主な変更点
- Python 3.15からUTF-8モードがデフォルトで有効になる
- ユーザーは引き続き
PYTHONUTF8=0 または -X utf8=0 を設定してUTF-8モードを無効化できる
locale.getencoding() を追加
- UTF-8モードに関係なくロケールエンコーディングを取得するためのAPI
warn_default_encoding オプションが指定されると、locale.getpreferredencoding() は open() と同様に EncodingWarning を発生させる(PEP 597参照)
encoding="locale" オプションを修正
TextIOWrapper は encoding="locale" が指定された場合、UTF-8モードでもロケールエンコーディングを使用する必要がある
後方互換性
- ほとんどのUnixシステムはUTF-8ロケールを使用しており、PythonはロケールがCまたはPOSIXのときにUTF-8モードを有効にするため、この変更は主にWindowsユーザーに影響する
- Pythonプログラムがデフォルトエンコーディングに依存している場合、この変更によって
UnicodeError、文字化け、または静かなデータ破損が発生する可能性がある
- 後方互換性の問題を解決するための指針:
- UTF-8モードを無効化する
EncodingWarning(PEP 597)を使ってUTF-8モードの影響を受けるすべての箇所を見つける
encoding オプションが省略されている場合は、encoding="utf-8" または encoding="locale" の使用を検討
locale.getpreferredencoding() が使われている場合は、"utf-8" または locale.getencoding() の使用を検討
- UTF-8モードでアプリケーションをテストする
GN⁺の意見
- このPEPは、PythonのデフォルトエンコーディングをUTF-8に統一し、他の言語やシステムとの相互運用性を高めることを目的としている。これにより、Pythonがグローバルな開発環境でより円滑に使えるようになるはず
- ただし、この変更は既存のPythonプログラムの後方互換性に影響する可能性がある。特にWindows環境で動作するプログラムでは注意が必要
- 開発者は
EncodingWarning を活用して影響を受ける箇所を特定し、encoding オプションを明示的に指定するなどの方法で対応する必要がある
- 長期的には、この変更はPythonエコシステムに好影響を与えると予想される。ただし短期的には、一部のプロジェクトで移行コストが発生する可能性がある
- 開発者はPython 3.15へのアップグレードを計画する際、この変更点を考慮し、必要に応じて後方互換性のための適切な対策を講じるべき
1件のコメント
Hacker Newsの意見
init.dスクリプトで問題があった。rootとして実行されるJava実行スクリプトが一般ユーザーと異なるエンコーディングを使い、問題が発生したPython 2はcharsetに縛られず常にうまく動いていたが、Python 3の改善は改善以上のものだった
Python 3スクリプトとPython 2スクリプトを見分ける方法:
"utf-8"という文字列があればPython 3C.UTF-8ロケールでしか動かなければPython 3今回の変更は歓迎すべきもので、Python 3を「改善」するように見える
これはPython 3からデフォルトだったと思っていた
JavaがUTF-16からUTF-8へ移行したのは知らなかった
CPythonの内部エンコーディングがUTF-8なのかは分からない
Pythonの文字列はインデックス参照が可能だが、ランダムアクセスはまれなので、必要なときに遅延インデックス化するのがよさそう
1文字ずつ前後に移動するだけならインデックスは不要
したがって、内部的にUTF-8表現は可能だと思われる
なぜ
utf-8-sigではないのか? BOMを選択的に処理してくれるので便利UTF-8に関連して言えば、Linuxフレームバッファはずっと前からまともなUTF-8サポートを備えているべきだった
GNU Hurdは2007年ごろから、UTF-8をサポートするより良い「ターミナルコンソール」を持っていた
2024年になってようやくこうした変化が来るとは
良い変化。あとはJSだけがUTF-8に移行すればよいが、1995年に書かれたコードとの互換性を保たなければならず、改善が難しい