본문 바로가기

프로그래밍/Python

pip install 중에 , setup.py 에서 UnicodeDecodeError 'cp949' codec can't decode .... illegal multibyte sequence 가 발생하며 설치가 실패한다.

728x90

pip install 중에 ,setup.py 에서 UnicodeDecodeError 'cp949' codec can't decode .... illegal multibyte sequence 가 발생하며 설치가 실패한다.

파이썬에 처음 입문하고, 이런 저런 패키지(라이브러리)들을 설치해야 한다. 그런데, 간단히 성공해야 마땅한, 패키지 설치 중에 다음과 같이 UnicodeDecodeError 'cp949' codec can't decode 어쩌고 하는 에러가 발생하여, 패키지 설치가 실패하는 경우가 종종 발생한다. 여러가지 원인들 중에서, 매우 사소한 원인으로 패키지 설치가 실패하는 경우에 대해서 원인을 찾아보고, 패키지를 설치하는 방법에 대해서 알아보자.

테스트로 삼은 조건은 다음과 같다.

한국어 윈도우 환경에 python 3.6 버전을 깔았고, 여기에 inception 이라는 패키지를 깔려고 pip install inception 명령을 실행했다. 패키지 설치는 다음과 같은 에러메시지와 함께 실패한다.

(vtest) D:\PythonEnv\ws_test\inception>python --version
Python 3.6.8

(vtest) D:\PythonEnv\ws_test\inception>pip install inception
Collecting inception
  Using cached https://files.pythonhosted.org/packages/4f/4c/b5222986906ff7ba39b52b277a342eb75bf3a87c6db486236dcf7e3fdaec/inception-0.0.3.tar.gz
    ERROR: Command errored out with exit status 1:
     command: 'd:\pythonenv\vtest\scripts\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\daewon\\AppData\\Local\\Temp\\pip-install-rcgpb_on\\inception\\setup.py'"'"'; __file__='"'"'C:\\Users\\daewon\\AppData\\Local\\Temp\\pip-install-rcgpb_on\\inception\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\daewon\AppData\Local\Temp\pip-install-rcgpb_on\inception\pip-egg-info'
         cwd: C:\Users\daewon\AppData\Local\Temp\pip-install-rcgpb_on\inception\
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\daewon\AppData\Local\Temp\pip-install-rcgpb_on\inception\setup.py", line 39, in <module>
        long_description=read_description(),
      File "C:\Users\daewon\AppData\Local\Temp\pip-install-rcgpb_on\inception\setup.py", line 12, in read_description
        return fd.read()
    UnicodeDecodeError: 'cp949' codec can't decode byte 0xe2 in position 3259: illegal multibyte sequence
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
WARNING: You are using pip version 19.3; however, version 19.3.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

pip 명령으로 패키지 설치를 지시하면, pip 는 pypi 패키지 저장소로부터 inception 패키지의 최신버전 설치파일을 다운로드 받아서, 그걸 임시폴더에 풀고 설치하려 한다. pip 설치패키지는 여러가지 종류가 있는데, 이 버전의 inception 패키지의 경우에는 .tar.gz 확장자의 설치파일이 다운로드 되었다. .tar.gz 압축 파일은 파이썬(그리고 종종 c/cpp) 소스 파일들이 압축되어 들어있는 설치파일이다.

설치 진행은, .tar.gz 파일의 압축을 다시 임시폴더에 풀고, 설치 소스파일에 있는 setup.py 를 실행하며 이루어진다. 보통 setup.py 가 있는 설치파일은 python setup.py install 과 같은 명령으로 설치가 된다. 또는, 해당 폴더로 이동하여 pip install . 을 수행하면, setup.py install 이 실행되면서 설치가 되는 것이다.

지금 에러메시지에서 보면, inception 이라는 설치소스가 풀린 폴더 아래에 있는 setup.py 스크립트 파일안의 12번째 줄의 return fd.read() 부분에서 UnicodeDecodeError 가 발생한 것을 알 수 있다.

이 문제를 어떻게 해결할까?

pip install 명령 과정에서 자동으로 다운로드 받고, setup.py install 을 실행한 것을 수동으로 진행하면서, 디버깅을 할 것이다. 그리 어렵지 않다.

