728x90

vscode 환경의 장점은 수많은 플러그인을 통해 개발 생산성을 극도로 향상시킬 수 있다는 점입니다. 특히 각 언어 환경에서 제공되는 플러그인의 통합이 잘되는 편이라 단일 IDE 환경에서 다양한 플러그인의 혜택을 누릴 수 있습니다.

Python으로 코드를 만들면서 구문의 오류나 스타일 문제를 잡아내기 위해 널리 사용되는 플러그인이 pylint 입니다. vscode가 아닌 파이썬 환경에서 사용할 수 있는 linter 중 하나로 넓은 사용자층을 보유하고 있습니다.

그런데 이 플러그인이 vscode에서 궁합이 잘 맞지 않을 때가 있습니다. 기존에 개발 장비에서 없던 문제가 새 개발 장비에서 하나, 둘 계속 나오니 참 환장할 노릇입니다 ^^;; 오늘은 그 중에서 vscode 환경에서 pylint가 내뿜는 no-member 에러를 없애는 방법을 살펴보겠습니다. 


 

pylint의 no-member 오류란?

pylint는 linter 도구로 코드를 분석하여 구문의 오류를 찾아내는 역할을 합니다. 구문의 오류 범주에는 사용자가 직접 만든 클래스나 함수도 당연히 포함됩니다. 제가 겪었던 문제는 Django 환경에서 클래스의 멤버 객체를 찾지 못하는 문제였습니다. 

vscode는 pylint의 도움을 받아 아래와 같이 특정한 객체에 대하여 정의되지 않은 멤버를 호출하는 코드에 빨간 물결줄을 그려주면서 존재하지 않는 멤버라는 것을 알려줍니다. 문제는 존재하지 않는 멤버가 아니라는 것입니다 ^^;;

 

빌드는 잘되지만 에러라고 pylint가 자꾸 심기를 건드립니다.

 

이 문제가 더 당혹스러운 이유는 빌드에는 문제가 없기 때문입니다. 실제로 구문에 문제가 없지만 pylint가 제대로 사용자 정의 객체를 탐색하지 못하면서 발생하는 이슈라 보면 정확합니다. 빌드에 문제가 없지만 vscode IDE 상에서는 문제가 있는 구문인 것처럼 소스코드 파일을 열때마다 시뻘건 줄과 경고 문구를 쏟아내는데 스트레스가 꽤 큽니다. 

 

해결방법 : vscode 공통 환경 설정에서 pylint 옵션 지정하기

이 문제를 해결하기 위해서는 vscode의 공통 환경 설정 settings.json 파일에서 pylint에 대한 옵션을 추가로 지정해 주어야 합니다. 기본적으로는 settings.json 파일에 pylint와 관련한 항목은 설정되어 있지 않습니다.

우리가 추가해야 할 내용은 아래와 같습니다. 이미지에는 오타가 있기 때문에 (--generated-members가 아니라 --generate-members입니다) 아래의 구문을 복사해서 settings.json 파일에 추가하는 것을 권장드립니다. 

  1. Mac에서는 Shift+Command+P를, Windows에서는 Ctrl+Shift+P를 눌러 Command Palette를 엽니다
  2. Command Palette에서 "Preferences: Open Settings (JSON)"을 입력하거나 찾아서 선택합니다
  3. Setting.json 파일에 아래의 항목을 추가합니다.
  4. vscode를 재기동하여 프로젝트를 열어 확인합니다.
"python.linting.pylintArgs": ["--generate-members", "from_json,query"],

 

 


 

vscode를 사용하지 않는 환경에서는 pip를 이용해 pylint-django 플러그인을 설치하면 에러를 해결할 수 있다는 글도 검색하면서 봤던 것 같습니다. vscode가 아닌 환경에서 문제를 겪고 있다면 pylint-django 공식 가이드 문서에 따라 패키지 설치후 django 환경 변수를 지정해 보시기 바랍니다!

 

pylint-django

A Pylint plugin to help Pylint understand the Django web framework

pypi.org

 

그외에 vscode 환경에서 python 개발을 하면서 겪을 수 있는 다른 문제들에 대해서는 아래의 글들을 참고하시면 도움이 되실지도 모르겠습니다. 변수가 많은 vscode 환경에서의 개발에서 꼭 승리하시길 기원하겠습니다!

 

