python pip install で、UnicodeDecodeError が発生


VPS の移行中、pip install を実行したところ、下記のエラーが発生しました。
対処法を記載します。

  • 実行したコマンド

    python3.6 -m pip install git+https://github.com/kemsakurai/django-critical
    

  • エラー内容

    Collecting git+https://github.com/kemsakurai/django-critical
      Cloning https://github.com/kemsakurai/django-critical to /tmp/pip-sctm4huk-build
        Complete output from command python setup.py egg_info:
        Traceback (most recent call last):
          File "<string>", line 1, in <module>
          File "/tmp/pip-sctm4huk-build/setup.py", line 23, in <module>
            readme = open('README.rst').read()
          File "/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
            return codecs.ascii_decode(input, self.errors)[0]
        UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 2437: ordinal not in range(128)
    
        ----------------------------------------
    Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-sctm4huk-build/
    


前提

OS、Python の Version は以下の通りです。

  • OS

    cat /etc/redhat-release
    ---------------------------------------------
    CentOS Linux release 7.4.1708 (Core) 
    ---------------------------------------------
    

  • Python の Version

    python3.6 -V
    ---------------------------------------------
    Python 3.6.4
    ---------------------------------------------
    


原因

locale
---------------------------------------------
LANG=C
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=
---------------------------------------------
LANG=C になっています。

  • setup.py で 明示的に、デコードを指定する
    Python3 自体に、LANG設定が行われていない、且つ、README.rstに ASCII 以外の文字が含まれていると、インストールが失敗するようです。
    codecs を使って明示的に utf-8 としてデコードすることができます。

同様の問題にぶつかったライブラリでは、setup.py 内で codec を import して、utf-8 指定でファイルを開いています。
setup.py: Decode README.rst as utf-8 by Graziano · Pull Request #73 · keleshev/schema


言語設定を変更して再度、install してみる

言語設定を、LANG=Cから、LANG=ja_JP.utf8 に変更します。

  • Locale の確認

    localectl status
    ---------------------------------------------
       System Locale: LANG=C
           VC Keymap: jp106
          X11 Layout: jp
    ---------------------------------------------
    

  • Locale の変更

    localectl set-locale LANG=ja_JP.utf8
    

  • Locale の確認

    localectl status
    ---------------------------------------------
       System Locale: LANG=ja_JP.utf8
           VC Keymap: jp106
          X11 Layout: jp
    ---------------------------------------------
    

  • インストール実行

    python3.6 -m pip install git+https://github.com/kemsakurai/django-critical
    ---------------------------------------------
    Collecting git+https://github.com/kemsakurai/django-critical
      Cloning https://github.com/kemsakurai/django-critical to /tmp/pip-oll72dhd-build
        Complete output from command python setup.py egg_info:
        Traceback (most recent call last):
          File "<string>", line 1, in <module>
          File "/tmp/pip-oll72dhd-build/setup.py", line 23, in <module>
            readme = open('README.rst').read()
          File "/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
            return codecs.ascii_decode(input, self.errors)[0]
        UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 2437: ordinal not in range(128)
    
        ----------------------------------------
    Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-oll72dhd-build/
    ---------------------------------------------
    
    失敗しました。
    一度ログアウトして、再度ログイン後、実行してみます。
    python3.6 -m pip install git+https://github.com/kemsakurai/django-critical
    ---------------------------------------------
    Collecting git+https://github.com/kemsakurai/django-critical
      Cloning https://github.com/kemsakurai/django-critical to /tmp/pip-0ckc3mj4-build
    Collecting django-appconf>=0.4 (from django-critical==0.1.1)
      Downloading django_appconf-1.0.2-py2.py3-none-any.whl
    Collecting cssmin>=0.2.0 (from django-critical==0.1.1)
      Downloading cssmin-0.2.0.tar.gz
    Installing collected packages: django-appconf, cssmin, django-critical
      Running setup.py install for cssmin ... done
      Running setup.py install for django-critical ... done
    Successfully installed cssmin-0.2.0 django-appconf-1.0.2 django-critical-0.1.1
    ---------------------------------------------
    
    成功しました。

setup.py も修正しておいたほうがいいと思いますが、個人的に使っているオレオレライブラリなので、とりあえずそのままにしておきます。
以上です。

コメント