파이썬 라이브러리는 Pypi에서 찾을 수 있다. 각각의 라이브러리가 제공될 때 문제없이 배포될 수 있도록 패키지는 일련의 메타데이터를 포함하게 된다. 이 메타데이터는 명칭, 버전, 의존성 등을 적게된다. 라이브러리에 메타데이터를 작성할 수 있도록 다음과 같은 형식을 setup.py 파일에서 사용할 수 있다.
from setuptools import setup
setup(
name="MyLibrary",
version="1.0",
install_requires=[
"requests",
"bcrypt",
],
)
- 이 명세에는 이 의존성을 어디에서 가져와 해결해야 하는지에 대해서는 적혀있지 않다.
- 단순히 requests, bcrypt라고만 적혀있고 이 의존성이 위치하고 있는 URL도 파일 경로도 존재하지 않는다.
- 의존 라이브러리 정보를 저장할 수 있도록 pip의 requirements 파일을 생성하는 기능이 제공되게 되었다.
# 이 플래그의 주소는 pip의 기본 설정이지만 관계를 명확하게 보여주기 위해 추가함
--index-url https://pypi.python.org/simple/
MyPackage==1.0
requests==1.2.0
bcrypt==1.0.2
--index-url https://pypi.python.org/simple/
는requests==1.2.0
이 구체적으로 https://pypi.python.org/simple/에 있는 requests 1.2.0으로 처리하게 만든다.
TLDR
- setup.py는 재배포를 위한 파일이고 requirements.txt는 배포할 수 없는 것을 위한 파일
- 굳이 install_requires와 requirements를 분리하는 이유는 추상의존과 구체적 의존을 분리할 필요가 있기 때문
- 의존성을 두 방식으로 분리해서 사용하면 Pypi를 미러링해서 사용하는 것이 가능해짐
- 같은 이유로 회사 스스로 private 패키지 색인을 구축해서 사용할 수 있는것
- 동일한 라이브러리를 가져와서 버그를 고치거나 새로운 기능을 더한 다음 그 라이브러리 의존성으로 사용하는 것도 가능하게 됨
- 추상의존성은 명칭, 버전 지정만 있고 이 의존성을 설치할 때 해당 패키지를 Pypi에서 받을지 Create.io에서 받을지 아니면 자신의 파일 시스템에서 지정할 수 있기 때문
의존성 분리
구체적 의존성을 추상의존성이 필요한 곳에서 사용했을 때는 문제가 발생하게 된다.
import (
"github.com/foo/bar"
)
- go에서 사용하는 기본 패키지 관리자(go get)는 사용할 패키지를 다음 예제처럼 URL로 지정해서 가져오는 것이 가능하다.
bar
라이브러리에 존재하는 버그가 내 작업에 영향을 줘서bar
라이브러리를 교체하려고 한다고 가정했을 때bar
라이브러리를 포크해서 문제를 수정했다면 이제bar
라이브러리의 의존성이 명시된 코드를 변경해야 한다.- 만약 5단계 깊숙히 존재하는 라이브러리라면 단지 조금 다른
bar
를 쓰기 위한 작업인데 다른 패키지를 최소 5개를 포크하고 내용을 수정해서 라이브러리를 갱신해야 한다
setuptools에는 Go예제와 비슷한 기능이 존재한다. dependency links라는 기능이며 다음 코드처럼 작성할 수 있다.
from setuptools import setup
setup(
# ...
dependency_links = [
"http://packages.example.com/snapshots/",
"http://example2.com/p/bar-1.0.tar.gz",
]
)
- 위 기능은 추상성을 지우고 하드코딩하는 기능으로 이 의존성 패키지를 정확히 어디에서 찾을 수 있는지 url로 저장하게 된다.
- 이제 Go에서 살펴본 예제처럼 패키지를 조금 수정한 다음에 패키지를 다른 서버에 두고 그 서버에서 의존성을 가져오는 간단한 작업에도 dependency_links를 변경해야한다. 사용하는 패키지의 모든 의존성 체인을 찾아다니며 이 주소를 수정해야 하는 상황이 되었다.
재사용
- 라이브러리와 어플리케이션을 구분해서 생각하는 것은 각 코드를 다루는 좋은 방식이라고 할 수 있다. 하지만 라이브러리를 개발하다보면 그 코드가 어플리케이션처렁 될 때가 있다.
- 의존성 목록을 두 파일로 분리해서 관리하다 보면 언젠가는 두 목록이 어긋나는 일이 필연적으로 발생한다.
- 이런 상황을 해결할 수 있도록 pip의 requirements파일에서 다음과 같은 기능을 제공한다.
--index-url [https://pypi.python.org/simple/](https://pypi.python.org/simple/)
-e .
- 이렇게 파일을 작성하더라도
pip install -r requirements.txt
명령을 실행해보면 이전과 다르지 않게 동작하게 된다. - 이 명령은 먼저 파일 경로 .에 위치한 라이브러리를 설치한다.
- 그리고 추상 의존성을 확인할 때
--index-url
설정의 경로를 참조해서 구체적인 의존성으로 전환하고 나머지 의존성을 마저 설치하게 된다. - 만약 단위별로 나눠서 배포하고 있는 라이브러리가 둘 이상 있거나 공식적으로 릴리즈하지 않은 기능을 별도의 부분 라이브러리로 분리해서 개발하고 있을 때
- 라이브러리가 분할되어 있다고 하더라도 이 라이브러리를 참조할 때는 최상위 라이브러리 명칭을 의존성에 입력하게 된다.
- 모든 라이브러리 의존성은 그대로 설치하면서 부분적으로는 개발 버전의 라이브러리를 설치하고 싶은 경우에는 다음처럼 requirements.txt에 개발버전을 먼저 설치해서 개발버전의 부분라이브러리를 사용하는 것이 가능하다.
--index-url https://pypi.python.org/simple/
-e https://github.com/foo/bar.git#egg=bar
-e .
bar
라이브러리를 https://github.com/foo/bar에서 받아 설치한 다음 현재 로컬 패키지에 설치하게 된다.- 여기서도 의존성을 조합하고 설치하기 위해 --index 옵션을 사용했다.
- 하지만
bar
라이브러리 의존성을 github의 주소를 사용해서 먼저 설치했기 때문에bar
의존성은 inde x로 부터 설치하지 않고 github에 있는 개발 버전을 사용하는 것으로 진행할 수 있게된다.
References
'Linux' 카테고리의 다른 글
[Linux System Programming] File System #3 (0) | 2022.09.26 |
---|---|
[Linux System Programming] GCC 컴파일러 사용법 #2 (0) | 2022.09.26 |
[Linux System Programming] vi cheat sheet #1 (0) | 2022.09.26 |
[Linux System Programming] Makefile 기초, 변수, 생성 규칙, 재귀, 함수... (0) | 2022.09.05 |