본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 13장: Python 3.13 마이그레이션 실전 가이드
2026년 2월 9일·프로그래밍·

13장: Python 3.13 마이그레이션 실전 가이드

기존 프로젝트를 Python 3.13으로 업그레이드하는 실전 가이드입니다. 호환성 체크리스트, 단계별 전략, 주요 라이브러리 호환성, 도구 전환 계획을 다룹니다.

17분538자12개 섹션
pythontypescriptperformancedevtoolsconcurrency
공유
python-trends13 / 13
12345678910111213
이전12장: AI 개발에서의 Python 활용

마이그레이션을 계획해야 하는 이유

Python 버전 업그레이드는 새 기능을 사용하기 위해서만 하는 것이 아닙니다. 보안 패치, 성능 향상, 그리고 생태계 호환성 측면에서도 중요합니다.

Python 버전별 지원 기간
text
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 이하를 사용하는 프로젝트는 보안 지원이 종료되었거나 곧 종료됩니다. 업그레이드는 기술 부채를 관리하는 핵심 활동입니다.

마이그레이션 전략: 한 번에 vs 단계적

권장: 단계적 업그레이드

한 번에 여러 버전을 건너뛰는 것보다, 한 버전씩 단계적으로 업그레이드하는 것이 안전합니다.

권장 업그레이드 경로
text
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.11에서 3.13으로의 직접 업그레이드는 비교적 안전합니다. 3.12와 3.13에서 제거된 기능이 이미 3.11에서 deprecated된 경우가 대부분이기 때문입니다.

Step 1: 현재 상태 파악

Python 버전과 의존성 확인

현재 환경 진단
bash
# 현재 Python 버전
python --version
 
# 설치된 패키지 목록
pip freeze > current_packages.txt
 
# 또는 uv 사용
uv pip freeze > current_packages.txt
 
# 의존성 트리 확인
uv tree

pyproject.toml 확인

현재 Python 버전 제약 확인
toml
[project]
requires-python = ">=3.9"  # 이 값을 업데이트해야 함

Step 2: 호환성 검사

제거된 기능 확인

Python 3.12~3.13에서 제거된 주요 기능입니다.

3.12에서 제거된 기능
text
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.Sized
3.13에서 제거된 기능
text
1. 여러 모듈에서 deprecated된 함수/클래스 제거
   - cgi, cgitb 모듈 제거
   - aifc, audioop, chunk, crypt, imghdr, mailcap 등 제거
   
2. typing 모듈 정리
   - typing.io, typing.re 네임스페이스 제거

자동 검사 도구

호환성 자동 검사
bash
# pyupgrade로 사용 가능한 업그레이드 확인
uvx pyupgrade --py312-plus src/**/*.py --check
 
# Ruff의 UP 규칙으로 업그레이드 기회 확인
uvx ruff check --select UP --target-version py312 src/
 
# vermin으로 최소 Python 버전 확인
uvx vermin src/
Warning

cgi, aifc, audioop 같은 제거된 표준 라이브러리를 사용하는 코드는 수동으로 대체해야 합니다. 이 모듈들은 PyPI의 별도 패키지로 대체 가능합니다. 예를 들어 cgi 모듈 대신 multipart 라이브러리를 사용할 수 있습니다.

Step 3: 의존성 호환성 확인

주요 라이브러리 호환성 매트릭스

주요 라이브러리 3.12/3.13 호환성 (2026년 기준)
text
라이브러리          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+   

의존성 호환성 확인 방법

의존성 호환성 확인
bash
# 새 Python 버전으로 가상 환경 생성
uv venv --python 3.13 .venv-test
 
# 의존성 설치 시도
uv sync --python 3.13
 
# 설치 실패 시 어떤 패키지가 문제인지 확인
# uv가 에러 메시지에서 호환되지 않는 패키지를 알려줌

호환되지 않는 패키지 대응

대응 방법
text
1. 패키지 업데이트
   - uv add "package>=새버전"
 