우선 pip download inception 이라고 하면, 동일한 에러가 발생하지만, 명령창에서 dir 명령을 해 보면 inception-0.0.3.tar.gz 이 다운로드 받아져 있을 것이다. 이 파일의 압축을 적당한 압축툴로 푼다. 파일을 잘 풀면 루트폴더에 다음과 같이 파일들이 있을 것이다.

(vtest) D:\PythonEnv\ws_test\inception>dir
 Volume in drive D is dee
 Volume Serial Number is 60E5-48F0

 Directory of D:\PythonEnv\ws_test\inception

2019-11-18  오후 09:12    <DIR>          .
2019-11-18  오후 09:12    <DIR>          ..
2019-11-18  오후 09:12    <DIR>          inception
2019-11-18  오후 09:12    <DIR>          inception.egg-info
2014-12-28  오전 02:53             9,472 PKG-INFO
2014-12-27  오후 04:52             6,663 README.rst
2014-12-28  오전 02:53               137 setup.cfg
2014-12-27  오후 05:37             1,904 setup.py
               4 File(s)         18,176 bytes
               4 Dir(s)  162,267,377,664 bytes free

적당한 폴더에 풀어서, dir 해서 위와 같이 나왔다면, 이 폴더에서 pip install . 이라고 명령을 쳐서 실행해본다. (이 때 명령을 실행하는 디렉토리에 setup.py 가 존재해야 한다.) 동일한 UnicodeDecodeError 가 뜰 것이다.

(vtest) D:\PythonEnv\ws_test\inception>pip install .
Processing d:\pythonenv\ws_test\inception
    ERROR: Command errored out with exit status 1:
     command: 'd:\pythonenv\vtest\scripts\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\daewon\\AppData\\Local\\Temp\\pip-req-build-g5k8484g\\setup.py'"'"'; __file__='"'"'C:\\Users\\daewon\\AppData\\Local\\Temp\\pip-req-build-g5k8484g\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\daewon\AppData\Local\Temp\pip-req-build-g5k8484g\pip-egg-info'
         cwd: C:\Users\daewon\AppData\Local\Temp\pip-req-build-g5k8484g\
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\daewon\AppData\Local\Temp\pip-req-build-g5k8484g\setup.py", line 39, in <module>
        long_description=read_description(),
      File "C:\Users\daewon\AppData\Local\Temp\pip-req-build-g5k8484g\setup.py", line 12, in read_description
        return fd.read()
    UnicodeDecodeError: 'cp949' codec can't decode byte 0xe2 in position 3259: illegal multibyte sequence
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
WARNING: You are using pip version 19.3; however, version 19.3.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

그럼, 여기서 적당한 편집기로 setup.py 를 열어보자.

# -*- coding: utf-8 -*-

import sys

from setuptools.command.test import test as TestCommand
from setuptools import setup, find_packages
from inception.version import APP


def read_description():
    with open('README.rst') as fd:
        return fd.read()     ## <<<<<<<<<<<<<<<<<<<--- line 12

이렇게 되어 있다. (물론, 뒤쪽에 코드가 더 있다.) read_description 함수 안의 return fd.read() 부분에서 에러가 발생한 것이다.

README.rst 라는 파일을 열어서 읽어서, 그 텍스트를 되돌려주는 함수이고, 파일을 읽는 부분에서 UnicodeDecodeError 가 발생한 것이다.

에러가 발생하는 이유는 무엇일까? README.rst 는 말그대로 패키지에 대한 간단한 설명파일일 뿐이다. 상식적으로 실제 패키지의 실행에는 아무런 영향을 주지 않는다.

원인은 이렇다. REAME.rst 파일을 vscode 로 열어보면, 자동으로 utf-8 인코딩으로 인코딩을 자동 디텍트하면서 잘 보여준다. 그런데, 윈도우에서 setup.py 를 실행하게 되면, open('README.rst') 부분에서 인코딩을 지정하지 않았기 때문에, 한글 windows 의 기본 인코딩인 cp949 로 읽게 된다. open 부분은 단순히 파일핸들을 가져오는 부분이고, fd.read() 부분에서 실제적으로 파일의 바이너리 내용을 cp949로 해석하려는 동작이 일어나게 된다. 여기에서 README.rst 파일 안에 cp949 인코딩으로 해석할 수 없는 바이트열이 포함되어 있는 것이고, 그것이 3259번째 바이트인 e2 로 시작하는 바이트열인 것이다.

이를 README.rst 파일을 헥사모드로 열어 확인해 보면, 아래와 같이 트리구조를 표현하기 위한 그림문자인 것을 알 수 있다. 좀 특이한 3바이트짜리 문자인 것이다.