Visual Studio Code 에서 Python 패키지의 Unresolved Import Error 를 처리하는 방법

코드를 만들 필요가 있을때 왠만하면 Node.js 를 이용하는 편입니다. 아무래도 익숙하기도 하거니와 자유로운 자바스크립트의 DNA 가 살아 있기 때문에 "대략 이렇게 돌아갈까?" 하는 것들이 동작

ondemand.tistory.com

 

728x90
728x90

애플실리콘 기반의 맥북이 등장하면서 세상이 참 행복해졌습니다. 베터리도 오래가고 이륙하지도 않고... 이렇게 쾌적한 맥 운영체제는 간만에 느껴보는 즐거움이었습니다. 하지만 의외의 장소에서 복병을 만나게 될줄은 몰랐고 비슷한 짜증을 경험할 수 있는 누군가(아마도 미래의 나...)를 위해 메모를 남겨 둡니다. 뜬금 없이 왜 애플실리콘 이야기인가...는 글을 읽으시면서 알 수 있게 됩니다. 


맥 환경에서 운영체제 패키지 관리를 위해 Homebrew를 보통 사용하게 됩니다. python의 유명한 라이브러리 중 하나인 magic을 사용하기 위해서는 운영체제 환경에 libmagic 패키지를 설치해 둘 필요가 있습니다. 

  1. virtualenv 로 가상 환경 구성 및 activate
  2. pip install 로 requirements.txt의 항목 설치

를 하고 디버깅을 시작하는데 import magic 에서 에러가 발생했습니다. 가상 환경에서 magic 패키지가 잘 설치되어 있고 brew 로 libmagic 설치를 확인해봐도 아무런 문제가 없는데 python이 계속 libmagic이 설치되었는지 확인하라고 짜증을 내더군요. 네, 저도 짜증이 나기 시작했습니다. 

% python3
Python 3.8.2 (default, Apr  8 2021, 23:19:18) 
[Clang 12.0.5 (clang-1205.0.22.9)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import magic
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "......./venv/lib/python3.8/site-packages/magic.py", line 176, in <module>
    raise ImportError('failed to find libmagic.  Check your installation')
ImportError: failed to find libmagic.  Check your installation

 

구글과 함께 문제의 원인과 해결방법을 찾아보면 대부분 패키지가 잘 설치되었는지 확인해봐라, brew 로 libmagic 설치하면 된다 류의 답변이 대부분입니다. 하지만 그 어떤 방법도 동작하지 않았습니다. 왜냐하면 python 패키지든 OS 패키지든 필요한 건 문제없이 다 설치되어 있었기 때문입니다.

두가지 방향으로 다시 조사를 시작했습니다. 범인은 brew와 pip 둘 중 하나일 것이라고 보고 brew에서 설치하는 libmagic과 pip를 통해 설치하는 magic(패키지명은 이것도 libmagic입니다)에 무슨 문제가 있는가... 하는 접근이었습니다. 먼저 발견한 흥미로운 단서는 brew에서 나왔습니다.

https://docs.brew.sh/FAQ

애플실리콘이 등장하면서 homebrew가 사용하는 기본 prefix 경로가 바뀌었다는 이야기가 FAQ에 등재되어 있었습니다. 기본 경로가 달라졌다는 것은 brew를 통해서 설치되는 패키지들도 경로가 달라졌다는 말이 됩니다. 그래 뭐 바뀌었겠지... 하다가 문득, python libmagic 패키지가 절대경로로 라이브러리를 참조하나? 싶은 생각이 들었고 python libmagic의 github 저장소를 들러보았습니다.

 

ahupp/python-magic

A python wrapper for libmagic. Contribute to ahupp/python-magic development by creating an account on GitHub.

github.com

유레카!

python libmagic 패키지가 운영체제의 libmagic 라이브러리를 참조하는 코드는 하드 코딩된 몇 가지 절대 경로를 탐색하도록 만들어져 있었습니다. 그 경로중 하나는 바로 brew가 인텔과 애플실리콘 환경에서 변화가 생긴 바로 그 경로였습니다. 오우... 코드에 기여할 수 있는 것인지 혹은 이미 이슈가 올라왔는지...는 조금 후에 생각하기로 하고 libmagic의 설치 경로를 확인해보고 symlink를 만들어 추정이 맞는지 시험해 보기로 했습니다.

(venv) % brew info libmagic
libmagic: stable 5.40 (bottled)
Implementation of the file(1) command
https://www.darwinsys.com/file/
/opt/homebrew/Cellar/libmagic/5.40 (339 files, 8.4MB) *
  Poured from bottle on 2021-05-18 at 15:25:48
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/libmagic.rb
License: Cannot Represent
==> Analytics
install: 13,403 (30 days), 39,666 (90 days), 127,530 (365 days)
install-on-request: 3,672 (30 days), 11,365 (90 days), 34,209 (365 days)
build-error: 0 (30 days)

 

우려했던, 그리고 Homebrew FAQ에서 알려줬던 것처럼 운영체제 패키지는 /opt/homebrew/Cellar/libmagic/{버전} 경로에 설치가 되어 있었습니다. 해당 경로에 진입하여 libmagic.dylib 의 정확한 경로를 확인하고 /usr/local/lib 로 이동해서 symlink 를 만들었습니다. 

% pwd        
/usr/local/lib
% ln -s /opt/homebrew/Cellar/libmagic/5.40/lib/libmagic.dylib libmagic.dylib
%

 

symlink 까지 만들어주고 다시 코드를 실행하니 import magic 구문에서 문제가 더 이상 발생하지 않았습니다. 보통 python 에서 패키지 문제가 생기면 1) 가상 환경에 설치가 되었는지 보고, 2) 버전을 타는 문제가 있나 확인하는 정도로 문제가 해결되었는데 이번 케이스는 좀 그렇지 않아 시간을 은근히 쓸 수 밖에 없었네요. 금방 한것처럼 보이지만 구글링을 얼마나 했던지... 


 