2. 대체 패키지 사용
   - 유지보수가 중단된 패키지는 대안을 찾음
 
3. 특정 패키지만 버전 고정
   - pyproject.toml에서 버전 범위를 조정
 
4. 패키지 기여
   - 오픈소스 패키지라면 3.13 호환성 PR 제출

Step 4: 코드 수정

distutils 마이그레이션

distutils -> setuptools
python
# 변경 전 (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))

typing 임포트 정리

typing 임포트 현대화
python
# 변경 전
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()
    ...

Ruff로 자동 수정

Ruff로 코드 자동 수정
bash
# 타입 힌트 현대화 (UP 규칙)
ruff check --select UP --fix --target-version py312 src/
 
# 임포트 정리
ruff check --select I --fix src/
 
# 전체 자동 수정
ruff check --fix src/
 
# 포매팅
ruff format src/

Step 5: 테스트 실행

CI/CD에 새 버전 추가

GitHub Actions: 멀티 버전 테스트
yaml
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/

DeprecationWarning 확인

경고 메시지 확인
bash
# 모든 경고를 에러로 처리하여 테스트
uv run python -W error::DeprecationWarning -m pytest
 
# 또는 경고만 표시
uv run python -W all -m pytest 2>&1 | grep DeprecationWarning

Step 6: 새 기능 점진적 도입

호환성이 확보되면, 새 기능을 점진적으로 도입합니다.

단계적 도입 순서

새 기능 도입 우선순위
text
즉시 도입 (리스크 낮음):
  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 빌드 실험

pyproject.toml 업데이트

