기존 프로젝트를 Python 3.13으로 업그레이드하는 실전 가이드입니다. 호환성 체크리스트, 단계별 전략, 주요 라이브러리 호환성, 도구 전환 계획을 다룹니다.
Python 버전 업그레이드는 새 기능을 사용하기 위해서만 하는 것이 아닙니다. 보안 패치, 성능 향상, 그리고 생태계 호환성 측면에서도 중요합니다.
Python 3.9 - 보안 수정 종료: 2025년 10월
Python 3.10 - 보안 수정 종료: 2026년 10월
Python 3.11 - 보안 수정 종료: 2027년 10월
Python 3.12 - 보안 수정 종료: 2028년 10월
Python 3.13 - 보안 수정 종료: 2029년 10월특히 Python 3.9 이하를 사용하는 프로젝트는 보안 지원이 종료되었거나 곧 종료됩니다. 업그레이드는 기술 부채를 관리하는 핵심 활동입니다.
한 번에 여러 버전을 건너뛰는 것보다, 한 버전씩 단계적으로 업그레이드하는 것이 안전합니다.
3.9 -> 3.10 -> 3.11 -> 3.12 -> 3.13
| | | |
v v v v
패턴매칭 성능향상 타입문법 GIL제거
테스트 테스트 테스트 테스트
각 단계에서:
1. CI에서 새 버전으로 테스트 실행
2. 경고와 에러 수정
3. 새 버전에서 안정성 확인
4. 프로덕션 배포3.11에서 3.13으로의 직접 업그레이드는 비교적 안전합니다. 3.12와 3.13에서 제거된 기능이 이미 3.11에서 deprecated된 경우가 대부분이기 때문입니다.
# 현재 Python 버전
python --version
# 설치된 패키지 목록
pip freeze > current_packages.txt
# 또는 uv 사용
uv pip freeze > current_packages.txt
# 의존성 트리 확인
uv tree[project]
requires-python = ">=3.9" # 이 값을 업데이트해야 함Python 3.12~3.13에서 제거된 주요 기능입니다.
1. distutils 완전 제거
- setuptools로 대체
- import distutils -> ModuleNotFoundError
2. unittest의 오래된 메서드 제거
- assertEquals -> assertEqual
- assertNotEquals -> assertNotEqual
- assertRegexpMatches -> assertRegex
3. asyncio의 레거시 API 제거
- asyncio.coroutine 데코레이터
- loop 파라미터 (여러 함수에서)
4. imp 모듈 완전 제거
- importlib으로 대체
5. typing의 일부 폐기
- typing.Hashable -> collections.abc.Hashable
- typing.Sized -> collections.abc.Sized1. 여러 모듈에서 deprecated된 함수/클래스 제거
- cgi, cgitb 모듈 제거
- aifc, audioop, chunk, crypt, imghdr, mailcap 등 제거
2. typing 모듈 정리
- typing.io, typing.re 네임스페이스 제거# pyupgrade로 사용 가능한 업그레이드 확인
uvx pyupgrade --py312-plus src/**/*.py --check
# Ruff의 UP 규칙으로 업그레이드 기회 확인
uvx ruff check --select UP --target-version py312 src/
# vermin으로 최소 Python 버전 확인
uvx vermin src/cgi, aifc, audioop 같은 제거된 표준 라이브러리를 사용하는 코드는 수동으로 대체해야 합니다. 이 모듈들은 PyPI의 별도 패키지로 대체 가능합니다. 예를 들어 cgi 모듈 대신 multipart 라이브러리를 사용할 수 있습니다.
라이브러리 3.12 3.13 비고
-------------------------------------------------
Django 5.0+ 5.1+ LTS 확인
FastAPI 0.109+ 0.110+ 최신 권장
Flask 3.0+ 3.0+
SQLAlchemy 2.0+ 2.0+
Pydantic 2.5+ 2.6+
NumPy 1.26+ 2.0+ Major 변경 주의
pandas 2.1+ 2.2+
PyTorch 2.2+ 2.3+
Celery 5.3+ 5.4+
pytest 8.0+ 8.0+
requests 2.31+ 2.31+
httpx 0.27+ 0.27+ # 새 Python 버전으로 가상 환경 생성
uv venv --python 3.13 .venv-test
# 의존성 설치 시도
uv sync --python 3.13
# 설치 실패 시 어떤 패키지가 문제인지 확인
# uv가 에러 메시지에서 호환되지 않는 패키지를 알려줌1. 패키지 업데이트
- uv add "package>=새버전"
2. 대체 패키지 사용
- 유지보수가 중단된 패키지는 대안을 찾음
3. 특정 패키지만 버전 고정
- pyproject.toml에서 버전 범위를 조정
4. 패키지 기여
- 오픈소스 패키지라면 3.13 호환성 PR 제출# 변경 전 (Python 3.11 이하)
from distutils.core import setup
from distutils.util import strtobool
# 변경 후 (Python 3.12+)
from setuptools import setup
def strtobool(val: str) -> bool:
"""distutils.util.strtobool 대체"""
val = val.lower()
if val in ("y", "yes", "t", "true", "on", "1"):
return True
elif val in ("n", "no", "f", "false", "off", "0"):
return False
else:
raise ValueError("invalid truth value " + repr(val))# 변경 전
from typing import List, Dict, Tuple, Optional, Union, Set
def process(items: List[Dict[str, Any]]) -> Optional[Tuple[str, ...]]:
result: Set[str] = set()
...
# 변경 후 (Python 3.12+)
def process(items: list[dict[str, Any]]) -> tuple[str, ...] | None:
result: set[str] = set()
...# 타입 힌트 현대화 (UP 규칙)
ruff check --select UP --fix --target-version py312 src/
# 임포트 정리
ruff check --select I --fix src/
# 전체 자동 수정
ruff check --fix src/
# 포매팅
ruff format src/name: Test
on: [push, pull_request]
jobs:
test:
strategy:
matrix:
python-version: ["3.12", "3.13"]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Set up Python
run: uv python install ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --all-groups
- name: Run tests
run: uv run pytest --tb=short -q
- name: Run type checking
run: uv run ty check src/
- name: Run linting
run: uv run ruff check src/# 모든 경고를 에러로 처리하여 테스트
uv run python -W error::DeprecationWarning -m pytest
# 또는 경고만 표시
uv run python -W all -m pytest 2>&1 | grep DeprecationWarning호환성이 확보되면, 새 기능을 점진적으로 도입합니다.
즉시 도입 (리스크 낮음):
1. typing 임포트 현대화 (list, dict 소문자)
2. Union -> | 연산자
3. Ruff + uv 도구 전환
4. f-string 유연한 문법 활용
중기 도입 (새 코드부터):
5. PEP 695 타입 파라미터 문법
6. type 문으로 타입 별칭
7. override 데코레이터
8. 패턴 매칭 (적합한 코드에서)
장기 검토:
9. TypeIs, ReadOnly TypedDict
10. free-threaded 모드 실험
11. JIT 빌드 실험[project]
name = "my-project"
version = "2.0.0"
requires-python = ">=3.12"
# 또는 3.13만 지원하는 경우
# requires-python = ">=3.13"
[tool.ruff]
target-version = "py312" # 또는 "py313"
[tool.ruff.lint]
select = [
"E", "W", "F", "I", "N",
"UP", # pyupgrade: 최신 문법 권장
"B", "C4", "SIM", "RUF",
]
[tool.ty]
python-version = "3.12" # 또는 "3.13"패키지 관리:
[ ] pip + virtualenv -> uv
[ ] requirements.txt -> pyproject.toml + uv.lock
[ ] pyenv -> uv python install
코드 품질:
[ ] flake8 -> ruff check
[ ] black -> ruff format
[ ] isort -> ruff (I 규칙)
[ ] mypy -> ty (또는 병행)
CI/CD:
[ ] GitHub Actions에 uv 설정
[ ] 멀티 Python 버전 테스트
[ ] pre-commit 훅 업데이트문제: ModuleNotFoundError: No module named 'distutils'
해결: pip install setuptools 또는 해당 import를 setuptools로 변경
문제: SyntaxWarning: invalid escape sequence
해결: 문자열의 백슬래시를 raw string(r"...")으로 변경하거나 이스케이프
문제: C 확장 빌드 실패
해결: 해당 패키지의 최신 버전으로 업그레이드
문제: typing 관련 ImportError
해결: typing에서 제거된 항목을 collections.abc 등으로 변경Python 3.12에서는 정규표현식 등에서 이스케이프되지 않은 백슬래시에 대해 SyntaxWarning을 발생시킵니다. 3.13에서는 이것이 SyntaxError로 승격될 예정이었으나, 일부는 유예되었습니다.
# 경고 발생
pattern = "\d+" # SyntaxWarning: invalid escape sequence '\d'
# 수정 방법 1: raw string 사용 (권장)
pattern = r"\d+"
# 수정 방법 2: 이중 백슬래시
pattern = "\\d+"# Ruff의 W605 규칙으로 감지 및 수정
ruff check --select W605 --fix src/소규모 프로젝트 (코드 5,000줄 이하):
의존성 확인: 1시간
코드 수정: 2~4시간
테스트: 1~2시간
총: 1일
중규모 프로젝트 (코드 5만줄 이하):
의존성 확인: 2~4시간
코드 수정: 1~2일
테스트: 1일
총: 3~5일
대규모 프로젝트 (코드 10만줄 이상):
의존성 확인: 1일
코드 수정: 1~2주
테스트: 1주
총: 2~4주Ruff의 자동 수정 기능을 적극 활용하면 코드 수정 시간을 대폭 단축할 수 있습니다. 특히 typing 임포트 현대화(UP 규칙)와 이스케이프 시퀀스 수정(W605)은 자동으로 처리됩니다.
이 시리즈는 Python 3.12~3.13의 변화를 언어 기능, 성능, 도구 생태계, 실전 활용의 네 가지 축으로 다루었습니다.
Python은 30년이 넘은 언어이지만, 지금 가장 활발하게 진화하고 있습니다. GIL 제거, JIT 컴파일러, Rust 기반 차세대 도구는 Python의 근본적인 제약을 해결하려는 시도입니다. 이 변화의 결과가 완전히 성숙하기까지는 몇 년이 더 걸리겠지만, 방향은 명확합니다.
핵심 내용을 요약합니다.
Python의 진화는 계속됩니다. 3.14에서는 deferred evaluation of annotations(PEP 649), 더 발전된 JIT, 그리고 free-threaded 모드의 안정화가 예정되어 있습니다. 이 시리즈에서 다룬 내용이 변화에 대응하는 기반이 되기를 바랍니다.
이 글이 도움이 되셨나요?
AI/ML 개발에서 Python이 차지하는 위치와 최신 트렌드를 다룹니다. PyTorch 생태계, LLM 개발 도구, 타입 안전한 AI 파이프라인, free-threaded Python의 AI 활용을 살펴봅니다.
Python 3.12~3.13의 typing 모듈 고급 기능을 다룹니다. TypedDict, Protocol, override, dataclass_transform, TypeGuard, TypeIs 등 실전 타입 시스템을 안내합니다.
Astral의 Ruff(린터/포매터)와 ty(타입 체커)를 다룹니다. 기존 도구 대체, 설정 방법, 규칙 커스터마이징, IDE 통합, 프로젝트 도입 전략을 안내합니다.