728x90
728x90

새로운 개발 장비가 생기면 이전에 사용하던 장비의 환경과 동일하게 준비하는 것이 은근 번거롭습니다. 한동안 손대지 않고 있던 파이썬 Python 장고 Django 프레임웍으로 개발된 코드를 새 장비에서 다루려다보니 역시나 의존성 문제들이 여러번 발생하고 있습니다.

그 중에서도 최초 환경 설치시에도 겪었던 mysqlclient 패키지 설치 이슈가 있어서 간략하게 정리해봅니다. 한줄 요약을 먼저하자면 Mac OS 환경에서는 homebrew 를 이용해 mysql 을 설치하는 것이 가장 쉽고 빠른 해결 방법입니다. 


개발중인 과제는 requirements.txt 에 필요한 의존성 패키지들이 잘 정리되어 있습니다. virtualenv 를 사용할 수 있는 환경을 만들고 pip install -r requirements.txt 명령을 이용해 패키지를 잘 설치하던 와중에... 떡하니 mysqlclient 패키지 설치가 문제가 발생했습니다.

폴백 fallback 로직에 따라 하위 버전까지 내려가면서 설치 시도를 하느라 실제 터미널 화면에는 휘황찬란한 붉은색의 에러메세지가 도배되었습니다. 에러를 알려주려는 메세지는 여러줄이었지만 핵심을 찝어내면 mysql_config not found 에러가 문제였습니다. 구글링을 조금 해보면 Mac OS 에서는 mysql 설치로 해결하는 것이 정석인듯 합니다. 

Collecting mysqlclient
  Downloading mysqlclient-2.0.3.tar.gz (88 kB)
     |████████████████████████████████| 88 kB 2.6 MB/s 
    ERROR: Command errored out with exit status 1:
    ...
    ...
    Complete output (15 lines):
    /bin/sh: mysql_config: command not found
    /bin/sh: mariadb_config: command not found
    /bin/sh: mysql_config: command not found
    ...
    ...
    OSError: mysql_config not found
    mysql_config --version
    mariadb_config --version
    mysql_config --libs

 

Homebrew 를 이용하여 mysql 을 설치하는 방법은 간단합니다. 사실 mysql 설치 외에도 다른 방법이 있을 거라 생각되지만 (로컬 환경에서 mysql 인스턴스를 띄울 일도 없어서...) 환경을 만들고 코드를 동작시키는 것이 더 급한 관계로 mysql 을 설치했습니다. 

