Debugging Sparrow

Poetry를 통한 파이썬 패키지 관리

2020/07/08 Poetry Python 포에트리 파이썬

Poetry는 파이썬의 패키징, 의존성 관리를 위한 툴입니다. 또한 툴을 사용함으로써 가상환경의 관리도 가능합니다. 기존의 pip, setup.py, requirements.txt, virtualenv를 대체할 수 있으며 PEP-517을 준수한 pyproject.toml 파일을 config 파일로 사용하기 때문에 기존 setup.py스타일(setuptools, disutils, pip 등을 사용하는)의 문제점을 없앨 수 있습니다.

Poetry를 사용하면 무엇이 좋나요?

Poetry의 장점

패키징 및 의존성 관리를 쉽게할 수 있습니다. 기존 파이썬의 패키징 및 의존성 관리는 개발자들에게 꽤나 많은 혼란을 일으킵니다. setup.py, requirements.txt, setup.cfg, MANIFEST.in, Pipfile 등은 배우기 어렵거나 의존성 관리에 필요한 모든 정보를 담기 어렵습니다. poetry는 pyproject.toml 파일을 사용하여 이들을 대체합니다.

가상환경과 디렉터리 관리를 함께 할 수 있습니다. 즉 일일이 virtualenv를 사용할 필요가 없어집니다. 이러한 방식은 npm의 그것과 같다고 볼 수 있습니다. 디렉터리마다 가상환경이 관리되며 $ poetry run python과 같은 방식으로 가상환경에서 실행할 수 있습니다.

아래의 중대한 문제점들을 해결할 수 있습니다.

setup.py는 어떠한 문제점이 있나요?

PEP-518 문서는 빌드 의존성을 나타낼 수 있는 새로운 설정 파일인 pyproject.toml을 소개하며 기존의 문제점에 대해 말합니다. 이를 요약하면 다음과 같습니다.

초기 파이썬의 배포를 위해서 disutils를 사용해왔으나 disutils에 몇 가지 기능을 추가한 setuptools가 인기를 얻게 되었다. 두가지 모두 setup.py내에 기술하여 프로젝트 관리자는 빌드 배포를 위해 이 두 소프트웨어를 실행해 왔다.

distutils같은 경우는 파이썬의 표준 라이브러리 이기 때문에 외부 의존성이 따로 없었다. 하지만 프로젝트에서 setuptools를 사용한다면 setup.py와 같은 실행 파일은 문제를 일으킨다. 우리는 setuptools의 의존성을 알지 못하면 setup.py를 실행할 수 없으며 setup.py를 실행하지 않고서는 의존성을 알 수 있는 표준 방법이 없는 모순에 빠져왔다.

setuptools는 이러한 문제점을 해결하기 위해 setup_requires라는 argument를 두었으나 여러가지 문제들과 복잡함으로 인하여 극히 드물게 사용되었고 프로젝트 관리자들의 기술부채는 계속 늘어왔다.

결국 pip는 setuptools를 setup.py를 실행할 때 필수라 쉽게 가정했다. 그러나 이러한 방식은 타 프로젝트의 발전 가능성을 저하하며 setuptools가 그랬던 것처럼 setuptools외의 다른 툴이 인기를 얻었을 때 확장될 수 없다.

이 PEP는 .toml 파일을 통한 선언적 방식으로 최소한의 의존성을 나열하는 방식으로 상황을 개선하려고 한다.

1
2
3
[build-system]
# Minimum requirements for the build system to execute.
requires = ["setuptools", "wheel"] # PEP 508 specifications.

의존성 관리에 requirements.txt를 사용하면 무엇이 안좋나요?

Poetry Github에서는 Poetry를 소개하며 다음의 예시를 보여줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ pip install oslo.utils==1.4.0

Collecting oslo.utils==1.4.0
Downloading oslo.utils-1.4.0-py2.py3-none-any.whl (55 kB)
|████████████████████████████████| 55 kB 123 kB/s
Collecting Babel>=1.3
Downloading Babel-2.8.0-py2.py3-none-any.whl (8.6 MB)
|████████████████████████████████| 8.6 MB 46 kB/s
Collecting six>=1.9.0
Using cached six-1.14.0-py2.py3-none-any.whl (10 kB)
Collecting oslo.i18n>=1.3.0
Downloading oslo.i18n-4.0.1-py3-none-any.whl (47 kB)
|████████████████████████████████| 47 kB 91 kB/s
Collecting netaddr>=0.7.12
Downloading netaddr-0.7.19-py2.py3-none-any.whl (1.6 MB)
|████████████████████████████████| 1.6 MB 50 kB/s
Collecting pbr!=0.7,<1.0,>=0.6
Downloading pbr-0.11.1-py2.py3-none-any.whl (79 kB)
|████████████████████████████████| 79 kB 73 kB/s
Collecting netifaces>=0.10.4
Downloading netifaces-0.10.9-cp37-cp37m-macosx_10_14_x86_64.whl (12 kB)
Collecting iso8601>=0.1.9
Downloading iso8601-0.1.12-py2.py3-none-any.whl (12 kB)
Collecting pytz>=2015.7
Using cached pytz-2020.1-py2.py3-none-any.whl (510 kB)
Requirement already satisfied: pip in ./venv/lib/python3.7/site-packages (from pbr!=0.7,<1.0,>=0.6->oslo.utils==1.4.0) (20.1)