최종 pyproject.toml
toml
[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"

도구 전환 체크리스트

도구 전환 체크리스트
text
패키지 관리:
  [ ] 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 훅 업데이트

트러블슈팅

흔한 문제와 해결

자주 발생하는 문제
text
문제: ModuleNotFoundError: No module named 'distutils'
해결: pip install setuptools 또는 해당 import를 setuptools로 변경
 
문제: SyntaxWarning: invalid escape sequence
해결: 문자열의 백슬래시를 raw string(r"...")으로 변경하거나 이스케이프
 
문제: C 확장 빌드 실패
해결: 해당 패키지의 최신 버전으로 업그레이드
 
문제: typing 관련 ImportError
해결: typing에서 제거된 항목을 collections.abc 등으로 변경

SyntaxWarning 대응

Python 3.12에서는 정규표현식 등에서 이스케이프되지 않은 백슬래시에 대해 SyntaxWarning을 발생시킵니다. 3.13에서는 이것이 SyntaxError로 승격될 예정이었으나, 일부는 유예되었습니다.

백슬래시 경고 수정
python
# 경고 발생
pattern = "\d+"  # SyntaxWarning: invalid escape sequence '\d'
 
# 수정 방법 1: raw string 사용 (권장)
pattern = r"\d+"
 
# 수정 방법 2: 이중 백슬래시
pattern = "\\d+"
백슬래시 경고 일괄 수정
bash
# Ruff의 W605 규칙으로 감지 및 수정
ruff check --select W605 --fix src/

마이그레이션 시간 추정

프로젝트 규모별 예상 시간
text
소규모 프로젝트 (코드 5,000줄 이하):
  의존성 확인: 1시간
  코드 수정:  2~4시간
  테스트:    1~2시간
  총:       1일
 
중규모 프로젝트 (코드 5만줄 이하):
  의존성 확인: 2~4시간
  코드 수정:  1~2일
  테스트:    1일
  총:       3~5일
 
대규모 프로젝트 (코드 10만줄 이상):
  의존성 확인: 1일
  코드 수정:  1~2주
  테스트:    1주
  총:       2~4주
Tip

Ruff의 자동 수정 기능을 적극 활용하면 코드 수정 시간을 대폭 단축할 수 있습니다. 특히 typing 임포트 현대화(UP 규칙)와 이스케이프 시퀀스 수정(W605)은 자동으로 처리됩니다.

시리즈 마무리

이 시리즈는 Python 3.12~3.13의 변화를 언어 기능, 성능, 도구 생태계, 실전 활용의 네 가지 축으로 다루었습니다.

Python은 30년이 넘은 언어이지만, 지금 가장 활발하게 진화하고 있습니다. GIL 제거, JIT 컴파일러, Rust 기반 차세대 도구는 Python의 근본적인 제약을 해결하려는 시도입니다. 이 변화의 결과가 완전히 성숙하기까지는 몇 년이 더 걸리겠지만, 방향은 명확합니다.

핵심 내용을 요약합니다.

  • PEP 695 타입 파라미터 문법과 type 문으로 타입 시스템이 현대화되었습니다
  • 패턴 매칭은 복잡한 데이터 분기를 선언적으로 표현합니다
  • f-string의 제약이 해제되고, 에러 메시지가 크게 개선되었습니다
  • PyREPL은 별도 설치 없이 현대적 REPL 경험을 제공합니다
  • free-threaded 모드는 Python 멀티스레딩의 미래를 열었습니다
  • JIT 컴파일러는 향후 성능 향상의 기반입니다
  • uv, Ruff, ty는 Python 도구 생태계의 새로운 표준입니다
  • 마이그레이션은 단계적으로, 자동화 도구를 활용하여 진행하는 것이 안전합니다

Python의 진화는 계속됩니다. 3.14에서는 deferred evaluation of annotations(PEP 649), 더 발전된 JIT, 그리고 free-threaded 모드의 안정화가 예정되어 있습니다. 이 시리즈에서 다룬 내용이 변화에 대응하는 기반이 되기를 바랍니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#python#typescript#performance#devtools#concurrency

관련 글

프로그래밍

12장: AI 개발에서의 Python 활용

AI/ML 개발에서 Python이 차지하는 위치와 최신 트렌드를 다룹니다. PyTorch 생태계, LLM 개발 도구, 타입 안전한 AI 파이프라인, free-threaded Python의 AI 활용을 살펴봅니다.

2026년 2월 7일·13분
프로그래밍

11장: typing 고급 기능 실전 활용

Python 3.12~3.13의 typing 모듈 고급 기능을 다룹니다. TypedDict, Protocol, override, dataclass_transform, TypeGuard, TypeIs 등 실전 타입 시스템을 안내합니다.

2026년 2월 5일·13분
프로그래밍

10장: Ruff와 ty - 차세대 린터, 포매터, 타입 체커

Astral의 Ruff(린터/포매터)와 ty(타입 체커)를 다룹니다. 기존 도구 대체, 설정 방법, 규칙 커스터마이징, IDE 통합, 프로젝트 도입 전략을 안내합니다.

2026년 2월 3일·14분
이전 글12장: AI 개발에서의 Python 활용

댓글

목차

약 17분 남음
  • 마이그레이션을 계획해야 하는 이유
  • 마이그레이션 전략: 한 번에 vs 단계적
    • 권장: 단계적 업그레이드
    • 예외: 3.11에서 3.13으로 직접
  • Step 1: 현재 상태 파악
    • Python 버전과 의존성 확인
    • pyproject.toml 확인
  • Step 2: 호환성 검사
    • 제거된 기능 확인
    • 자동 검사 도구
  • Step 3: 의존성 호환성 확인
    • 주요 라이브러리 호환성 매트릭스
    • 의존성 호환성 확인 방법
    • 호환되지 않는 패키지 대응
  • Step 4: 코드 수정
    • distutils 마이그레이션
    • typing 임포트 정리
    • Ruff로 자동 수정
  • Step 5: 테스트 실행
    • CI/CD에 새 버전 추가
    • DeprecationWarning 확인
  • Step 6: 새 기능 점진적 도입
    • 단계적 도입 순서
    • pyproject.toml 업데이트
  • 도구 전환 체크리스트
  • 트러블슈팅
    • 흔한 문제와 해결
    • SyntaxWarning 대응
  • 마이그레이션 시간 추정
  • 시리즈 마무리