% brew install mysql
==> Downloading https://ghcr.io/v2/homebrew/core/protobuf/manifests/3.15.8
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/protobuf/blobs/sha256:a1615a95bf6f0bd3d9111fd0afa9260373295eadf147c35aef03e31abdbef6bc
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:a1615a95bf6f0bd3d9111fd0afa9260373295eadf147c35aef03e31abdbef6bc?se=2021-05-18T03%3A15%3A00Z&sig=fpdRcLV73XovJ%2BjHStE98SY%2B9UBYum6GJxr8QQa
######################################################################## 100.0%
...
...
MySQL is configured to only allow connections from localhost by default

To connect run:
    mysql -uroot

To have launchd start mysql now and restart at login:
  brew services start mysql
Or, if you don't want/need a background service you can just run:
  mysql.server start
%

 

mysql 설치가 완료된 후 다시 pip 로 requirements.txt 에 기술된 항목들을 설치 시도해보니 특별히 문제 없이 mysqlclient 가 설치되는 것을 확인할 수 있었습니다. 똑똑한 pip 는 캐시에 저장된 mysqlclient 바이너리를 활용하여 패캐지 설치를 마쳤답니다 :-)

% pip3 install -r requirements.txt
...
...
Collecting mysqlclient
  Using cached mysqlclient-2.0.3.tar.gz (88 kB)
Collecting netifaces
  Downloading netifaces-0.10.9.tar.gz (28 kB)
Collecting cryptography
...
...

 

(업데이트) 트위터로 포스팅이 공유된 후 "왜 PyMySQL과 mysqlclient를 같이 쓰는가?"에 대한 이야기를 들었습니다. 그러고 보니... 왜 두개가 같이 들어가 있는지 생각도 못하고 있었네요. 다행(?)히도 같이 작업하시던 누군가 PyMySQL과 mysqlclient를 같이 시험하다 최종적으로 mysqlclient를 쓰기로 한 것이었습니다. requirements.txt에서 가볍게 삭제~ 

검색을 해보면 python에서 mysql 액세스를 하기 위해 널리 쓰이는게 PyMySQL과 mysqlclient, 그리고 peewee 정도인 것 같습니다. peewee는 ORM의 성격이 강한 것 같고 (써보진 않았습니다) mysqlclient는 C로 개발되어 속도가 빠르다, PyMySQL은 python 으로 만들어졌다 정도의 특징들이 있는 것 같네요!

728x90
728x90

아따 많이도 업데이트한다...

 

어제는 간만에 Flutter로 코드 만들어 보느라 고생했고 오늘은 또 간만에 파이썬으로 코드 만드느라 고생중입니다. 그 사이에 무슨 일이 있었던 것인가... (빅써 없데이트!?) 갑작스레 새 코드 프로젝트를 만들기 위해 virtualenv 를 돌리는데 Library not loaded 에러가 발생합니다. 자연스레 pip 로 virtualenv 를 업데이트 해볼랬더니.. 어라? pip도 동작을 안합니다. 

% virtualenv
dyld: Library not loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.6/Resources/Python.app/Contents/MacOS/Python
  Reason: image not found
zsh: abort      virtualenv
% pip
dyld: Library not loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.6/Resources/Python.app/Contents/MacOS/Python
  Reason: image not found
zsh: abort      pip

 

뭔가 운영체제 업데이트가 되면서 symlink가 꼬인 느낌이라 과감히 brew 로 파이썬을 재설치 해보기로 했습니다. 의존성이 걸려있는 패키지가 너무 많은 탓인지 업데이트가 한참 걸리네요. 열심히 다운로드 받고 설치하는 동안 저의 맥북프로는 또 다시 이륙을 하고는 고도를 높여 나갑니다...

% brew install python
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 3 taps (homebrew/core, homebrew/cask and homebrew/services).
...
...
==> Installing python@3.9
==> Pouring python@3.9-3.9.2_1.big_sur.bottle.tar.gz
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink bin/2to3
Target /usr/local/bin/2to3
already exists. You may want to remove it:
  rm '/usr/local/bin/2to3'

To force the link and overwrite all conflicting files:
  brew link --overwrite python@3.9

To list all files that would be deleted:
  brew link --overwrite --dry-run python@3.9

