Python 개발을 시작하는 많은 사람들이 하나의 .py 파일로 스크립트를 작성하는 것부터 시작한다. 하지만 프로젝트가 커지고 여러 파일, 외부 라이브러리, 테스트 등이 필요해지면, 단순한 스크립트 방식만으로는 한계에 부딪히게 된다. 이때 필요한 것이 바로 프로젝트 관리 시스템이며, 그 중심에 pyproject.toml 파일이 있다.
과거에는 Python 프로젝트의 메타데이터, 빌드 설정, 의존성 관리 등을 위해 setup.py, requirements.txt, setup.cfg, MANIFEST.in 등 여러 파일이 사용되었다. 이는 프로젝트 설정이 파편화되어 관리하기 어렵다는 단점이 있다. pyproject.toml은 이러한 문제점을 해결하고, Python 생태계의 복잡한 빌드 도구와 의존성 관리를 표준화하고 간소화하기 위해 등장했다. 이제 pyproject.toml 하나로 프로젝트의 거의 모든 설정을 통합하여 관리할 수 있다.
1. pyproject.toml 이해하기
pyproject.toml은 이름에서 알 수 있듯이, TOML(Tom's Obvious, Minimal Language) 포맷으로 작성된 파일이다. TOML은 사람이 읽고 쓰기 쉬운 최소한의 설정 파일 포맷을 지향한다.
- 키-값 쌍: key = "value" 형태로 데이터를 정의한다.
- 섹션: [section_name] 형태로 섹션을 구분하여 관련 설정을 묶는다.
- 배열: array_name = ["item1", "item2"] 형태로 목록을 정의한다.
pyproject.toml의 주요 목적은,
- 빌드 시스템 지정 ([build-system]): Python 패키지를 만들고 배포하는 데 필요한 빌드 도구(예: Poetry, Hatch, Setuptools)를 명시한다.
- 프로젝트 메타데이터 정의 ([project]): 프로젝트 이름, 버전, 설명, 의존성 등 프로젝트 자체에 대한 정보를 정의한다. 패키지를 PyPI(Python Package Index)에 배포할 때 사용되는 핵심 정보다.
- 도구별 설정 통합 (예: [tool.poetry]): 특정 도구(Poetry, Ruff, MyPy 등)가 사용하는 설정을 [tool.] 섹션 아래에 통합하여 관리할 수 있다.
2. 기본적인 pyproject.toml 구조
모든 pyproject.toml 파일에는 최소한 [build-system] 섹션이 포함되어야 한다. 또한, 대부분의 프로젝트에서는 [project] 섹션을 통해 프로젝트의 기본 정보를 정의한다.
필수 섹션: [build-system]
이 섹션은 Python 프로젝트를 빌드하고 패키징하는 데 어떤 도구와 백엔드를 사용할 것인지를 정의한다.
# pyproject.toml 예시
[build-system]
requires = ["poetry-core>=1.0.0"] # 빌드에 필요한 도구의 최소 버전
build-backend = "poetry.core.masonry.api" # 실제로 빌드를 수행할 백엔드 모듈 지정
- requires: 빌드 과정에 필요한 도구들의 목록을 지정한다. 위의 예시에서는 poetry-core를 사용하여 프로젝트를 빌드할 것임을 나타낸다.
- build-backend: requires에 지정된 도구들 중 실제로 빌드를 처리할 모듈을 지정합니다.
프로젝트 메타데이터: [project]
이 섹션은 프로젝트의 이름, 버전, 설명, 의존성 등 가장 기본적인 정보를 담고 있습니다. 이 정보는 PyPI와 같은 패키지 저장소에 패키지를 게시할 때 핵심적인 역할을 합니다.
# pyproject.toml 예시
[project]
name = "my-awesome-project" # 프로젝트 이름 (필수)
version = "0.1.0" # 프로젝트 버전 (필수)
description = "이것은 저의 아주 멋진 Python 프로젝트입니다." # 짧은 설명
readme = "README.md" # README 파일 경로
requires-python = ">=3.9" # 이 프로젝트가 요구하는 Python 버전
dependencies = [ # 런타임 의존성 목록
"requests>=2.28.1",
"beautifulsoup4>=4.11.1",
]
optional-dependencies = { # 선택적 의존성 (개발, 테스트 등)
dev = ["pytest>=7.0.0", "black>=22.3.0"],
docs = ["sphinx>=5.0.0"],
}
authors = [ # 작성자 정보
{ name = "홍길동", email = "hong.gildong@example.com" },
]
maintainers = [ # 유지보수자 정보
{ name = "관리자", email = "admin@example.com" },
]
keywords = ["web", "scraper", "utility"] # 키워드
classifiers = [ # PyPI 분류자
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
urls = { # 관련 URL
"Homepage" = "https://github.com/yourusername/my-awesome-project",
"Bug Tracker" = "https://github.com/yourusername/my-awesome-project/issues",
}
[project]
섹션은 pyproject.toml
이 단순한 빌드 설정 파일을 넘어 프로젝트의 핵심 정보를 담는 중앙 집중식 저장소 역할을 하도록 만든다.
3. 인기 있는 도구와 pyproject.toml
연동: Poetry
pyproject.toml
의 가장 큰 장점 중 하나는 다양한 Python 도구들이 이를 표준 설정 파일로 채택하고 있다는 점이다. 여기서는 특히 Poetry와 pyproject.toml
의 연동에 대해 다룬다. Poetry는 의존성 관리 및 패키징에 특화된 도구이다.
Poetry와 [tool.poetry]
섹션
Poetry는 pyproject.toml
내의 [tool.poetry]
섹션을 사용하여 프로젝트의 의존성, 스크립트, 패키지 정보 등을 관리한다. 이 섹션은 [project]
섹션과 유사하지만, Poetry만의 추가적인 기능을 제공한다.
# pyproject.toml (Poetry 사용 시)
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry]
name = "my-poetry-project"
version = "0.1.0"
description = "Poetry로 관리되는 멋진 프로젝트"
authors = ["당신의 이름 <you@example.com>"]
readme = "README.md"
packages = [{include = "my_poetry_project"}] # Poetry가 패키징할 모듈/디렉토리 지정
[tool.poetry.dependencies]
python = ">=3.9,<3.12" # Python 버전 범위
requests = "^2.28.1" # requests 라이브러리 (버전 제약)
fastapi = {extras = ["all"], version = "^0.100.0"} # extras 포함 의존성
[tool.poetry.group.dev.dependencies] # 개발 전용 의존성 그룹
pytest = "^7.4.0"
black = "^23.9.1"
위의 예시에서 [tool.poetry.dependencies]
는 프로젝트 런타임에 필요한 의존성을, [tool.poetry.group.dev.dependencies]
는 개발 환경에서만 필요한 의존성(예: 테스트 프레임워크, 코드 포매터)을 정의한다. Poetry는 이 정보를 바탕으로 가상 환경을 생성하고 의존성을 설치하며, poetry.lock 파일을 통해 의존성 버전을 정확히 고정한다.
4. pyproject.toml 활용 시 장점
pyproject.toml을 사용하면 다음과 같은 여러 장점을 얻을 수 있습니다.
- 단일 진실 공급원 (Single Source of Truth): 프로젝트의 모든 설정(빌드, 메타데이터, 의존성, 도구 설정)이 pyproject.toml 파일 하나에 통합되어 관리된다. 이를 통해 설정의 파편화를 막고 일관성을 유지하는 것이 쉬워진다.
- 표준화: Python 커뮤니티에서 pyproject.toml이 점차 표준 설정 파일로 자리 잡으면서, 다양한 도구들이 이를 인식하고 활용한다. 새로운 도구를 도입하더라도 기존 설정과 쉽게 통합될 수 있다.
- 가독성 및 편집 용이성: TOML 포맷은 JSON이나 YAML보다 문법이 직관적이고 가독성이 높아, 사람이 직접 읽고 편집하기가 쉽다.
- 새로운 도구 통합 용이: [tool.] 섹션 덕분에 새로운 Python 도구가 등장해도 프로젝트 설정에 쉽게 통합할 수 있다. 이를 통해 Python 생태계의 빠른 발전에 유연하게 대응할 수 있다.
5. 시작하기: 나만의 pyproject.toml 만들기
이제 pyproject.toml을 사용하여 프로젝트를 시작하는 방법을 알아보자. Poetry를 사용한다면 과정은 매우 간단하다.
새 프로젝트 시작 시 (Poetry 사용)
Poetry를 설치한 후, 새로운 프로젝트 디렉토리에서 다음 명령어를 실행한다.
poetry new my-new-project
cd my-new-project
이 명령어를 실행하면 my-new-project 디렉토리와 함께 기본적인 pyproject.toml 파일이 자동으로 생성된다.
# my-new-project/pyproject.toml
[tool.poetry]
name = "my-new-project"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10" # 현재 시스템의 Python 버전에 따라 자동으로 설정됩니다.
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
이제 poetry add <패키지명> 명령어를 사용하여 필요한 의존성을 추가하면, pyproject.toml의 [tool.poetry.dependencies]
섹션에 자동으로 추가되고 poetry.lock 파일이 생성되어 의존성 관리가 시작된다.
기존 프로젝트 마이그레이션
기존에 setup.py, requirements.txt 등으로 관리되던 프로젝트를 pyproject.toml 기반으로 전환하는 것도 가능하다. Poetry의 경우 poetry init 명령어를 통해 기존 프로젝트를 Poetry 프로젝트로 초기화하고, 기존 의존성 파일을 바탕으로 pyproject.toml을 생성할 수 있다.
마무리
pyproject.toml은 Python 프로젝트의 빌드, 의존성, 메타데이터 관리를 통합하고 표준화함으로써 개발 워크플로우를 크게 개선했다. 특히 프로젝트가 커지고 복잡해질수록 그 진가가 발휘된다. 단일 파일 스크립팅을 넘어 프로젝트 단위의 체계적인 개발을 목표로 한다면, pyproject.toml과 같은 현대적인 도구들을 적극적으로 활용하는 것이 필요하다.
'잡(job)기술' 카테고리의 다른 글
CMake --preset: 더 이상 길고 복잡한 빌드 명령어에 시달리지 말자 (1) | 2025.06.28 |
---|---|
Poetry로 Python 프로젝트 환경 만들기 (2) | 2025.06.24 |
Node.js child_process의 exec와 spawn 차이 정리 (0) | 2025.06.20 |
pickle 모듈을 이용한 캐싱 관리 기법 (2) | 2025.06.18 |
TypeORM 마이그레이션 사용하기: 안전한 데이터베이스 관리를 위한 단계별 가이드 (0) | 2025.05.30 |