本文へ移動
技術を、自社の仕事に。
判断と実行を助けるメディア

記事を検索

Python 3.15のUTF-8既定化とCP932のCSV

目次 · 7項目

基幹システムから書き出した受注データのCSVを、Windows のPCで動く Python のスクリプトで集計している。毎朝の作業はこれまで問題なく動いていたのに、PCを入れ替えたり Python を入れ直したりした翌日から UnicodeDecodeError で止まる。2026年10月9日に公開された Python 3.15 では、こうした止まり方が起こり得ます。

3.15 から、open() などで encoding を指定しなかったときの文字コードが、Windows を含むすべての環境で UTF-8 になりました。3.14 までの Windows では、PCのロケール(ANSIコードページ)の文字コードが使われていました。CP932 で書かれたファイルを encoding なしで読んでいたスクリプトは、ここで挙動が変わります。Python のリポジトリの文書で変更点を確かめ、手元で再現した結果から、確かめ方と直し方を整理します。

3.15で変わったこと

v3.15.0 のタグにある「What’s new in Python 3.15」は、冒頭で「Python 3.15 was released on 9 October 2026.」とし、主な変更の1つに「UTF-8 as the default encoding」を挙げています。本文は次のとおりです。

Python now uses UTF-8 as the default encoding, independent of the system’s environment. This means that I/O operations without an explicit encoding, for example, open('flying-circus.txt'), will use UTF-8.

この変更は PEP 686「Make UTF-8 mode default」によるもので、3.7 から選んで有効にできた「UTF-8 モード」が既定で有効になったものです。PEP は、ファイルに加えて標準入出力とパイプも UTF-8 になると説明し、影響の範囲を次のように書いています。

Most Unix systems use UTF-8 locale and Python enables UTF-8 mode when its locale is C or POSIX. So this change mostly affects Windows users.

さらに「this change may cause UnicodeError, mojibake, or even silent data corruption」とも書いています。読み込みが止まるだけでなく、書き出したファイルの文字コードが変わって、受け取る側で文字化けすることもあり得る、という意味です。

3.14までと3.15の比較。encodingを指定しないopen()は、3.14までのWindowsではロケールの文字コード(ANSIコードページ)、3.15ではUTF-8になる。CP932のCSVを読むとUnicodeDecodeErrorになり、書き出すファイルはUTF-8になる。対処はencodingの明示(cp932、utf-8、locale)で、一時的にはPYTHONUTF8=0で以前の挙動に戻せる

手元で再現した

この記事の検証環境には Python 3.15 を用意できなかったため、Linux 上の Python 3.11.17 で UTF-8 モードを有効にし(-X utf8=1)、3.15 の既定の状態を再現しました。CP932 で書いた次のCSVを用意しています。

受注番号,得意先,金額
1001,株式会社サンプル,12000
1002,髙橋商店,8000

encoding を指定せずに読むスクリプトを実行すると、1文字目で止まりました。

$ python3 -X utf8=1 read_orders.py orders_cp932.csv
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8e in position 0: invalid start byte

encoding='cp932' を指定すると、「髙」のような文字も含めて読めました。

$ python3 -X utf8=1 -c "import csv; print(list(csv.reader(open('orders_cp932.csv', encoding='cp932', newline='')))[2])"
['1002', '髙橋商店', '8000']

書き出す側も変わります。同じ UTF-8 モードで open('out.csv', 'w') に「得意先」と書くと、ファイルの中身は UTF-8 のバイト列(e5 be 97 e6 84 8f e5 85 88)になりました。これまで CP932 で受け取っていた別のシステムや取り込み処理があれば、そちらで文字化けします。

再現は Linux 上で行ったもので、Windows の PC で 3.14 と 3.15 を比べたものではありません。3.14 までの Windows で何の文字コードが使われるかは、対象のPCで次のコマンドを実行すると確認できます。Python のドキュメントは、Windows では locale.getencoding() が ANSI コードページを返すと説明しています。

python -c "import locale; print(locale.getencoding())"

ここで cp932 と表示されるPCで encoding なしの読み書きをしているスクリプトが、今回の確認の対象です。

影響する箇所を洗い出す

PEP 686 は、互換性の問題への対処として、UTF-8 モードを無効にしたうえで EncodingWarning を使って影響する場所を探すことを挙げています。3.10 以降なら、-X warn_default_encoding を付けて実行すると、encoding を省略した箇所で警告が出ます。