ERROR: oslo-i18n 4.0.1 has requirement pbr!=2.1.0,>=2.0.0, but you'll have pbr 0.11.1 which is incompatible.

Installing collected packages: pytz, Babel, six, pbr, oslo.i18n, netaddr, netifaces, iso8601, oslo.utils
Successfully installed Babel-2.8.0 iso8601-0.1.12 netaddr-0.7.19 netifaces-0.10.9 oslo.i18n-4.0.1 oslo.utils-1.4.0 pbr-0.11.1 pytz-2020.1 six-1.14.0

28라인에서 에러가 난 것을 볼 수 있습니다. 왜냐하면 oslo.utils==1.4.0은 다음의 패키지를 요구하기 때문입니다.

1
2
pbr>=0.6,!=0.7,<1.0
oslo.i18n>=1.3.0

위의 요구사항 대로 oslo.i18n은 4.0.1이 설치 되고 pbr은 0.11.1이 설치되었으나 에러는 oslo.i18n==4.0.1에서 요구하는 pbr의 버전 (pbr!=2.1.0,>=2.0.0) 때문에 발생하였습니다.

다음은 Poetry를 이용한 설치입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
poetry add oslo.utils==1.4.0
Creating virtualenv ttt-UJsJie9g-py3.7

Updating dependencies
Resolving dependencies... (59.1s)

Writing lock file

Package operations: 19 installs, 0 updates, 0 removals

- Installing pytz (2020.1)
- Installing zipp (3.1.0)
- Installing babel (2.8.0)
- Installing importlib-metadata (1.6.0)
- Installing pbr (0.11.1)
- Installing pyparsing (2.4.7)
- Installing six (1.14.0)
- Installing attrs (19.3.0)
- Installing iso8601 (0.1.12)
- Installing more-itertools (8.3.0)
- Installing netaddr (0.7.19)
- Installing netifaces (0.10.9)
- Installing oslo.i18n (2.1.0)
- Installing packaging (20.3)
- Installing pluggy (0.13.1)
- Installing py (1.8.1)
- Installing wcwidth (0.1.9)
- Installing oslo.utils (1.4.0)
- Installing pytest (5.4.2)

Poetry는 위의 문제를 해결할 뿐만 아니라 Lock 파일 또한 지원하는데, 의존성을 수정하면 자동으로 생성되는 파일입니다. 즉 의존성이 생성되는 시점의 정보를 담고 있어 패키지 버전을 확정지을 수 있습니다.

Poetry 사용법

설치

1
$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python

Poetry에서 자주 사용하게 될 명령어들

https://python-poetry.org/docs/cli/ 문서에 자세히 나와있으나 간단히 몇개만 알아봅시다.

new
프로젝트를 생성합니다.

add
패키지를 설치합니다. pip install과 유사하나 pyproject.toml에 패키지 정보 또한 추가합니다. ex) poetry add requests

run
가상환경 내에서 커맨드를 실행합니다. ex) poetry run pytest, poetry run python

install
현재 pyproject.toml 파일에 기반하여 패키지를 설치합니다. pip install -r requirements.txt와 유사합니다.

update
현재 pyproject.toml 파일에 기반하여 패키지를 업데이트 합니다.

shell
가상환경 내에서 shell에 진입합니다.

Author: dbgsprw

Link: https://dbgsprw.github.io/2020/07/08/Poetry를-통한-파이썬-패키지-관리/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
Kubernetes Container Resource
NextPost >
Distributed Time Travel for Feature Generation
CATALOG
  1. 1. Poetry를 사용하면 무엇이 좋나요?
    1. 1.1. Poetry의 장점
    2. 1.2. setup.py는 어떠한 문제점이 있나요?
    3. 1.3. 의존성 관리에 requirements.txt를 사용하면 무엇이 안좋나요?
  2. 2. Poetry 사용법
    1. 2.1. 설치
    2. 2.2. Poetry에서 자주 사용하게 될 명령어들