Possible conflicting files are:
/usr/local/bin/2to3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/2to3
/usr/local/bin/easy_install-3.9 -> /usr/local/Cellar/python@3.9/3.9.0_2/bin/easy_install-3.9
/usr/local/bin/idle3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/idle3
/usr/local/bin/pip3 -> /usr/local/Cellar/python@3.9/3.9.0_2/bin/pip3
/usr/local/bin/pip3.9 -> /usr/local/Cellar/python@3.9/3.9.0_2/bin/pip3.9
/usr/local/bin/pydoc3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/pydoc3
/usr/local/bin/python3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/python3
/usr/local/bin/python3-config -> /Library/Frameworks/Python.framework/Versions/3.6/bin/python3-config
==> /usr/local/Cellar/python@3.9/3.9.2_1/bin/python3 -m ensurepip
==> /usr/local/Cellar/python@3.9/3.9.2_1/bin/pip3 install -v --global-option=--no-user-cfg --install-option=--force --install-option=--single-version-externally-managed --install-option=--record=installed.txt --upgrade --target=/usr/local
==> /usr/local/Cellar/python@3.9/3.9.2_1/bin/pip3 wheel --wheel-dir=/usr/local/Cellar/python@3.9/3.9.2_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ensurepip/_bundled /usr/local/Cellar/python@3.9/3.9.2_1/libexec/setuptools /us
==> Caveats
Python has been installed as
  /usr/local/bin/python3

Unversioned symlinks `python`, `python-config`, `pip` etc. pointing to
`python3`, `python3-config`, `pip3` etc., respectively, have been installed into
  /usr/local/opt/python@3.9/libexec/bin

You can install Python packages with
  pip3 install <package>
They will install into the site-package directory
  /usr/local/lib/python3.9/site-packages

See: https://docs.brew.sh/Homebrew-and-Python
...
...

 

brew 의 로그를 보면서 에러가 난 부분들을 집중적으로 살펴봅니다. 확실히 python 3.9 를 설치하는 과정에 link 연결이 원활하지 않은게 보이는군요. 설치가 끝나는대로 brew link 명령을 --overwrite 으로 돌려보는게 좋을 것 같습니다. 그나저나 설치는 언제 끝나나...하고 있는데 설치가 끝났네요. 자 한번 brew link 를 수행해 보겠습니다

% brew link --overwrite --dry-run python@3.9
Would remove:
/usr/local/bin/2to3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/2to3
/usr/local/bin/idle3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/idle3
/usr/local/bin/pydoc3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/pydoc3
/usr/local/bin/python3 -> /Library/Frameworks/Python.framework/Versions/3.6/bin/python3
/usr/local/bin/python3-config -> /Library/Frameworks/Python.framework/Versions/3.6/bin/python3-config
%
% brew link --overwrite python@3.9
Linking /usr/local/Cellar/python@3.9/3.9.2_1... 21 symlinks created.
%
%
% python3
dyld: Library not loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
  Referenced from: /Library/Frameworks/Python.framework/Versions/3.6/Resources/Python.app/Contents/MacOS/Python
  Reason: image not found
zsh: abort      python3

 

하아... 뭔가 잘 해결이 안되었네요. 분명 3.9 를 설치한 것 같은데 에러 내용의 중간을 보니 3.6을 참조하고 있는게 문제인 듯 싶습니다. python3 의 위치를 탐색해서 강제로 symlink 를 변경해 보도록 하겠습니다. 

% which python3
/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
%
%
% cd /Library/Frameworks/Python.framework/Versions/3.6/bin/
% rm python3
%
% which python3
/usr/local/bin/python3

 

하하~! 요렇게 하니 이제 새로 설치된 python3.9 버전이 잘 실행이 됩니다. 그러나 여전히 virtualenv나 pip가 제대로 동작하지 않았습니다.

% python3
Python 3.9.2 (default, Feb 24 2021, 13:26:09)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

 

뭐가 문제일까 하다가... 문득 .bash_profile 에 추가되었던 PATH 정보가 생각나서 이 부분을 모두 제거하고 터미널을 재기동 해보았습니다. 그리고 나니 이제야 제대로 동작하는 virtualenv 와 pip..!! 개발 환경은 처음 설정이 늘 어렵고 번거롭고... 그런것 같습니다 ㅎㅎ. 비슷한 어려움을 겪는 분들이 계시다면, 

1. brew 로 python 패키지 업데이트
2. symlink 가 이상하게 걸려 있는지 확인
3. PATH 로 잡혀 있는 파이썬 디렉토리 확인

의 순서를 따르시면 문제를 해결하실 수 있을 것 같습니다!

 

728x90

+ Recent posts