$ python3 -X utf8=0 -X warn_default_encoding read_orders.py orders_utf8.csv
read_orders.py:2: EncodingWarning: UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.
read_orders.py:3: EncodingWarning: 'encoding' argument not specified

1行目は locale.getpreferredencoding() を呼んでいる行、2行目は encoding を省略した open() の行で出た警告です。行番号付きで出るため、修正の一覧をそのまま作れます。警告は実際に通った行でしか出ないので、普段は動かない分岐(月末だけの処理など)は、ソースの検索で補います。

grep -rnE "open\(|read_text\(|write_text\(|text=True|universal_newlines|getpreferredencoding" --include=*.py .

subprocess の text=True も対象です。PEP 686 は、パイプでこれまでの文字コードを使いたい場合、text=True を encoding="utf-8" か encoding="locale" の明示に置き換えるまでは、UTF-8 モードを無効にしてしのぐよう書いています。

直し方

  1. ファイルの文字コードが決まっているなら、そのまま書く。 CP932 のCSVなら encoding='cp932'、UTF-8 なら encoding='utf-8'。What’s new も「ensure that an explicit encoding argument is always provided」と勧めています
  2. PCのロケールに合わせたい場合は encoding='locale'。 3.10 から使える指定で、UTF-8 モードでもロケールの文字コードを使います
  3. すぐに直せない場合は、環境変数 PYTHONUTF8=0 か -X utf8=0 で以前の挙動に戻す。 タスクスケジューラーなどから起動している場合は、その起動の設定に加えます。あくまで修正までのつなぎとして使います

書き出す側は、受け取る相手の決まりに合わせて encoding を明示します。CSVの文字コードと改行、BOMの扱いをどう取り決めるかはCSVを配るのは難しい — 業務データ受け渡しの設計で詳しく整理しています。

いつまでに直すか

3.15 への更新を急ぐ必要はありません。PEP 790(3.15 のリリース計画)によると、3.15 はおよそ2年間バグ修正が提供され、その後は2031年10月ごろまでセキュリティ修正が続きます。3.14 以前もそれぞれの期限まで使えます。

注意したいのは、意図せず 3.15 になる場面です。PCの入れ替え、Python の入れ直し、CI やコンテナのイメージの更新で、最新の版が入ることがあります。編集部としては、3.15 に上げる予定がなくても、encoding の明示だけは先に済ませておくことを勧めます。どの版でも同じ結果になるため、更新のときに慌てずに済みます。

依存パッケージの更新もあわせて進めるなら、脆弱性の確認はuv audit でPythonの依存脆弱性を継続チェックする、公開直後の版を避ける設定はPip 26.1 Dependency Cooldownsで扱っています。

確認した範囲

2026年10月11日に、python/cpython の v3.15.0 タグの Doc/whatsnew/3.15.rst・Doc/library/os.rst・Doc/library/locale.rst・Include/patchlevel.h(PY_VERSION "3.15.0"、リリースレベル FINAL)と、python/peps の PEP 686・PEP 790 を raw.githubusercontent.com から取得して確認しました(資料調査)。あわせて Linux 上の Python 3.11.17 で UTF-8 モードを有効・無効にして、CP932 と UTF-8 のCSVの読み込み、書き出したファイルのバイト列、-X warn_default_encoding の警告を確かめました(実機検証)。2026年10月16日には python.org の 3.15.0 のリリースページ(Release date: Oct. 9, 2026、主な変更に PEP 686)も確認しました。Python 3.15 そのものと Windows の PC では試していません。

社内で動いているスクリプトの棚卸しや、CSV連携の作り直しは、開発・AI・自動化のご相談からお問い合わせください。

参考資料

この記事を共有XFacebook
鈴木 翔

技術の可能性に魅了され、学生時代からプログラミングとデジタルアートの分野に深い関心を持つ

この記事のテーマを、自社の次の一歩へ

自社での進め方を、具体的に。

つくりたい仕組み、既存システム、運用の条件を整理し、実現に向けた次の一歩を考えます。

  • 実現したい仕組み
  • 既存環境との接続
  • 運用の条件
開発・運用の構想を相談する

構想段階からご相談いただけます。この記事の情報を相談フォームに引き継ぎます。

最新記事をメールで受け取る