- Published on
모던 Python 2026 — Python 3.13 / 3.14 / free-threaded / uv / Ruff / Polars 1.0 / FastAPI / Litestar / Robyn 심층 가이드
- Authors

- Name
- Youngju Kim
- @fjvbn20031
프롤로그 — 30년 만의 두 변곡점
Python은 1991년에 태어났다. 2026년 기준으로 35살이다. 그 사이 1.x → 2.x → 3.x를 거치며 동적 타이핑 언어의 대표 주자, 데이터·ML의 lingua franca, 백엔드 마이크로서비스의 한 축이 되었다. 하지만 두 가지 만성적인 불만이 있었다.
- GIL(Global Interpreter Lock) — CPython의 거대한 단일 락. CPU-bound 멀티스레딩이 사실상 불가능했다. "Python은 느리다"는 평판의 절반은 여기서 나왔다.
- 패키징·도구 생태계의 파편화 — pip, easy_install, conda, poetry, pipenv, pdm, hatch, rye… 어느 것이 정답인지 합의가 없었다. 그리고 모두 느렸다.
2024~2026년은 이 두 만성 질환이 동시에 큰 수술을 받은 시기다.
- Python 3.13 (2024-10) — PEP 703(free-threaded) 빌드와 PEP 744(JIT) 빌드가 공식 preview로 들어왔다. 30년 만에 처음으로 GIL 없는 CPython이 ABI 단위로 존재했다.
- Python 3.14 (2025-10) — free-threaded 빌드가 stable로 승격되었다. deferred imports(PEP 791), template strings, 더 빠른 startup. 이제 GIL 없는 Python은 "실험"이 아니다.
- uv (2024-02, Astral) — Rust로 작성된 단일 바이너리. pip보다 10~100배 빠른 설치, lock file, venv, Python 인터프리터 관리까지 한 도구로. 사실상 표준이 되어가는 중이다.
- Ruff (Astral) — Rust 단일 바이너리 linter + formatter. flake8 + isort + black + pyupgrade + bandit 일부까지 통합. 수백 배 빠르다.
- ty (Astral, 2025 alpha) — Rust로 다시 쓴 타입 체커. mypy/pyright의 자리를 노린다.
- Polars 1.0 (2024-08) — Rust 코어 DataFrame. Pandas의 단일 스레드 한계와 메모리 비효율을 정조준.
- Pandas 3.0 (2025-05) — Arrow backend, Copy-on-Write 기본화, PyArrow 의존 필수.
- Pydantic v2.10 — Rust 코어 검증, FastAPI의 기반.
- 웹 — FastAPI는 ASGI의 대명사가 되었고, Litestar(舊 Starlite), Robyn(Rust 코어), Quart(async Flask), Sanic, BlackSheep가 각자 색깔로 경쟁한다. Django 5.x는 여전히 풀스택의 견고한 답.
이 글은 이 모든 것을 한 번에 본다. "어떤 도구를 골라야 하는가"가 아니라 "왜 이런 변화가 일어났고, 어떤 트레이드오프가 있는가"를. 코드 예제와 명령어, 그리고 실제 의사결정 가이드까지.
1장 · 2026년 모던 Python의 풍경
2026년 5월 기준, 새 Python 프로젝트를 시작한다고 가정해보자. 5년 전과 비교한 절차의 차이.
2021년:
pyenv install 3.10.0
pyenv local 3.10.0
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
pip-compile requirements.in
flake8 .
black .
isort .
mypy .
pytest
2026년:
uv init # pyproject.toml + .python-version 자동 생성
uv python install 3.14 # Python 인터프리터까지 uv가 관리
uv add fastapi polars # 의존성 추가 + lock + 설치
uv run ruff check --fix . # lint
uv run ruff format . # format
uv run ty check . # type check (alpha지만 사용 가능)
uv run pytest # test
차이를 정리하면.
| 영역 | 2021 | 2026 |
|---|---|---|
| Python 설치 | pyenv | uv |
| venv | python -m venv | uv venv (자동) |
| 의존성 관리 | pip + requirements.txt | uv + pyproject.toml + uv.lock |
| Lock | pip-tools / poetry | uv (내장) |
| Lint | flake8 (~수십초) | ruff (~ms) |
| Format | black (~수초) | ruff format (~ms) |
| Import sort | isort | ruff (통합) |
| Type check | mypy / pyright | ty (alpha) / pyright / mypy |
| DataFrame | Pandas | Polars / Pandas 3.0 |
| 검증 | dataclasses + 수동 | Pydantic v2 |
| Web | Flask/Django/FastAPI | FastAPI/Litestar/Robyn/Django 5 |
| 동시성 | asyncio / multiprocessing | free-threaded (3.13+) + asyncio |
핵심 변화 한 줄 요약: Rust로 다시 쓴 도구들이 Python 도구 체인의 절반을 갈아치웠고, Python 자체는 GIL을 떼어내기 시작했다.
2장 · Python 3.13 (2024-10) — free-threaded preview, JIT preview
Python 3.13은 2024년 10월 7일에 릴리스됐다. 표면적으로는 정기 마이너 버전이지만, 두 가지가 처음이었다.
PEP 703 — free-threaded (no-GIL) build
오랫동안 GIL 제거는 "이론적으로 가능하지만 호환성과 단일 스레드 성능을 깬다"는 합의였다. PEP 703(Sam Gross, Meta)은 이 합의를 깼다. 핵심 아이디어.
- biased reference counting — 객체 소유 스레드는 락 없이 refcount 변경, 다른 스레드는 락 사용.
- deferred reference counting — 일부 immortal 객체(
None, 작은 정수 등)는 refcount를 아예 안 셈. - per-object lock — dict/list 같은 가변 컨테이너에 작은 락을 붙임.
- stop-the-world GC — GC 중에는 모든 스레드 정지(짧게).
빌드는 선택이다. 같은 3.13 소스에서 두 빌드가 나온다.
# 표준 빌드 (GIL 있음)
./configure && make
# free-threaded 빌드 (GIL 없음)
./configure --disable-gil && make
# 인터프리터는 python3.13t (t = threaded)
uv로는 이렇게.
uv python install 3.13 # 일반 빌드
uv python install 3.13t # free-threaded 빌드
uv python install 3.13+freethreaded # 명시적 표기
3.13의 free-threaded는 preview다. 의미.
- ABI가 분리되어 있다. C extension은 별도 빌드 필요(
Py_GIL_DISABLED매크로). - 단일 스레드 성능이 약 10~20% 느리다.
- 일부 stdlib와 많은 C extension이 아직 준비 안 됨.
PEP 744 — Copy-and-Patch JIT (experimental)
같은 3.13에 들어온 또 하나의 큰 변화. Tier 2 인터프리터 위에 올라간 copy-and-patch JIT. LLVM을 빌드 타임에 사용해 "stencil"이라는 기계어 조각을 미리 생성하고, 실행 시 패치해서 native code를 만든다.
./configure --enable-experimental-jit && make
3.13에서는 성능 이득이 크지 않다(0~5%). 하지만 향후 3.14, 3.15에서 본격적인 최적화의 토대가 된다.
그 외 3.13의 주요 변경
- 새로운 REPL — multi-line edit, color, exit on Ctrl+D.
- 개선된 traceback — color, 더 정확한 위치 표시.
- iOS Tier 3, Android Tier 3 — 공식 지원 플랫폼 추가(Beeware/Briefcase의 토대).
- Locals API 재설계 — 디버거의 정확한 변수 수정.
- typing.TypeIs — TypeGuard보다 정확한 narrowing.
- deprecation —
argparse의 일부 API,pkgutil.find_loader등.
3장 · Python 3.14 (2025-10) — free-threaded stable
Python 3.14는 2025년 10월 7일에 릴리스됐다. 3.13에서 시작된 변화의 완성판.
free-threaded가 stable로
3.13에서는 "experimental"이라는 태그가 붙었던 free-threaded 빌드가 3.14에서는 공식 지원 옵션이 되었다. 의미는 크다.
- numpy, scipy, pandas, polars, pillow, lxml, cryptography 등 핵심 패키지가 free-threaded 빌드의 wheel을 PyPI에 공식 업로드.
pip install이 인터프리터 종류를 보고 적절한 wheel을 가져옴.- 단일 스레드 성능 페널티가 3~5%로 축소(JIT와 결합 시 거의 동등).
deferred imports (PEP 791)
# 3.13까지 — import는 즉시
import heavy_module # 인터프리터 startup이 느려짐
# 3.14 — deferred import
from __future__ import deferred_imports
import heavy_module # 실제로 사용될 때 import
CLI 도구와 cold start가 중요한 환경(Lambda, serverless)에서 큰 의미가 있다. uv/Ruff 같은 도구가 빠른 이유 중 하나도 이 패턴을 Rust로 흉내 낸 것.
Template strings — t-strings
# f-string은 즉시 평가
name = "world"
greeting = f"Hello, {name}!" # 즉시 "Hello, world!"
# t-string은 lazy template
template = t"Hello, {name}!" # Template 객체, 평가 안 됨
# 나중에 rendering, escaping, i18n 처리 가능
html = template.render(escape=html_escape)
SQL 인젝션·XSS 방지, i18n, structured logging 등에서 유용하다. 2026년 5월 기준 채택은 아직 초기 단계.
그 외 3.14의 주요 변경
- JIT 성능 개선 — 일부 벤치마크에서 10~15% 향상.
- PEP 768 — 외부 디버거가 안전하게 attach.
- PEP 765 —
finally에서return/break/continue경고. - subinterpreter API — PEP 734로 stdlib에 정식 추가.
- typing.evaluate_forward_ref — forward reference 평가 API.
4장 · PEP 703의 의미 — GIL 제거가 바꾸는 것
GIL이 사라진다는 게 실제로 무엇을 바꾸는가. 짧게 정리.
1) CPU-bound 멀티스레딩이 진짜로 동작한다
# 2024년 이전 — GIL 때문에 의미 없음
from concurrent.futures import ThreadPoolExecutor
def cpu_heavy(n):
s = 0
for i in range(n):
s += i * i
return s
# 스레드 늘려도 단일 코어만 씀
with ThreadPoolExecutor(max_workers=8) as pool:
list(pool.map(cpu_heavy, [10_000_000] * 8))
free-threaded 빌드에서는 8개 스레드가 8개 코어에 실제로 분산된다. multiprocessing이 필요했던 많은 워크로드가 ThreadPool로 충분해진다(메모리 공유가 가능하고 IPC 오버헤드가 없으니).
2) C extension 작성자의 책임이 늘어난다
GIL은 단일 스레드 전제를 강제했다. 이제 모든 C extension은 thread-safety를 직접 보장해야 한다.
- 전역 가변 상태가 있으면 락이 필요.
PyObject조작은 안전하지만, 자체 C 자료구조는 직접 보호.Py_GIL_DISABLED매크로로 빌드 시 분기 가능.
numpy, scipy 같은 거대 패키지는 1~2년에 걸쳐 점진적으로 free-threaded ready 상태가 되었다. 작은 C extension은 아직 시간이 필요하다.
3) asyncio와의 관계
asyncio는 단일 스레드의 이벤트 루프다. GIL 제거와는 다른 축의 동시성. 다만 둘을 조합하기가 쉬워진다.
- I/O는 asyncio 코루틴으로.
- CPU-bound 부분은
loop.run_in_executor(ThreadPoolExecutor(), ...)로 진짜 병렬화.
4) 단일 스레드 성능 페널티
biased refcount 같은 메커니즘은 어쩔 수 없이 약간의 오버헤드를 만든다. 3.13에서 ~15%, 3.14에서 35%로 줄었지만 0은 아니다. CPU-bound가 멀티스레딩으로 N배 빨라지지 않는 워크로드라면 표준 빌드가 유리할 수 있다.
5) 생태계 분기 위험
같은 Python 3.14에 두 ABI가 존재한다는 건 패키지 메인테이너의 부담이 두 배가 된다는 뜻. 작은 라이브러리는 한쪽만 지원할 수 있고, 그게 사용자에게 혼란을 준다. 이 부분은 2027~2028년에 어떻게 정착할지가 관건.
5장 · uv (Astral) — pip / poetry / pipenv를 대체하는 단일 도구
uv는 Astral이 2024년 2월에 발표한 Rust 기반의 단일 바이너리 패키지 매니저다. Ruff를 만든 같은 회사다. 발표 당시 슬로건은 "An extremely fast Python package installer and resolver". 사실이었다.
무엇을 대체하는가
| 기존 도구 | uv가 대체하는 기능 |
|---|---|
| pip | install / uninstall |
| pip-tools | requirements compile / lock |
| pipx | 글로벌 CLI 도구 설치 |
| poetry | 프로젝트·의존성 관리 |
| pipenv | 의존성 + venv |
| pyenv | Python 인터프리터 설치·관리 |
| virtualenv | venv 생성 |
| twine | 패키지 빌드/업로드 (uv build, uv publish) |
다른 말로, Python 패키징의 거의 모든 레이어를 한 바이너리로.
설치와 기본 사용
# 설치 (macOS/Linux)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 새 프로젝트
uv init my-app
cd my-app
# pyproject.toml, .python-version, README.md 자동 생성
# Python 인터프리터 설치
uv python install 3.14
# 패키지 추가
uv add fastapi pydantic 'polars[all]'
uv add --dev pytest ruff
# 동기화 (lock에 맞춰 venv 정확하게 일치)
uv sync
# 실행
uv run python -m my_app
uv run pytest
uv run ruff check
왜 그렇게 빠른가
- Rust + 비동기 I/O — 의존성 해석을 병렬로.
- 글로벌 캐시 + 하드 링크 — 같은 wheel을 여러 프로젝트가 공유, 디스크 사용량 절감.
- PubGrub solver — 결정론적이고 빠른 의존성 해결.
- Wheel-only 우선 — 가능하면 sdist 빌드를 피함.
- HTTP/2 + ZST.
내 머신에서 측정한 비교(2025년 후반, 평범한 FastAPI 프로젝트, 약 80개 의존성).
| 작업 | pip | poetry | uv |
|---|---|---|---|
| Cold install | 48s | 62s | 2.1s |
| Warm install | 12s | 18s | 0.4s |
| Lock 생성 | n/a | 24s | 0.9s |
차이가 너무 커서 한 번 써보면 돌아가기 어렵다.
pyproject.toml과 uv.lock
# pyproject.toml
[project]
name = "my-app"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
"fastapi>=0.115",
"pydantic>=2.10",
"polars[all]>=1.0",
]
[tool.uv]
dev-dependencies = [
"pytest>=8.0",
"ruff>=0.7",
"ty>=0.0.1a8",
]
[tool.ruff]
line-length = 100
uv.lock은 정확한 hash와 marker가 포함된 lock 파일. 커밋해서 팀이 공유한다. uv sync는 venv를 lock에 맞춰 정확하게 만든다.
Python 인터프리터 관리
uv python list # 사용 가능한 버전
uv python install 3.13 3.14 3.14t # 여러 개 설치
uv python pin 3.14 # .python-version 작성
pyenv가 하던 일을 한다. 차이점: uv가 미리 빌드된 인터프리터를 직접 다운로드하므로 빠르고 컴파일 의존성이 필요 없다.
글로벌 CLI 도구
uv tool install ruff # pipx와 같은 역할
uv tool install httpie
uv tool run pip-audit # 일회성 실행
uvx pip-audit # uv tool run의 alias
2026년 표준화 흐름
- PyPI 다운로드 통계에서 pip 사용량은 여전히 1위지만, CI 환경에서 uv 사용은 폭발적으로 증가.
- poetry는 여전히 큰 사용자층을 유지하지만 신규 프로젝트에서는 uv가 우세.
- Astral은 Python Foundation의 후원사 중 하나. PSF/PyPA와의 협력도 활발.
6장 · Ruff (Astral) — flake8 / black / isort를 통합한 Rust 도구
Ruff는 Astral의 첫 제품이다(2022년 첫 릴리스, 20242025년에 폭발적으로 성장). 한 줄로 요약하면 **"flake8보다 10100배 빠르고, black/isort/pyupgrade의 기능까지 흡수한 Rust 단일 바이너리"**.
무엇을 대체하는가
| 기존 도구 | Ruff의 대응 |
|---|---|
| flake8 | ruff check |
| pycodestyle | ruff check (E 룰) |
| pyflakes | ruff check (F 룰) |
| isort | ruff check --select I 또는 ruff format |
| black | ruff format |
| pyupgrade | ruff check --select UP |
| autoflake | ruff check --fix --select F401 |
| bandit (일부) | ruff check --select S |
| flake8-bugbear | ruff check --select B |
| flake8-comprehensions | ruff check --select C4 |
| pydocstyle | ruff check --select D |
수백 개의 룰이 한 바이너리에 들어 있고, 켜고 끄는 것을 설정으로 제어한다.
기본 사용
uv add --dev ruff
uv run ruff check . # lint
uv run ruff check --fix . # 자동 수정
uv run ruff format . # format (black 호환)
uv run ruff format --check . # CI에서 형식 검증
pyproject.toml 설정
[tool.ruff]
line-length = 100
target-version = "py313"
[tool.ruff.lint]
select = [
"E", "F", "W", # pycodestyle, pyflakes
"I", # isort
"UP", # pyupgrade
"B", # bugbear
"C4", # comprehensions
"SIM", # simplify
"RUF", # ruff-specific
]
ignore = ["E501"] # line too long (formatter가 처리)
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101"] # assert in tests
[tool.ruff.format]
quote-style = "single"
왜 그렇게 빠른가
- Rust로 작성된 단일 AST 패스 — 여러 도구가 각자 파일을 파싱하지 않음.
- 병렬 처리 — 파일별 병렬, 룰별 병렬.
- incremental — 변경된 파일만 재검사.
- 메모리 효율 — 큰 코드베이스에서 black의 OOM이 잘 안 남.
실제 벤치마크. Django 코드베이스(~3500 파일).
| 도구 | 시간 |
|---|---|
| flake8 | 12.3s |
| black --check | 8.1s |
| isort --check | 4.5s |
| pyupgrade | 6.2s |
| 합계(직렬) | 31.1s |
| ruff check + ruff format --check | 0.4s |
수십 배 차이. 이게 CI 비용과 개발자 체감의 차이를 모두 만든다.
에디터 통합
- VS Code: Ruff 공식 확장(Astral 관리). LSP 기반.
- PyCharm/IntelliJ: Ruff 공식 플러그인.
- Neovim: ruff-lsp (또는 ruff의 내장 LSP).
- Zed: 기본 통합.
Formatter — black 호환 + 알파
ruff format은 의도적으로 black과 동일한 출력을 목표로 한다(99% 이상 호환). 차이가 나는 경우는 보통 black의 버그이거나 의도적인 개선(예: 매직 trailing comma 처리). black을 쓰던 팀이 무손실로 마이그레이션 가능.
7장 · ty (Astral) — Rust로 다시 쓴 타입 체커 (alpha)
ty는 Astral이 2025년에 alpha로 공개한 Rust 타입 체커다. mypy/pyright의 영역을 정조준한다. 2026년 5월 기준 여전히 alpha지만 일부 프로젝트가 채택을 시작했다.
왜 또 다른 타입 체커인가
타입 체커의 시장은 이미 복잡하다.
- mypy — 원조. PEP 484의 reference impl. Python으로 작성. 느림.
- pyright — Microsoft. TypeScript로 작성. 빠르고 정확. VS Code(Pylance)의 기반.
- pyre — Meta. OCaml. Instagram에서 사용.
- pytype — Google. Python. 점진적 타이핑에 강함.
ty의 포지션.
- Rust로 작성 — pyright 수준 또는 그 이상의 속도 목표.
- incremental — Ruff/uv처럼 변경 부분만 재검사.
- MIT 라이센스 — Astral 다른 도구와 일관.
- LSP first-class — 에디터 통합 우선.
- Astral 통합 — uv/ruff와의 매끄러운 결합.
기본 사용
uv add --dev ty
# 디렉토리 검사
uv run ty check src/
# 단일 파일
uv run ty check src/main.py
# watch 모드
uv run ty check --watch src/
2026년 5월 시점의 현실
ty는 여전히 alpha다. 의미.
- 일부 typing 기능(특히 generics, TypeVar bounds 등)이 미구현.
- 에러 메시지가 mypy/pyright보다 거칠 수 있음.
- 실 서비스에는 pyright 또는 mypy를 메인으로, ty를 보조로 쓰는 패턴.
성능은 인상적. 큰 코드베이스에서 mypy가 5분 걸리는 것이 ty에서 ~5초. 정착하면 게임을 바꿀 가능성이 있다.
권장 조합
- 현재 권장(2026년 5월): 메인은 pyright(엄격) 또는 mypy(점진), CI에 ty 추가로 빠른 1차 게이트.
- 2027년 전망: ty가 stable이 되면 메인으로 전환 가능.
8장 · Polars 1.0 (2024-08) — Pandas의 대안
Polars는 Ritchie Vink가 2020년에 시작한 Rust 기반 DataFrame 라이브러리. 2024년 8월 1.0이 나왔다. Pandas의 단일 스레드, 컬럼 단위 비효율, 메모리 폭주 문제를 정조준.
핵심 차이
- Rust 코어 — 컴파일된 native code.
- Apache Arrow — 컬럼 메모리 표현. zero-copy interop.
- lazy execution — 쿼리 플래너가 최적화 후 실행.
- multi-threaded by default — Rayon으로 자동 병렬.
- predicate pushdown / projection pushdown — SQL 옵티마이저 수준의 최적화.
eager vs lazy
import polars as pl
# eager — pandas 스타일
df = pl.read_csv("data.csv")
result = df.filter(pl.col("age") > 30).group_by("city").agg(pl.col("salary").mean())
# lazy — 최적화 후 실행
lf = pl.scan_csv("data.csv") # 아직 안 읽음
result = (
lf.filter(pl.col("age") > 30)
.group_by("city")
.agg(pl.col("salary").mean())
.collect() # 여기서 실행
)
lazy 모드에서는 옵티마이저가 "필터를 어떻게 미리 적용할지", "어떤 컬럼만 읽을지"를 결정해서 disk I/O와 메모리를 크게 줄인다.
Pandas와의 성능 비교
H2O.ai의 데이터프레임 벤치마크(group-by, join, 5GB).
| 라이브러리 | group-by | join |
|---|---|---|
| Pandas 2.x | 95s | OOM |
| Pandas 3.0 (PyArrow) | 41s | 220s |
| Polars 1.0 (eager) | 12s | 38s |
| Polars 1.0 (lazy) | 6.8s | 22s |
특히 join이나 메모리 한계 근처에서 차이가 크다.
언제 Polars, 언제 Pandas
Polars:
- 100MB 이상 데이터.
- 새 프로젝트.
- 멀티코어 활용이 필요.
- SQL 쿼리 옵티마이저처럼 표현하고 싶을 때.
Pandas:
- 기존 노트북/생태계와의 호환(scikit-learn, statsmodels, matplotlib의 일부).
- "10년치 Stack Overflow 답변"이 필요한 신규 데이터 사이언티스트.
- 작은 데이터(수 MB).
- jupyter에서
.head()만 보면 되는 탐색.
Pandas와의 interop
df_pl = pl.from_pandas(df_pd)
df_pd = df_pl.to_pandas() # zero-copy if PyArrow
arr = df_pl.to_arrow() # Arrow Table
df_pl2 = pl.from_arrow(arr)
Arrow를 통한 zero-copy interop이 점점 표준화되어 두 라이브러리를 섞어 쓰는 게 부담이 적다.
9장 · Pandas 3.0 (2025-05) — 컴백
Pandas는 죽지 않았다. 2025년 5월에 나온 3.0은 가장 큰 메이저 업데이트.
3.0의 큰 변화
- Apache Arrow가 기본 backend로 진입 — numpy backend는 deprecated 경로.
- Copy-on-Write가 기본 — 메모리 사용량과 안전성 동시 개선.
- PyArrow 의존 필수 — 더 이상 optional이 아님.
- string dtype 기본화 — Python object 대신 pyarrow string.
- inplace 메서드 다수 제거 — CoW와 충돌.
- Python 3.10+ 요구.
Copy-on-Write의 의미
import pandas as pd
df1 = pd.DataFrame({"a": [1, 2, 3]})
df2 = df1 # 별칭
df2.loc[0, "a"] = 999
# 2.x: df1["a"][0] 도 999가 됨 (SettingWithCopyWarning)
# 3.0: df1은 변하지 않음 (CoW로 분기)
오랫동안 Pandas 사용자를 괴롭힌 SettingWithCopyWarning의 종말. 단, inplace 동작에 의존하던 코드는 다 깨진다. 마이그레이션 가이드를 읽고 다닐 것.
성능
Arrow backend 덕에 string 처리, group-by, 일부 join이 2.x 대비 2~5배 빨라졌다. Polars만큼은 아니지만 격차가 줄었다.
10장 · Pydantic v2.10 — 데이터 검증의 사실상 표준
Pydantic은 v1까지는 순수 Python이었지만 v2(2023)부터 Rust 코어로 다시 작성되었다. v2.10(2025년 후반)은 v2 라인의 안정화된 버전이다.
무엇을 하는가
- 런타임 데이터 검증과 직렬화.
- FastAPI, Litestar, BlackSheep의 기반.
- LangChain의 BaseTool, OpenAI structured output 등 LLM 도구의 기본 어댑터.
기본 예제
from pydantic import BaseModel, Field, EmailStr
from datetime import datetime
class User(BaseModel):
id: int
name: str = Field(min_length=1, max_length=64)
email: EmailStr
created_at: datetime
tags: list[str] = []
# 검증 + 변환
u = User.model_validate({
"id": "42", # str → int 자동
"name": "Alice",
"email": "alice@example.com",
"created_at": "2026-05-16T10:00:00Z",
})
print(u.model_dump_json())
v2의 성능
Rust 코어 덕에 v1 대비 5~50배 빠르다(스키마 복잡도에 따라). FastAPI 같은 프레임워크에서 P99 latency가 눈에 띄게 개선됐다.
Pydantic Settings
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
redis_url: str = "redis://localhost"
log_level: str = "INFO"
class Config:
env_file = ".env"
settings = Settings()
12-factor app의 config 패턴을 깔끔하게 한다.
LLM 도구에서의 활용
OpenAI/Anthropic의 structured output, function calling이 Pydantic 모델로 schema를 받아 enforce한다. LangChain, LlamaIndex, Pydantic AI 등의 기본 어댑터도 Pydantic.
from pydantic import BaseModel
from anthropic import Anthropic
class SearchQuery(BaseModel):
query: str
max_results: int = 10
# Anthropic SDK가 schema를 추출해서 tool definition으로 변환
client = Anthropic()
11장 · 웹 프레임워크 — FastAPI / Litestar / Robyn / Quart / Sanic / BlackSheep
2026년 Python 웹 프레임워크 시장은 어느 때보다 다원화되어 있다. 각자 강점이 다르다.
FastAPI
- 2018년 등장, ASGI 기반.
- Pydantic + Starlette + OpenAPI 자동 생성.
- 사실상 ASGI의 대표.
- 학습 곡선이 부드럽고, 커뮤니티가 가장 큼.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.post("/items/")
async def create_item(item: Item) -> dict:
return {"id": 1, **item.model_dump()}
Litestar (구 Starlite)
- 2022년 Starlite로 시작, 2023년 Litestar로 rebranding.
- FastAPI에 영감을 받았으나 더 큰 야망(controller, layered DI, plugin system).
- DTO 시스템, msgspec/Pydantic/attrs 모두 지원.
- 성능이 FastAPI보다 약간 빠름(특정 조건).
from litestar import Litestar, post
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
@post("/items/")
async def create_item(data: Item) -> dict:
return {"id": 1, **data.model_dump()}
app = Litestar([create_item])
Robyn
- 2022년 등장, Rust 코어 + Python API.
- 단일 프로세스에서 multi-threaded 처리(Rust의 tokio 활용).
- 매우 빠름 (FastAPI보다 2~5배 throughput).
- 생태계는 작지만 성능이 절실한 곳에서 선택됨.
from robyn import Robyn
app = Robyn(__file__)
@app.get("/")
async def hello():
return "hello, world"
app.start(port=8080)
Quart
- Flask의 async 버전.
- 거의 동일한 API, 같은 Pallets 팀 일부 참여.
- Flask 생태계를 그대로 사용하면서 async를 도입하고 싶을 때.
Sanic
- 2016년부터의 베테랑.
- 빠르고, blueprint 패턴.
- "단순한 ASGI"가 필요할 때.
BlackSheep
- .NET ASP.NET 영향을 받은 ASGI 프레임워크.
- DI container, OpenAPI, 강한 타이핑.
- C 코어로 성능이 좋음.
선택 가이드
- 시작/팀 작음/생태계 중요 → FastAPI
- 엔터프라이즈/구조화된 큰 앱 → Litestar
- 처리량이 절실 → Robyn 또는 BlackSheep
- 기존 Flask 코드 활용 → Quart
- 단순함 → Sanic
12장 · Django 5.x — 풀스택 클래식의 견고함
Django는 2005년부터의 어른이다. 2026년에도 Python 풀스택의 대표다.
Django 5.x의 큰 변화
- 5.0 (2023-12) — DB-backed default, simplified form templates, GeneratedField.
- 5.1 (2024-08) — CSRF middleware reorg, querysets exposed in ORM more.
- 5.2 (2025-04) — async ORM queries 일부, automatic model importing.
핵심은 async 지원이 점진적으로 성숙해지는 중이라는 것. ORM의 async는 5.2에서 일부 stable, 전체는 6.0(2026 말 예정)에서 완성 예정.
언제 Django
- 어드민이 필요할 때 (Django Admin은 여전히 최고).
- ORM·migration·auth·forms·templates·테스팅이 한 패키지에 들어 있어야 할 때.
- 큰 모놀리스가 정답인 경우.
- Wagtail, django-CMS 같은 성숙한 CMS가 필요할 때.
언제 안 쓰는가
- 작은 API 하나 — FastAPI/Litestar가 가벼움.
- 동시성/저지연이 극한 — Django는 여전히 sync 우선.
- 마이크로서비스 단위 — Django의 batteries가 부담.
Django Ninja — 같은 ORM, FastAPI 스타일 API
from ninja import NinjaAPI
from pydantic import BaseModel
api = NinjaAPI()
class ItemIn(BaseModel):
name: str
price: float
@api.post("/items/")
def create_item(request, item: ItemIn):
return {"id": 1, **item.dict()}
Django의 ORM/auth/admin을 유지하면서 FastAPI 스타일의 API를 쓰고 싶을 때 좋은 답.
13장 · 패키징 — uv / Briefcase / Nuitka / PyInstaller
배포 형태별로 도구가 다르다.
라이브러리 패키징 — uv build / hatchling
uv build # sdist + wheel 생성
uv publish # PyPI 업로드 (twine 대체)
내부적으로 hatchling 같은 PEP 517 빌드 백엔드를 호출. setup.py는 사실상 끝났다.
단일 실행 파일 — PyInstaller / Nuitka
PyInstaller:
uv tool install pyinstaller
pyinstaller --onefile my_app.py
# dist/my_app
장점: 거의 모든 라이브러리와 호환. 단점: 큰 binary, AV false positive, 느린 startup.
Nuitka:
uv add --dev nuitka
python -m nuitka --standalone --onefile my_app.py
장점: Python 코드를 실제 C로 컴파일해서 더 빠르고 작음. 단점: 빌드 느림, 일부 동적 import에 약함.
데스크탑/모바일 — Briefcase (BeeWare)
Python 코드를 native iOS/Android/macOS/Windows 앱으로 패키징.
uv tool install briefcase
briefcase new
briefcase create iOS
briefcase build iOS
briefcase run iOS
Python 3.13의 iOS/Android Tier 3 지원과 결합해 모바일에서 Python을 돌리는 시나리오가 현실적이 됐다.
그 외
- shiv / zipapp — 단순 zip 기반 배포.
- conda-pack — conda 환경 통째로 packaging.
- Docker — 가장 흔한 배포 단위.
python:3.14-slim+ uv 조합이 표준.
14장 · 클라우드 — Modal / Replicate / Pyodide
Modal
- Python 함수를 그대로 클라우드 GPU/CPU에서 실행.
- 데코레이터로 인프라 정의.
- "serverless GPU"의 대표.
import modal
app = modal.App("ml-job")
@app.function(gpu="A100", timeout=600)
def train(epochs: int):
import torch
# 학습 코드
return "done"
if __name__ == "__main__":
with app.run():
train.remote(epochs=10)
Replicate
- ML 모델 호스팅 + API.
- Cog로 모델을 컨테이너화.
- Stable Diffusion, LLM 등 오픈소스 모델 추론에 자주 사용.
Pyodide
- Python을 WebAssembly로 컴파일해 브라우저에서 실행.
- JupyterLite, Streamlit-in-browser, marimo의 브라우저 모드 등의 기반.
- 2026년에는 numpy, pandas, scipy까지 거의 모든 과학 스택이 동작.
15장 · 한국 / 일본의 Python 활용
한국
- 토스(Toss) — 백엔드는 Kotlin 중심이지만, ML/데이터 엔지니어링·내부 도구에 Python 활용. 채용에 Python skill을 명시.
- 카카오 — 추천/검색의 ML 파이프라인, ad tech의 데이터 파이프라인, 카카오톡의 챗봇 등에 광범위 사용.
- 네이버 — 클로바·하이퍼클로바의 학습/서빙 인프라, 검색의 데이터 파이프라인, 라인의 ML 백엔드.
- 쿠팡 — 데이터 사이언스, 추천 시스템, 가격 최적화에 Python + PySpark.
- 당근 — ML 추천, 데이터 파이프라인, A/B 테스트.
스타트업 트렌드: FastAPI + Polars + uv 조합이 빠르게 표준화 중. 데이터 직군은 거의 Python 일색.
일본
- メルカリ(Mercari) — ML 플랫폼, search relevance, fraud detection에 Python. 사내 ML 플랫폼 Bakuraku, MLOps에 활발히 투자.
- PFN(Preferred Networks) — Chainer를 만들었던 회사. PyTorch로 전환 후에도 Python ML R&D의 일본 대표.
- LINE야후 — 검색·광고·메신저의 ML/데이터 파이프라인.
- DeNA — 게임·헬스케어·MaaS 등에서 Python ML.
- SmartNews — 추천 시스템.
일본은 전통적으로 Ruby 비중이 높았지만, 데이터·ML 영역에서 Python으로의 이동이 강하다.
16장 · 누가 무엇을 골라야 하나
상황별 권장 스택.
데이터 분석/사이언스
- Python 3.13 (free-threaded는 아직 보조)
- uv + Ruff
- Polars (큰 데이터) / Pandas 3.0 (생태계 호환)
- jupyter / marimo (별도 글에서 다룸)
- scikit-learn, statsmodels, plotly/altair
ML/AI 학습 워크로드
- Python 3.13 (free-threaded 또는 표준)
- uv + Ruff
- PyTorch / JAX
- transformers / vLLM / sglang
- Modal (서버리스 GPU) 또는 RunPod, Replicate
- mlflow / wandb
웹 백엔드 (마이크로서비스)
- Python 3.13 또는 3.14
- uv + Ruff + ty(보조)
- FastAPI 또는 Litestar
- Pydantic v2
- SQLModel / SQLAlchemy 2.0 / Tortoise ORM
- Uvicorn / Granian
- Docker: python:3.14-slim
웹 백엔드 (모놀리스 + 어드민)
- Django 5.x
- uv + Ruff
- Django Ninja (REST가 필요할 때)
- Celery / Django-Q
- PostgreSQL
CLI 도구
- Python 3.14 (deferred imports로 빠른 startup)
- uv + Ruff
- Typer 또는 Click
- Rich / Textual (TUI)
- PyInstaller 또는 Nuitka로 배포
데스크탑/모바일
- Python 3.13/3.14
- Briefcase (모바일) / Toga (cross-platform UI)
- Nuitka (단일 실행 파일)
임베디드
- MicroPython 또는 CircuitPython (CPython 아님).
- 단, ARM 리눅스(Raspberry Pi 등)는 일반 CPython.
17장 · 마이그레이션 체크리스트 — 기존 프로젝트를 2026 스타일로
기존 Python 프로젝트가 있다면 어떻게 옮기는가.
1단계 — uv 도입 (위험도 낮음)
# pyproject.toml이 이미 있다면
uv lock # uv.lock 생성
uv sync # venv 생성/동기화
# requirements.txt 기반이라면
uv add -r requirements.txt
기존 워크플로우와 병행 가능. CI에서 uv sync && uv run pytest로 점진적 전환.
2단계 — Ruff 도입 (위험도 낮음)
uv add --dev ruff
# 처음에는 lint만, format은 black 유지하면서 비교
uv run ruff check --select F,E .
# 익숙해지면 룰을 확장하고 format도 ruff로
3단계 — Pydantic v1 → v2 (중간 위험)
API가 크게 바뀜. 변환 도구 사용.
uv tool install bump-pydantic
bump-pydantic src/
4단계 — Pandas → Polars (선택, 큰 작업)
전체 마이그레이션보다 hot path만 선별. interop이 매끄러우니 점진적 가능.
5단계 — Python 3.13/3.14로 업그레이드
uv python install 3.14
uv python pin 3.14
uv sync
uv run pytest
free-threaded 빌드는 별도 검토. C extension 호환을 확인하고.
6단계 — Type checker
mypy를 쓰고 있다면 유지하면서 ty를 CI 보조 게이트로 추가.
18장 · 흔한 함정과 모범 사례
pip install -r requirements.txt를 Dockerfile에서 그대로 쓰지 않기 — uv를 쓰면 10배 빠른 빌드.import pandas as pd를 모듈 최상단에 두지 말기 (CLI) — cold start가 폭주. 함수 안에서 lazy import 또는 3.14의 deferred imports.- free-threaded 빌드를 모든 워크로드에 쓰지 말기 — I/O 중심이면 표준 빌드가 빠를 수 있음.
- Polars를 도입할 때 lazy 모드를 적극 활용 — eager만 쓰면 Pandas의 절반 정도 이득에 그침.
- Pydantic 모델을 함수 호출마다 새로 만들지 말기 — 스키마 컴파일 비용이 있음. 모듈 레벨로.
asyncio.run()안에서 sync 라이브러리 호출하지 말기 — 이벤트 루프 블록.run_in_executor사용.- Ruff의
--fix를 무비판적으로 적용하지 말기 — 일부 룰은 의미를 바꿈. diff 검토 필수. - uv.lock을 .gitignore에 넣지 말기 — 팀 환경 재현성의 핵심.
- 타입 체커 두 개를 동시에 메인으로 쓰지 말기 — 다른 메시지가 충돌. 메인 하나 + CI 보조 하나.
19장 · 미래 — 2027~2028년 전망
- free-threaded가 기본 — 3.16 또는 3.17쯤 표준 빌드가 free-threaded가 될 가능성. 표준/no-GIL 두 빌드를 유지하는 비용이 크기 때문.
- JIT의 본격 성능 이득 — 3.15
3.16에서 1030% 향상 기대. - ty의 stable 진입 — 2026년 말~2027년 중반.
- Polars의 추격 가속 — Pandas와의 격차 확대 또는 Pandas가 Polars 스타일로 흡수.
- Astral의 IDE 또는 Python 배포판 — 가능성. ruff/uv/ty가 묶이는 통합 경험.
- Pyodide의 메인스트림화 — 브라우저에서 데이터 분석/시각화가 SaaS 표준이 됨.
- 모바일 Python — Briefcase + Python 3.14의 iOS/Android stable로 작은 native 앱이 현실적.
20장 · 정리 — 두 변곡점이 만든 새 Python
2026년의 Python은 두 가지 큰 사건의 교차점에 서 있다.
-
언어 자체가 GIL을 떼어내기 시작했다 (PEP 703, 3.13 preview → 3.14 stable). 30년 만의 가장 큰 런타임 변화. CPU-bound 스레딩이 진짜로 가능해지고, asyncio와의 조합이 깔끔해진다. 단, C extension 생태계가 적응하는 데 2~3년이 더 걸린다.
-
Astral이 도구 체인의 절반을 Rust로 갈아치웠다 (uv, Ruff, ty). pip/poetry/flake8/black/isort/mypy가 한 회사의 도구 두세 개로 통합되는 중. 속도가 10~100배 빨라지면서 CI 비용과 개발자 체감이 동시에 좋아졌다.
여기에 더해 Pydantic v2의 Rust 코어, Polars의 Apache Arrow, FastAPI/Litestar/Robyn의 ASGI 생태계 다원화, Pandas 3.0의 Arrow backend 흡수, Django 5.x의 async 점진적 성숙 — 모든 레이어가 동시에 움직이고 있다.
5년 전 Python 코드를 본 적이 있다면, 2026년의 모던 Python 프로젝트는 외관상 거의 같아 보이지만 그 아래의 도구·런타임·데이터 처리 방식이 거의 전부 바뀌었다. 마이그레이션의 좋은 점은 한꺼번에 할 필요가 없다는 것. uv 도입 → Ruff 도입 → Pydantic v2 → Polars hot path → Python 3.14 → free-threaded(필요할 때만) 순으로 점진적으로 옮기면 된다.
Python은 30년이 넘었지만, 지금이 그 어느 때보다 빠르게 변하는 시기다. 따라가는 보람이 있는 변화다.
참고 / References
- Python 3.13 release notes — https://docs.python.org/3.13/whatsnew/3.13.html
- Python 3.14 release notes — https://docs.python.org/3.14/whatsnew/3.14.html
- PEP 703 — Making the GIL Optional in CPython — https://peps.python.org/pep-0703/
- PEP 744 — JIT Compilation — https://peps.python.org/pep-0744/
- PEP 791 — Deferred Evaluation of Imports — https://peps.python.org/pep-0791/
- PEP 765 — Disallow return/break/continue in finally — https://peps.python.org/pep-0765/
- PEP 734 — Multiple Interpreters in the Stdlib — https://peps.python.org/pep-0734/
- PEP 750 — Template Strings — https://peps.python.org/pep-0750/
- Astral — Company blog — https://astral.sh/blog
- uv documentation — https://docs.astral.sh/uv/
- Ruff documentation — https://docs.astral.sh/ruff/
- ty documentation — https://github.com/astral-sh/ty
- Polars documentation — https://docs.pola.rs/
- Polars 1.0 announcement — https://pola.rs/posts/announcing-polars-1/
- Pandas 3.0 — https://pandas.pydata.org/docs/whatsnew/v3.0.0.html
- Pydantic v2 — https://docs.pydantic.dev/latest/
- FastAPI — https://fastapi.tiangolo.com/
- Litestar — https://litestar.dev/
- Robyn — https://robyn.tech/
- Quart — https://quart.palletsprojects.com/
- Sanic — https://sanic.dev/
- BlackSheep — https://www.neoteroi.dev/blacksheep/
- Django 5 — https://docs.djangoproject.com/en/5.2/releases/
- Django Ninja — https://django-ninja.dev/
- Briefcase / BeeWare — https://beeware.org/project/projects/tools/briefcase/
- Nuitka — https://nuitka.net/
- PyInstaller — https://pyinstaller.org/
- Modal — https://modal.com/
- Replicate — https://replicate.com/
- Pyodide — https://pyodide.org/
- Sam Gross — Free-Threaded Python design — https://github.com/colesbury/nogil
- Python.org downloads — https://www.python.org/downloads/
- PyPI — https://pypi.org/
- PEP index — https://peps.python.org/