본문 바로가기

프로그래밍/Python

파이썬을 한글명이 포함된 디렉토리 아래에 깔았을 때, site.py virtual_install_main_packages 안에서 UnicodeDecodeError 가 발생.

728x90

윈도우에서 파이썬을 한글이 포함된 디렉토리 패쓰 아래에 설치하였을 때, 패쓰의 한글 문자 때문에, UnicodeError 가 발생할 수 있다. 이런 문제가 발생하는 조건을 발견하여, 기록한다. 이런 문제에 대한 간단한 해결책은 파이썬을 한글을 포함하지 않는 디렉토리 아래에 설치하면 된다. (C:\Dev\Python38 등) 보통 파이썬을 처음 설치하는 경우에, 아무런 설정을 건드리지 않으면, 디폴트로 윈도우 사용자폴더 (보통 C:\Users\철수 같은 것 ) 하위에 설치를 하게 되는데, 윈도우 사용자명이 한글인 경우에 별 생각없이 설치하면, 나중에 이런 문제에 맞닥뜨릴 수 있다.

그리고 또 한가지, 모든 UnicodeDecodeError 가 파이썬 설치폴더만 바꾸어서 해결되는 것은 아니다. 초보자들은 오해하지 마시라. 굉장히 다양한 다른 원인들이 존재한다.

문제를 재현한 조건은 다음과 같다.

  • 윈도우
  • 파이썬3.8
  • 설치폴더가 C:\temp\한글폴더\Python
  • 파이썬3.8 에 virtualenv 를 설치. ( pip install virtualenv )
  • 설치한 virtualenv 모듈을 이용하여 test 란 이름의 가상환경을 생성하려함.

발생하는 에러메시지는 다음과 같다.

C:\temp>py -m virtualenv test
Using base prefix 'C:\\temp\\한글폴더\\Python38'
New python executable in C:\temp\test\Scripts\python.exe
Fatal Python error: init_import_size: Failed to import the site module
Python runtime state: initialized
Traceback (most recent call last):
  File "C:\temp\test\lib\site.py", line 769, in <module>
    main()
  File "C:\temp\test\lib\site.py", line 734, in main
    virtual_install_main_packages()
  File "C:\temp\test\lib\site.py", line 557, in virtual_install_main_packages
    sys.real_prefix = f.read().strip()
UnicodeDecodeError: 'cp949' codec can't decode byte 0xed in position 8: illegal multibyte sequence
ERROR: The executable C:\temp\test\Scripts\python.exe is not functioning
ERROR: It thinks sys.prefix is 'c:\\temp' (should be 'c:\\temp\\test')
ERROR: virtualenv is not compatible with this system or executable
Note: some Windows users have reported this error when they installed Python for "Only this user" or have multiple versions of Python installed. Copying the appropriate PythonXX.dll to the virtualenv Scripts/ directory may fix this problem.

virtualenv 는 기본 파이썬과 격리된 파이썬 실행환경을 만들어주는 모듈이다. 실행한 명령은 기본적으로 test 폴더를 만들고, 그 아래에 파이썬 실행에 필요한 파이썬 파일들과 라이브러리 등을 복사하는 짓을 한다. 에러가 발생한 이후에 test 폴더를 보면 실패하기 전까지 파이썬 실행환경에 필요한 파일 디렉토리 들이 복사되어 있다.

C:\temp\test>dir
 C 드라이브의 볼륨: coo
 볼륨 일련 번호: E0E6-7488

 C:\temp\test 디렉터리

2019-11-13  오전 12:12    <DIR>          .
2019-11-13  오전 12:12    <DIR>          ..
2019-11-13  오전 12:07    <DIR>          Include
2019-11-13  오전 12:12    <DIR>          Lib
2019-10-14  오후 07:43            31,322 LICENSE.txt
2019-11-13  오전 12:12    <DIR>          Scripts
2019-11-13  오전 12:12    <DIR>          tcl
               1개 파일              31,322 바이트
               6개 디렉터리  65,443,848,192 바이트 남음

에러메시지에 나와있는 site.py 파일도 있으며, 에러발생라인을 살펴보면 다음과 같다.

lib\site.py

def virtual_install_main_packages():
    f = open(os.path.join(os.path.dirname(__file__), "orig-prefix.txt"))
    sys.real_prefix = f.read().strip()     # <<< LINE 557
    f.close()

site.py 파일과 같은 디렉토리에 있는 orig-prefix.txt 파일을 바이너리가 아닌 텍스트모드 읽어들이는 부분이다.

해당 디렉토리의 orig-prefix.txt 파일을 열어봤다. 내용은 다음과 같고, 파일의 인코딩은 utf-8 로 되어 있다.

C:\temp\한글폴더\Python38

이로서 왜 이런 문제가 발생했는를 알 수 있다.

한글윈도우환경에서 파이썬의 open 함수의 텍스트모드 기본 인코딩은 시스템인코딩은 cp949이다. 하지만, orig-prefix.txt 는 파이썬 virtualenv 가 임시로 기본파이썬의 위치( 에러메시지의 Using base prefix 'C:\\temp\\한글폴더\\Python38' 를 보라 )를 저장하면서, utf-8로 저장하였다. 한글(또는 일본어, 중국어, 키릴문자등)이 포함된 utf-8을 해당 언어 윈도우 기본인코딩(cp949등 )으로 읽으면, 이렇게 UnicodeDecodeError 가 발생할 가능성이 크다.