Structures examples:

.. code::

    .
    ├── files
    │   └── level_1
    │       └── level_2
    │           ├── example1.txt
    │           ├── example2.txt.jinja
    │           └── {{ name }}.txt
    └── settings.py

원인을 파악했으니 문제를 해결하는 방법도 알 수 있다. 여러가지 방법을 써 볼 수 있다.

  1. 무식하게, README.rst 파일을 싹 다 지우고 저장한 후에, pip install . 을 실행해 본다.
  2. README.rst 를 잘 읽어서 설치하고 싶다면, setup.py 의 11번째 라인의 open('README.rst') 부분에 encoding 옵션을 지정하여준다. 즉, open('README.rst', encoding='utf-8') 로 바꾸고, 저장한 후에, pip install . 을 실행한다.

2번째 방법으로 해 본다.

(vtest) D:\PythonEnv\ws_test\inception>pip install .
Processing d:\pythonenv\ws_test\inception
Requirement already satisfied: inquirer>=2.1.2 in d:\pythonenv\vtest\lib\site-packages (from inception==0.0.3) (2.6.3)
Requirement already satisfied: jinja2>=2.7.3 in d:\pythonenv\vtest\lib\site-packages (from inception==0.0.3) (2.10.3)
Requirement already satisfied: blessings==1.7 in d:\pythonenv\vtest\lib\site-packages (from inquirer>=2.1.2->inception==0.0.3) (1.7)
Requirement already satisfied: readchar==2.0.1 in d:\pythonenv\vtest\lib\site-packages (from inquirer>=2.1.2->inception==0.0.3) (2.0.1)
Requirement already satisfied: python-editor==1.0.4 in d:\pythonenv\vtest\lib\site-packages (from inquirer>=2.1.2->inception==0.0.3) (1.0.4)
Requirement already satisfied: MarkupSafe>=0.23 in d:\pythonenv\vtest\lib\site-packages (from jinja2>=2.7.3->inception==0.0.3) (1.1.1)
Requirement already satisfied: six in d:\pythonenv\vtest\lib\site-packages (from blessings==1.7->inquirer>=2.1.2->inception==0.0.3) (1.12.0)
Building wheels for collected packages: inception
  Building wheel for inception (setup.py) ... done
  Created wheel for inception: filename=inception-0.0.3-cp36-none-any.whl size=6886 sha256=2f6495d7b15ed233d86ebab3cdeb2080e7e6efb8f7e49cca0e43501f4d0aec01
  Stored in directory: C:\Users\daewon\AppData\Local\Temp\pip-ephem-wheel-cache-y815f1x4\wheels\cf\b6\e0\3222c958c75735f400a4913aa5193afae83100479d34c4af44
Successfully built inception
Installing collected packages: inception
Successfully installed inception-0.0.3
WARNING: You are using pip version 19.3; however, version 19.3.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

Successfully installed inception-0.0.3 가 나오며, 설치가 정상적으로 완료된 것을 확인할 수 있다.

