본문 바로가기

시행착오 노트

Pypi 에 내가 만든 패키지 배포하면서 알게된거

기억날 때 빨리 시행착오 겪은거 적어야겠다.
진짜 지나고보면 아무것도 아닌데, 막상 뭐가 안되는 상황 때 되면 스트레스 엄청 받으니까.

일단 내 상황은 파이썬으로 패키지를 만들고, 이를 pip 형식으로 받을 수 있게, Pypi 에 올리려고 하는 중이었다.
기본적으로 파이썬 배포는 아래 블로그를 참조했다.

 

PyPI로 패키지 배포하기:내가 만든 모듈도 pip로 다운받을 수 있다!

pypi에 내 프로젝트를 올리는 법

blessingdev.wordpress.com

배포 관련 여러 포스팅이 있지만, 위 글이 제일 깔끔하고 쉽게 알려주었다.
첨언하면, 위 글에서 '2. 프로젝트를 만듭니다' 파트에 적혀있는 패키지 구조를 잘 보자.
이 구조 유지안하면, 하여튼 뭔가 문제가 생긴다. 저 구조를 되도록 유지해주자.

이제 배포 과정 중 알게된 것들을 적어본다.

1. 패키지 이름에는 오직 영문자만 있는게 좋다.

내가 처음에 지은 패키지 이름은 deckgl\_jupyter 였다.
그런데 이를 Pypi 에 올리자, deckgl-jupyter 로 변환되어 올려졌다.
원치 않던 underscore(_) 가 dash(-)로 바뀐 것이다.

처음엔 별 신경안쓰고 그냥 이대로 배포하려 했다.
문제는, 쥬피터나 파이썬에서 이를 import 해올 수가 없다는 것이다.
물론, import 해올 수는 있는데 기존의 깔끔한 방식은 아니다.

예를 들어,

import deckgl-jupyter

와 같이 쓰면 당연히 오류가 난다.

그럼 어떻게 해야하는가?
애초에 패키지 이름에 underscore(_) 를 안넣어주는게 정답이다.
그리고 찾아보니 이와 관련된 이슈가 몇 번 있었고, PEP8 에 이미 패키지 이름과 관련된 가이드가 있었다.

다음 링크를 참고했다.

 

Is it acceptable to have python package names with numbers in it?

I've seen PyPI distribution names as well python package names with numbers in them. For example flake8 is one example, where you also import with import flake8. According to PyPI and PEP standar...

stackoverflow.com

핵심 내용은,

Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability. Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.

When an extension module written in C or C++ has an accompanying Python module that provides a higher level (e.g. more object oriented) interface, the C/C++ module has a leading underscore (e.g._socket).

즉, underscore 를 사용해도 되긴 하는데, 권장하진 않는다는 말이다.
별개로, Pypi 에서는 왜 강제로 dash 로 변환시키는지는 모르겠다...
결국, 나는 패키지 이름 deckgl_jupyter 를 deckgljupyter 로 바꿨다.

2. Pypi 에 한번 업데이트(커밋) 할 때마다 버전을 다르게 해야한다.

Pypi 에 배포 후, 계속하여 패키지를 업데이트 해야하는 경우가 많은데, (대부분 그렇겠지만)
이 때 코드 수정 후, 나는 다음과 같은 과정으로 업데이트 했다.

$ rm -rf dist build deckgljupyter.egg-info
$ python setup.py sdist bdist_wheel
$ python -m twine upload dist/*

즉, 기존의 설치파일을 지우고, 소스, 빌드파일을 만들어서 업로드하는 것이다.
근데 그냥 Pypi 에 해당 패키지가 이미 존재한다는 오류 메시지가 나고, 업로드도 안된다.
이유를 찾아보고 하니, Setup.py 에서 version 을 바꿔야한다고 한다.
기존이 version = 0.1 이었으므로, version = 0.1.1 로 바꾼뒤 다시 업로드하니 잘 되었다.
왜 많은 오픈소스 패키지들의 버전이 0.1.1.1 이런 식인지 이제 이해가 간다 ㅋㅋㅋ

3. 패키지 내 .py 외 파일들을 설치파일에 넣어주려면 MANIFEST.in 를 사용해야한다.

오픈소스들 보다보면, MANIFEST.in 이라는 놈을 자주 볼 수 있었는데, 당시엔 그게 뭔지 몰랐다.
패키지를 배포해보려니 이제 알겠더라. 얘는 패키지 내 .py 파일이 아닌 파일들을 패키지 설치파일에 담아줄 때 사용한다.

나의 경우, jinja2 로 html 렌더링 하는 코드가 있어서 패키지 내 .html 파일들이 있었다.
*그냥 setup.py 로 빌드하면 패키지 내 .py 파일이 아닌 파일들은 설치파일에 안담긴다! *나도 업로드 하고 pip 로 내 패키지 받아서 테스트하던 중 알았다.

별건 없고, 다음과 같이 MANIFEST.in 을 setup.py 와 동일 디렉토리에 넣어주면, 저런 파일들도 패키지에 들어가게 된다.

# MANIFEST.in
include deckgljupyter/templates/*