【Python】Python3でなんか日本語が処理できなくなったのでトラブルシューティング

Python
スポンサーリンク

2月ぐらいに構築したポケモン耐久調整ツールですが、なぜか4月28日ぐらいから使用できない状態となっていました。

んで、気づいたのが1週間前ぐらいだったのですが、なかなか修正に取り組む時間もなく放置してしまっておりましたが、ようやくまとまった時間が取れたので本腰を入れる。

まずはなんでおかしくなっているのかを確認しました。

 

スポンサーリンク

原因

まずは原因調査。

APIサービスを再起動してみてログに何が出てるか確認する。

BrokenFilesystemWarning: Detected a misconfigured UNIX filesystem: Will use UTF-8 as filesystem encoding instead of 'ascii'

単純に翻訳すると、

「asciiが使えないからutf-8を使うよ」

っていうエラーに見えます。

そもそもasciiを使用するような設定はしてなかったと思うのですが、なんでこんなエラーがいきなり表示されるんや?

と思い、以下のファイルを覗いてみる。

less /usr/local/lib/python3.6/site-packages/werkzeug/filesystem.py
# -*- coding: utf-8 -*-
"""
    werkzeug.filesystem
    ~~~~~~~~~~~~~~~~~~~

    Various utilities for the local filesystem.

    :copyright: 2007 Pallets
    :license: BSD-3-Clause
"""
import codecs
import sys
import warnings

# We do not trust traditional unixes.
has_likely_buggy_unicode_filesystem = (
    sys.platform.startswith("linux") or "bsd" in sys.platform
)


def _is_ascii_encoding(encoding):
    """Given an encoding this figures out if the encoding is actually ASCII (which
    is something we don't actually want in most cases). This is necessary
    because ASCII comes under many names such as ANSI_X3.4-1968.
    """
    if encoding is None:
        return False
    try:
        return codecs.lookup(encoding).name == "ascii"
    except LookupError:
        return False


class BrokenFilesystemWarning(RuntimeWarning, UnicodeWarning):
    """The warning used by Werkzeug to signal a broken filesystem. Will only be
    used once per runtime."""


_warned_about_filesystem_encoding = False


def get_filesystem_encoding():
    """Returns the filesystem encoding that should be used. Note that this is
    different from the Python understanding of the filesystem encoding which
    might be deeply flawed. Do not use this value against Python's unicode APIs
    because it might be different. See :ref:`filesystem-encoding` for the exact
    behavior.

    The concept of a filesystem encoding in generally is not something you
    should rely on. As such if you ever need to use this function except for
    writing wrapper code reconsider.
    """
    global _warned_about_filesystem_encoding
    rv = sys.getfilesystemencoding()
    if has_likely_buggy_unicode_filesystem and not rv or _is_ascii_encoding(rv):
        if not _warned_about_filesystem_encoding:
            warnings.warn(
                "Detected a misconfigured UNIX filesystem: Will use"
                " UTF-8 as filesystem encoding instead of {0!r}".format(rv),
                BrokenFilesystemWarning,
            )
            _warned_about_filesystem_encoding = True
        return "utf-8"
    return rv

たぶん、

    rv = sys.getfilesystemencoding()
    if has_likely_buggy_unicode_filesystem and not rv or _is_ascii_encoding(rv):
        if not _warned_about_filesystem_encoding:
            warnings.warn(
                "Detected a misconfigured UNIX filesystem: Will use"
                " UTF-8 as filesystem encoding instead of {0!r}".format(rv),
                BrokenFilesystemWarning,
            )
            _warned_about_filesystem_encoding = True
        return "utf-8"

この辺でasciiからutf-8に変換する処理をやってそうだなあと考えました。

簡単に読んでみると、rvという変数にデフォルト言語を格納している?みたいな感じ。

このrvがasciiになっているからおかしなことになっている・・・のかな?

というわけで

    rv = sys.getfilesystemencoding()
    print(rv) # 追記
    if has_likely_buggy_unicode_filesystem and not rv or _is_ascii_encoding(rv):
        if not _warned_about_filesystem_encoding:
            warnings.warn(
                "Detected a misconfigured UNIX filesystem: Will use"
                " UTF-8 as filesystem encoding instead of {0!r}".format(rv),
                BrokenFilesystemWarning,
            )
            _warned_about_filesystem_encoding = True
        return "utf-8"

ってやって無理やりrvの中身を表示させてみる。

ascii

あーやっぱりなーーー

原因はPython3のデフォルト言語がUTF-8ではなくasciiになっており、うまくエンコードできなかったのでその部分でエラーを吐いていたようです。

 

解決方法

では、どやってUTF-8に直すのかというと、こちらの記事が非常に参考になりました。

Python3環境で日本語を使うとUnicodeEncodeErrorが出る問題について - Qiita
背景 私の環境でpython(3.6.2)の文字列に日本語を使うとUnicodeEncodeErrorが出てしまいました。すぐ直せるだろうと軽く考えていたのですが、案外解決に手間取ったので備忘録がてら記事にしておこうと思いました...

単純に環境変数にUTF-8を設定して解決させる方法です。

上記の記事ではC.UTF-8を設定しておりましたが、私の場合は以下コマンドにてJPを設定。

export LANG="ja_JP.UTF-8

APIサービスを再起動すると、発生していたエラーは無くなりました。

よかったよかった・・・

 

まとめ

  • Python3で日本語エンコード辺りでエラーを吐いている場合は環境変数等を見直しましょう。

何故突然こんなことになったのか謎ですが、今後も発生しうると思われますので備忘録として残しておきます。

使用してくれている方々には大変ご迷惑をおかけいたしました・・・。

コメント

タイトルとURLをコピーしました