Python の UnicodeDecodeError に悩まされる

先日 Ubuntu を aptitude safe-upgrade でパッケージをアップデートしたら、そこで稼動している Python3 のプログラムに UnicodeDecodeError が起こるようになった。

例外のスタックトレースを追ってみると、open('/path/to/file', 'r').read() のようにして日本語テキストを含むファイルを読み込む処理で UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 ... といった例外を送出していた。
デバッグのため、OS 上で直接 python インタープリタを用いて同様の処理を実行してみたところ、エラーは起きない。よく分からないまま open() で取得したファイルオブジェクトをログ出力するようにしてみると、

<_io.TextIOWrapper name='/path/to/file' mode='r' encoding='ANSI_X3.4-1968'>

このように encoding が ANSI_X3.4-1968 になっていた。何故??
OS の LANG 環境変数は en_US.UTF-8 になっているし、今まで何も問題なかったところなのに。

このプログラムは Celery の Worker から実行されており、さらにその Celery Worker は Supervisor によって実行されている。
そこで Supervisor を通して明示的に LANG 環境変数を渡してやればいいのではないかと思い、Supervisor の設定ファイルに以下のように指定。

[supervisord]
environment=LANG="en_US.UTF-8"

そうすると、先程のファイルオブジェクトも

<_io.TextIOWrapper name='/path/to/file' mode='r' encoding='UTF-8'>

となって、エラーも起こらなくなって解決した。
それにしても OS のパッケージアップデートの何がきっかけになったのだろうか。Python3 になって Unicode 文字列からは解放されたと思ったが、この手の文字コード絡みのエラーにはやっぱり悩まされ続ける(今回は Python のせいではなかったけれど)。

Last updated on March 4, 2016