다소 장황하게 설명을 했는데, 서양의 개발자들이 만든 패키지들 중에 이런 동일한 문제를 가지고 있는 패키지들을 종종 만나게 된다. setup.pyread_description 함수 부분은 거의 표준적으로 사용되는 부분이기 때문에, 다른 패키지 설치용 setup.py에도 동일하게 들어있는 게 정말 많다. 정말 사소한 문제인데, 이런 문제 때문에, 패키지를 못깔아서 시간을 허비하는 경우가 많다. 나 또한 굉장히 많은 시간을 허비했다. 이 과정을 조금 잘 이해해 두면, 나중에 동일한 문제를 만났을 때 쉽게 문제를 피해갈 수 있을 것이다.

  • Favicon of https://conansjh20.tistory.com BlogIcon 말테 2020.02.25 21:38 신고

    그냥 단순히 해법만 알려주시는 것이 아니라 왜 그렇게 나오는지 하나하나 이해까지 시켜주셔서 너무 잘 이해되고 문제도 해결했습니다.
    감사합니다~!^^

  • Favicon of https://conansjh20.tistory.com BlogIcon 말테 2020.02.25 23:14 신고

    관련해서 하나만 더 문의드릴게 있습니다.ㅠㅠ
    위의 방법대로 직접 설치를 성공적으로 하였는데 실행해보면 no module named 에러가 뜹니다.
    pip install 로 해보면 분명 이미 설치 되었고 C:\Users\Shin\AppData\Local\Programs\Python\Python38-32\Lib\site-packages 여기 안에 다른 기존 package들과 마찬가지로 설치되어 있습니다...
    path 지정이 아마도 문제인듯 한데(직접 설치시엔 path 지정이 잘 안되는 것 같기도 한데..ㅠㅠ)
    도저히 방법을 못찾겠습니다.ㅠㅠ

    • Favicon of https://daewonyoon.tistory.com BlogIcon daewonyoon 2020.02.26 13:08 신고

      그런 경우는 둘 이상의 python 인터프리터가 설치되어 있는 상태이고, pip 를 A 패쓰의 python 인터프리터에 설치하였고, no module named 가 나올 때에는 B 패쓰의 python 인터프리터로 실행한 것입니다.

      둘 이상의 python 인터프리터가 설치될 수 있는 경우는 여러가지가 있습니다.
      1. python 을 여러버전을 설치했다. ( 2.7, 3.6, ...)
      2. python 을 설치하고, anaconda 도 설치했다. (아나콘다는 기본 파이썬과 별도의 python 인터프리터를 설치합니다.)
      3. 가상환경 ( virtualenv, venv, conda env, ...) 을 설치하여 실행한다. pycharm 등에서 프로젝트를 만들면, (디폴트 설정이) 프로젝트 폴더 안에 가상환경을 만들어 새롭게 python 인터프리터가 설치됩니다.

      대략 이런 경우들이 있습니다. 어떤 경우인지 확인해 보시고, 댓글 주시면 도와드리죠. (큰 확률로, 확인하는 과정에서 스스로 해결하실 수 있을 겁니다.)

  • Favicon of https://conansjh20.tistory.com BlogIcon 말테 2020.02.26 13:34 신고

    비쥬얼 스튜디오 코드로 작성중이고 전에 파이썬 3.8 64비트 깔았다가 지우고 32비트 깐적은 있습니다.(보니깐 폴더가 서로 다르긴 하더군요.)
    그런데 다른 방법으로 원인을 발견한데 실제 제가 받은 패키지가 jTransliterate라고 파이썬2 버전용이더군요!(아직 초보라 한눈에 알아보지 못하고 또 자세히 보지도 않았구요 ㅠ) 그리고 억지로 설치한다고 해도 파이썬3 인터프리터는 파이썬2 인터프리터를 모듈로 인식을 안하고 그래서 없는걸로 나온다는 글을 어디서 봤구요. 어쨌든 파이썬2용 패키지라 깔끔하게 포기하는걸로 결론은 났는데 조금 찝찝하네요.

    아무튼 답변주신 부분도 참고하겠습니다. 예전에 파이썬 프로그램 이것저것 깔지 마란 이유도 다 이런 이유도 해당하는 것이었군요.

    감사합니다^^

    • Favicon of https://daewonyoon.tistory.com BlogIcon daewonyoon 2020.02.26 14:06 신고

      해봤습니다. 설치 잘 확인했는데도, 에러 내용이 No module named 'translation_maps' 라고 나오네요. 위 댓글에서 제가 이야기한 상황이 아니라도 패키지 자체의 문제가 있음.

      패키지 디펜던시가 뭔가 잘못된 것 같습니다. 패키지 릴리즈 히스토리 보니까 2012년이 마지막이니, 다른 패키지를 찾는 게 맞겠습니다.

      검색해 보니 pykakasi, romkan 같은 대체해서 쓸만한 패키지들이 보이니 이런 것으로 사용하시고요.

  • Favicon of https://conansjh20.tistory.com BlogIcon 말테 2020.02.26 14:09 신고

    넵 알겠습니다~ 역시 뭔가 이상했군요 ㅠ
    너무 친절한 답변 감사드리고 앞으로도 자주 들릴게요!ㅎㅎㅎ

  • 익명 2020.08.26 01:13

    자세한 설명 감사합니다. 덕분에 해결했습니다. (README 파일 내용만 지우는 것과 파일 자체를 지우는 부분에도 차이가 있다는것도 알게됐습니다....)
    혹시
    pip install tika 이 과정에서
    urllib.error.HTTPError: HTTP Error 403: SSL is required
    이런 에러가 발생 하는데 해결방법을 알고 계신다면 답변 부탁드립니다!