본문 바로가기
Computer/Python

Windows python pip install 명령 사용시 UnicodeDecodeError 처리

by DogBull 2016. 12. 30.

  윈도우에서 바로 사용할 수 있도록 미리 컴파일된 파이썬 바이너리 패키지를 제공하는 사이트(http://www.lfd.uci.edu/~gohlke/pythonlibs/)는 초급 이상으로 넘어가는 허들을 낮춰준다. 파이썬을 사용하다 보면 pip 명령을 이용하여 패키지를 설치하게 될 텐데, 몇몇 패키지는 성능 및 기타의 이유로 C/C++로 작성된 소스코드를 바이너리로 컴파일 해야 되는 경우가 있다. 널리 사용되는 numpy, scipy, gdal 등의 패키지가 그 예이다. 하지만 컴파일러가 없거나, 컴파일러는 있지만 컴파일에 요구되는 종속성을 해결하지 못하는 등의 문제가 발생되면 앞서 언급한 사이트에서 미리 컴파일된 바이너리 패키지를 다운로드하여 설치하면 된다.


  설치 방법은 아주 간단하다. 예를들어 가장 최신의 numpy 패키지를 확인해 보면 numpy‑1.12.0rc1+mkl‑cp36‑cp36m‑win_amd64.whl 인데, 이 파일을 다운로드 한 후 아래의 명령을 실행하면 된다.

pip install numpy‑1.12.0rc1+mkl‑cp36‑cp36m‑win_amd64.whl

  리눅스에서는 yum, apt 같은 패키지 매니저로 미리 컴파일된 바이너리 패키지를 설치할 수 있다.

pip install numpy

  위 명령을 실행하면 numpy 소스코드를 이용하여 컴파일 한 후 설치를 수행하지만, 아래의 명령은 미리 컴파일된 바이너리 패키지를 바로 설치한다.

yum install numpy


  미리 컴파일된 바이너리 패키지를 이용한 패키지 설치는 여러 가지 이유로 편리하다. 컴파일러를 준비하지 않아도 되고, 컴파일 종속성 해결을 위해 관련 패키지를 찾아 헤매지 않아도 되며, 특히 컴파일에 실패했을 경우 이를 해결하는데에 소모될 수 있는 시간을 절약할 수 있다.

  단점으로는 업데이트에 신속히 대응하지 못하는 점, 원하는 버전을 설치하기 어렵다는 점, 간단한 방법인 pip install <패키지명> 으로 설치하지 못하는 점, 마지막으로 가장 중요한 pip requirement format 파일을 이용할 수 없다는 점이 있다.


  최근(2016.12.23)에 출시된 Python 3.6.0의 pip를 이용하여 gdal 패키지 설치 중 아래와 같은 오류가 발생하였다.

pip install gdal --global-option="build_ext" --global-option="-IC:\App\OSGeo4W64\include" --global-option="-LC:\App\OSGeo4W64\lib"

c:\app\python\venv\py3gdal\lib\site-packages\pip\commands\install.py:194: UserWarning: Disabling all use of wheels due to the use of --build-options / --global-options / --install-options.
  cmdoptions.check_install_build_global(options)
Collecting gdal
  Using cached GDAL-2.1.0.tar.gz
Installing collected packages: gdal
  Running setup.py install for gdal ... error
Exception:
Traceback (most recent call last):
  File "c:\app\python\venv\py3gdal\lib\site-packages\pip\compat\__init__.py", line 73, in console_to_str
    return s.decode(sys.__stdout__.encoding)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb8 in position 75: invalid start byte

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\app\python\venv\py3gdal\lib\site-packages\pip\basecommand.py", line 215, in main
    status = self.run(options, args)
  File "c:\app\python\venv\py3gdal\lib\site-packages\pip\commands\install.py", line 342, in run
    prefix=options.prefix_path,
  File "c:\app\python\venv\py3gdal\lib\site-packages\pip\req\req_set.py", line 784, in install
    **kwargs
  File "c:\app\python\venv\py3gdal\lib\site-packages\pip\req\req_install.py", line 878, in install
    spinner=spinner,
  File "c:\app\python\venv\py3gdal\lib\site-packages\pip\utils\__init__.py", line 676, in call_subprocess
    line = console_to_str(proc.stdout.readline())
  File "c:\app\python\venv\py3gdal\lib\site-packages\pip\compat\__init__.py", line 75, in console_to_str
    return s.decode('utf_8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb8 in position 75: invalid start byte

  traceback 로그의 맨 마지막 파일(c:\app\python\venv\py3gdal\lib\site-packages\pip\compat\__init__.py)의 75라인에서 발행하는 인코딩 오류 이다. 이는 컴파일러(여기에서는 Visual Studio Community 2015에 포함된 컴파일러를 사용 하였다.)에 출력하는 한글이 포함된 경고 메시지가 있는데 이를 인코딩 할 때 발생되는 오류 이다. 근본적인 해결책은 차후에 찾아보기로 하기 임시 해결 책을 제시하면, 오류가 발생되는 라인을 try로 감싸고 except발생시 다른 인코딩 방식으로 한 번 더 시도 하는 것이다.

return s.decode('utf_8')

위 오류가 발생하는 구문을 아래와 같이 변경한다.

try:
    return s.decode('utf_8')
except UnicodeDecodeError:
    return s.decode('cp949')