Skip to content

필사 모드: Modern Python in 2026 — Python 3.13 / 3.14 / free-threaded / uv / Ruff / Polars 1.0 / FastAPI / Litestar / Robyn deep-dive

English
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

Prologue — Two inflection points in one decade

Python was born in 1991. It turns 35 in 2026. Across 1.x to 2.x to 3.x it became the flagship dynamic language, the lingua franca of data and ML, and a major pillar of backend microservices. But it carried two chronic complaints.

1. **The GIL (Global Interpreter Lock)** — CPython's single giant lock. CPU-bound multithreading was effectively impossible, and half of Python's "slow" reputation came from here.

2. **A fragmented packaging and tooling ecosystem** — pip, easy_install, conda, poetry, pipenv, pdm, hatch, rye… there was no consensus. And all of them were slow.

2024 through 2026 is when these two chronic conditions both got major surgery, at the same time.

- **Python 3.13** (Oct 2024) — PEP 703 (free-threaded) and PEP 744 (JIT) builds landed as **official previews**. For the first time in 30 years, a CPython without the GIL existed as an ABI.

- **Python 3.14** (Oct 2025) — the free-threaded build was promoted to **stable**. Deferred imports (PEP 791), template strings, faster startup. A no-GIL Python is no longer "experimental."

- **uv** (Feb 2024, Astral) — a single Rust binary. 10–100x faster installs than pip, a lockfile, venv management, and Python interpreter installation in one tool. **It is becoming the de facto standard**.

- **Ruff** (Astral) — a single Rust linter and formatter. Absorbs flake8, isort, black, pyupgrade, and parts of bandit. Hundreds of times faster.

- **ty** (Astral, alpha 2025) — a type checker rewritten in Rust, going after mypy and pyright.

- **Polars 1.0** (Aug 2024) — a Rust-core DataFrame. Targets the single-threaded ceiling and memory inefficiency of Pandas head-on.

- **Pandas 3.0** (May 2025) — Arrow backend, Copy-on-Write by default, PyArrow as a hard dependency.

- **Pydantic v2.10** — Rust-core validation, the foundation of FastAPI.

- **Web** — FastAPI is the ASGI default; Litestar (formerly Starlite), Robyn (Rust core), Quart (async Flask), Sanic, and BlackSheep compete with distinct flavors. Django 5.x remains the rock-solid full-stack answer.

This article walks through all of it at once. Not "which tool should I pick" but "why did these changes happen, and what tradeoffs come with them." With code examples, commands, and an actual decision guide.

1. The 2026 modern Python landscape

As of May 2026, imagine starting a new Python project. Compare the procedure to five years ago.

**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 # creates pyproject.toml + .python-version

uv python install 3.14 # uv manages the interpreter too

uv add fastapi polars # add dep + lock + install

uv run ruff check --fix . # lint

uv run ruff format . # format

uv run ty check . # type check (usable even at alpha)

uv run pytest # test

Summarized.

| Area | 2021 | 2026 |

| --- | --- | --- |

| Python install | pyenv | uv |

| venv | python -m venv | uv venv (auto) |

| Dep management | pip + requirements.txt | uv + pyproject.toml + uv.lock |

| Lock | pip-tools / poetry | uv (built in) |

| Lint | flake8 (~tens of seconds) | ruff (~ms) |

| Format | black (~seconds) | ruff format (~ms) |

| Import sort | isort | ruff (integrated) |

| Type check | mypy / pyright | ty (alpha) / pyright / mypy |

| DataFrame | Pandas | Polars / Pandas 3.0 |

| Validation | dataclasses + manual | Pydantic v2 |

| Web | Flask/Django/FastAPI | FastAPI/Litestar/Robyn/Django 5 |

| Concurrency | asyncio / multiprocessing | free-threaded (3.13+) + asyncio |

**One-line summary**: a wave of Rust-rewritten tools replaced half of Python's tool chain, and Python itself started shedding the GIL.

2. Python 3.13 (Oct 2024) — free-threaded preview, JIT preview

Python 3.13 shipped on October 7, 2024. On the surface a routine minor release, but two things were **firsts**.

PEP 703 — free-threaded (no-GIL) build

For a long time, the consensus was that GIL removal was "theoretically possible but breaks compatibility and single-thread performance." PEP 703 (Sam Gross, Meta) broke that consensus. Key ideas.

- **biased reference counting** — the thread that owns an object mutates the refcount without a lock; other threads take a lock.

- **deferred reference counting** — some immortal objects (`None`, small ints) skip refcounting entirely.

- **per-object locking** — small locks attached to mutable containers like dict and list.

- **stop-the-world GC** — all threads pause briefly during GC.

The build is **opt-in**. The same 3.13 source produces two builds.

Standard build (with GIL)

./configure && make

Free-threaded build (no GIL)

./configure --disable-gil && make

Interpreter is python3.13t (t = threaded)

With uv:

uv python install 3.13 # standard

uv python install 3.13t # free-threaded

uv python install 3.13+freethreaded # explicit form

3.13's free-threaded build is **preview**. That means:

- The ABI is separate. C extensions need a separate build (the `Py_GIL_DISABLED` macro).

- Single-threaded performance is about 10–20% slower.

- Some stdlib and many C extensions are not yet ready.

PEP 744 — Copy-and-Patch JIT (experimental)

Another big change in 3.13. A **copy-and-patch JIT layered on the Tier 2 interpreter**. At build time it uses LLVM to pre-generate "stencils" — small machine code fragments — then patches them at runtime to produce native code.

./configure --enable-experimental-jit && make

In 3.13 the speedup is small (0–5%). But it is the foundation for serious optimizations in 3.14 and 3.15.

Other notable 3.13 changes

- **New REPL** — multi-line editing, color, exit on Ctrl+D.

- **Improved tracebacks** — color, more precise location markers.

- **iOS Tier 3, Android Tier 3** — officially supported platforms, the foundation for BeeWare/Briefcase.

- **Redesigned locals API** — accurate variable modification from debuggers.

- **typing.TypeIs** — more precise narrowing than TypeGuard.

- **Deprecations** — some argparse APIs, `pkgutil.find_loader`, etc.

3. Python 3.14 (Oct 2025) — free-threaded stable

Python 3.14 shipped October 7, 2025. **The maturation of what 3.13 started**.

Free-threaded promoted to stable

The "experimental" tag on the free-threaded build in 3.13 became an **officially supported option** in 3.14. The implications are large.

- Core packages like numpy, scipy, pandas, polars, pillow, lxml, cryptography ship free-threaded wheels to PyPI.

- `pip install` reads the interpreter type and pulls the right wheel.

- The single-threaded performance penalty narrows to 3–5% (near zero when combined with the JIT).

Deferred imports (PEP 791)

Through 3.13 — import is immediate

3.14 — deferred imports

from __future__ import deferred_imports

It is a big deal for CLI tools and cold-start-sensitive environments (Lambda, serverless). Part of why uv and Ruff feel fast is that they emulate this pattern in Rust.

Template strings — t-strings

f-strings evaluate immediately

name = "world"

greeting = f"Hello, {name}!" # "Hello, world!" right away

t-strings are lazy templates

template = t"Hello, {name}!" # Template object, not evaluated

Later you can render, escape, or run i18n on it

html = template.render(escape=html_escape)

Useful for SQL-injection / XSS protection, i18n, and structured logging. As of May 2026 adoption is still early.

Other notable 3.14 changes

- **JIT improvements** — 10–15% on some benchmarks.

- **PEP 768** — external debuggers can attach safely.

- **PEP 765** — warns on return/break/continue inside finally.

- **Subinterpreter API** — added to the stdlib via PEP 734.

- **typing.evaluate_forward_ref** — an API for evaluating forward references.

4. What PEP 703 actually changes — life without the GIL

What does losing the GIL really change? In short.

1) CPU-bound multithreading actually works

Pre-2024 — meaningless because of the GIL

from concurrent.futures import ThreadPoolExecutor

def cpu_heavy(n):

s = 0

for i in range(n):

s += i * i

return s

More threads, still one core

with ThreadPoolExecutor(max_workers=8) as pool:

list(pool.map(cpu_heavy, [10_000_000] * 8))

On the free-threaded build, eight threads actually spread across eight cores. Many workloads that needed multiprocessing can use a ThreadPool instead (with shared memory and no IPC overhead).

2) C extension authors take on more responsibility

The GIL enforced a single-threaded assumption. Now every C extension is responsible for its own thread safety.

- If you have global mutable state, you need a lock.

- `PyObject` manipulation is safe, but your own C data structures must be protected.

- The `Py_GIL_DISABLED` macro lets you branch at build time.

Big packages like numpy and scipy reached free-threaded readiness over one to two years. Smaller C extensions still need time.

3) The relationship with asyncio

asyncio is a single-threaded event loop — a different axis of concurrency from GIL removal. The two compose more nicely now.

- I/O via asyncio coroutines.

- CPU-bound parts go to `loop.run_in_executor(ThreadPoolExecutor(), ...)` for actual parallelism.

4) The single-thread performance penalty

Mechanisms like biased refcounting add some unavoidable overhead. From ~15% in 3.13 down to ~3–5% in 3.14, but not zero. For workloads that don't scale N times with threading, the standard build can still win.

5) Risk of ecosystem split

Having two ABIs under one Python 3.14 doubles the burden for package maintainers. A small library may only support one side, and that confuses users. How this settles in 2027–2028 is the question.

5. uv (Astral) — one tool to replace pip / poetry / pipenv

uv is Astral's Rust-based, single-binary package manager, announced February 2024. Same company as Ruff. The launch slogan was "An extremely fast Python package installer and resolver." Accurate.

What it replaces

| Old tool | What uv replaces |

| --- | --- |

| pip | install / uninstall |

| pip-tools | requirements compile / lock |

| pipx | global CLI install |

| poetry | project + dep management |

| pipenv | dependencies + venv |

| pyenv | Python interpreter install / management |

| virtualenv | venv creation |

| twine | build/publish (uv build, uv publish) |

Put differently: **nearly every layer of Python packaging in one binary**.

Install and basic use

Install (macOS/Linux)

curl -LsSf https://astral.sh/uv/install.sh | sh

New project

uv init my-app

cd my-app

pyproject.toml, .python-version, README.md created

Install a Python interpreter

uv python install 3.14

Add packages

uv add fastapi pydantic 'polars[all]'

uv add --dev pytest ruff

Sync (venv matches lock exactly)

uv sync

Run

uv run python -m my_app

uv run pytest

uv run ruff check

Why it is fast

- **Rust + async I/O** — dependency resolution in parallel.

- **Global cache + hard links** — same wheel shared across projects, disk usage drops.

- **PubGrub solver** — deterministic and fast.

- **Wheel-only preference** — avoids sdist builds when possible.

- **HTTP/2 + zstd**.

A measurement on my machine (late 2025, a typical FastAPI project, ~80 deps).

| Operation | pip | poetry | uv |

| --- | --- | --- | --- |

| Cold install | 48s | 62s | 2.1s |

| Warm install | 12s | 18s | 0.4s |

| Generate lock | n/a | 24s | 0.9s |

Once you try it, going back is hard.

pyproject.toml and 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` is a lockfile with exact hashes and markers. Commit it so the team shares it. `uv sync` matches the venv to the lock precisely.

Python interpreter management

uv python list # available versions

uv python install 3.13 3.14 3.14t # install several

uv python pin 3.14 # writes .python-version

Does what pyenv used to. Difference: uv downloads pre-built interpreters directly, so it is fast and needs no compile-time deps.

Global CLI tools

uv tool install ruff # like pipx

uv tool install httpie

uv tool run pip-audit # one-off run

uvx pip-audit # alias for uv tool run

Standardization in 2026

- pip is still #1 by PyPI download count, but uv adoption in CI is exploding.

- poetry still has a large user base, but new projects lean uv.

- Astral is one of the PSF's corporate sponsors, with active collaboration with PSF / PyPA.

6. Ruff (Astral) — the Rust tool that absorbed flake8 / black / isort

Ruff is Astral's first product (first release 2022, explosive growth 2024–2025). In one sentence: **"10–100x faster than flake8, with black/isort/pyupgrade folded in, as a single Rust binary."**

What it replaces

| Old tool | Ruff equivalent |

| --- | --- |

| flake8 | `ruff check` |

| pycodestyle | `ruff check` (E rules) |

| pyflakes | `ruff check` (F rules) |

| isort | `ruff check --select I` or `ruff format` |

| black | `ruff format` |

| pyupgrade | `ruff check --select UP` |

| autoflake | `ruff check --fix --select F401` |

| bandit (partial) | `ruff check --select S` |

| flake8-bugbear | `ruff check --select B` |

| flake8-comprehensions | `ruff check --select C4` |

| pydocstyle | `ruff check --select D` |

Hundreds of rules live in one binary, opt-in via config.

Basic use

uv add --dev ruff

uv run ruff check . # lint

uv run ruff check --fix . # auto-fix

uv run ruff format . # format (black compatible)

uv run ruff format --check . # verify format in CI

pyproject.toml config

[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 (the formatter handles it)

[tool.ruff.lint.per-file-ignores]

"tests/*" = ["S101"] # assert in tests

[tool.ruff.format]

quote-style = "single"

Why it is fast

- **One Rust AST pass** — multiple tools no longer reparse files independently.

- **Parallel** — per-file and per-rule parallelism.

- **Incremental** — only re-checks changed files.

- **Memory efficient** — much less likely to OOM than black on huge codebases.

A real benchmark on the Django codebase (~3500 files).

| Tool | Time |

| --- | --- |

| flake8 | 12.3s |

| black --check | 8.1s |

| isort --check | 4.5s |

| pyupgrade | 6.2s |

| **Sum (serial)** | **31.1s** |

| **ruff check + ruff format --check** | **0.4s** |

Tens of times difference. That gap shows up as CI cost and developer feel.

Editor integration

- VS Code — official Ruff extension (Astral maintained). LSP based.

- PyCharm / IntelliJ — official Ruff plugin.

- Neovim — ruff-lsp (or Ruff's built-in LSP).

- Zed — integrated by default.

Formatter — black-compatible alpha

`ruff format` deliberately targets black's output (99%+ compatible). Differences are usually black bugs or intentional improvements (e.g. magic trailing comma handling). A black-using team can migrate losslessly.

7. ty (Astral) — a Rust-rewritten type checker (alpha)

ty is the type checker Astral unveiled in alpha in 2025. Aimed at mypy and pyright's territory. As of May 2026 it is still alpha, but some projects have started adopting it.

Why yet another type checker

The type checker market is already complex.

- **mypy** — the original. Reference implementation of PEP 484. Written in Python. Slow.

- **pyright** — Microsoft. TypeScript. Fast and accurate. Pylance's foundation in VS Code.

- **pyre** — Meta. OCaml. Used at Instagram.

- **pytype** — Google. Python. Strong on gradual typing.

ty's position.

- **Rust** — aiming at pyright-level speed or better.

- **Incremental** — like Ruff and uv, recheck only what changed.

- **MIT** — consistent with Astral's other tools.

- **LSP first-class** — editor integration is a priority.

- **Astral integration** — slots cleanly with uv and ruff.

Basic use

uv add --dev ty

Check a directory

uv run ty check src/

A single file

uv run ty check src/main.py

Watch mode

uv run ty check --watch src/

The reality in May 2026

ty is still alpha. Meaning:

- Some typing features (especially generics, TypeVar bounds) are not yet implemented.

- Error messages can be rougher than mypy or pyright.

- The pattern in production is pyright or mypy as the main checker, with ty as a fast first gate.

The performance is striking. A large codebase where mypy takes 5 minutes runs in ~5 seconds under ty. If it settles, it could change the game.

Recommended combination

- **Today (May 2026)**: main is pyright (strict) or mypy (gradual), with ty added to CI as a fast first gate.

- **2027 outlook**: when ty hits stable, it becomes plausible as the main.

8. Polars 1.0 (Aug 2024) — the alternative to Pandas

Polars is a Rust-based DataFrame library started by Ritchie Vink in 2020. 1.0 shipped in August 2024. It targets Pandas's single-threaded ceiling, column-wise inefficiencies, and memory blowups.

Core differences

- **Rust core** — compiled native code.

- **Apache Arrow** — column-oriented memory layout, zero-copy interop.

- **Lazy execution** — the query planner optimizes before executing.

- **Multi-threaded by default** — Rayon for automatic parallelism.

- **Predicate / projection pushdown** — SQL-optimizer-grade optimizations.

eager vs lazy

eager — Pandas style

df = pl.read_csv("data.csv")

result = df.filter(pl.col("age") > 30).group_by("city").agg(pl.col("salary").mean())

lazy — optimized, then run

lf = pl.scan_csv("data.csv") # not read yet

result = (

lf.filter(pl.col("age") > 30)

.group_by("city")

.agg(pl.col("salary").mean())

.collect() # executes here

)

In lazy mode the optimizer decides "how to apply the filter early" and "which columns to read," cutting disk I/O and memory significantly.

Performance vs Pandas

H2O.ai's DataFrame benchmark (group-by, join, 5 GB).

| Library | 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 |

The gap is biggest near join and memory limits.

When Polars, when Pandas

**Polars**:

- 100 MB or larger data.

- New projects.

- Multi-core utilization needed.

- You want to express things like a SQL query optimizer.

**Pandas**:

- Compatibility with existing notebooks and ecosystem (scikit-learn, statsmodels, some matplotlib paths).

- A new data scientist who needs "ten years of Stack Overflow answers."

- Small data (a few MB).

- Exploration where `.head()` in Jupyter is enough.

Interop with Pandas

df_pl = pl.from_pandas(df_pd)

df_pd = df_pl.to_pandas() # zero-copy with PyArrow

arr = df_pl.to_arrow() # Arrow Table

df_pl2 = pl.from_arrow(arr)

Arrow-based zero-copy interop keeps standardizing, so mixing the two libraries is low-friction.

9. Pandas 3.0 (May 2025) — the comeback

Pandas did not die. The May 2025 release of 3.0 is its biggest major update.

Big changes in 3.0

1. **Apache Arrow becomes the default backend** — the numpy backend is the deprecated path.

2. **Copy-on-Write by default** — better memory and safety simultaneously.

3. **PyArrow is now a hard dependency** — no longer optional.

4. **String dtype is default** — pyarrow string instead of Python object.

5. **Many inplace methods removed** — they conflict with CoW.

6. **Requires Python 3.10+**.

What Copy-on-Write means

df1 = pd.DataFrame({"a": [1, 2, 3]})

df2 = df1 # alias

df2.loc[0, "a"] = 999

2.x: df1 also sees 999 (SettingWithCopyWarning)

3.0: df1 stays unchanged (CoW branches)

The end of the long-suffering `SettingWithCopyWarning`. But code that relied on inplace behavior breaks. Read the migration guide.

Performance

Thanks to the Arrow backend, string handling, group-by, and some joins run 2–5x faster than 2.x. Not Polars-fast, but the gap is narrower.

10. Pydantic v2.10 — the de facto data validation standard

Pydantic was pure Python through v1; v2 (2023) rewrote the core in Rust. v2.10 (late 2025) is the stabilized point in the v2 line.

What it does

- Runtime data validation and serialization.

- Foundation for FastAPI, Litestar, BlackSheep.

- Default adapter for LangChain's BaseTool, OpenAI structured output, and other LLM tooling.

Basic example

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] = []

Validate + coerce

u = User.model_validate({

"id": "42", # str converts to int

"name": "Alice",

"email": "alice@example.com",

"created_at": "2026-05-16T10:00:00Z",

})

print(u.model_dump_json())

v2 performance

Thanks to the Rust core, 5–50x faster than v1 (depending on schema complexity). In frameworks like FastAPI, P99 latency improves visibly.

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()

Cleans up the 12-factor app config pattern.

Use in LLM tooling

OpenAI / Anthropic structured output and function calling take a Pydantic model as the schema and enforce it. LangChain, LlamaIndex, Pydantic AI, and friends use Pydantic as the default adapter.

from pydantic import BaseModel

from anthropic import Anthropic

class SearchQuery(BaseModel):

query: str

max_results: int = 10

The Anthropic SDK extracts the schema as a tool definition

client = Anthropic()

11. Web frameworks — FastAPI / Litestar / Robyn / Quart / Sanic / BlackSheep

The Python web framework market in 2026 is more pluralistic than it has ever been. Each has a distinct edge.

FastAPI

- Arrived 2018, ASGI-based.

- Pydantic + Starlette + auto OpenAPI.

- The de facto ASGI flagship.

- Gentle learning curve, biggest community.

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 (formerly Starlite)

- Started in 2022 as Starlite, rebranded to Litestar in 2023.

- Inspired by FastAPI but with bigger ambitions (controllers, layered DI, plugin system).

- DTO system, supports msgspec / Pydantic / attrs.

- Slightly faster than FastAPI under specific conditions.

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

- Appeared 2022, Rust core + Python API.

- Multi-threaded in a single process (Rust's tokio).

- Very fast (2–5x FastAPI throughput).

- Small ecosystem, chosen where performance is critical.

from robyn import Robyn

app = Robyn(__file__)

@app.get("/")

async def hello():

return "hello, world"

app.start(port=8080)

Quart

- Flask's async sibling.

- Nearly identical API, some shared maintenance with Pallets.

- Good when you want to reuse Flask code with async.

Sanic

- A veteran since 2016.

- Fast, blueprint pattern.

- When you want "just ASGI."

BlackSheep

- An ASGI framework influenced by .NET ASP.NET.

- DI container, OpenAPI, strong typing.

- A C core gives it good performance.

Selection guide

- **Starting / small team / ecosystem matters** → FastAPI

- **Enterprise / structured large app** → Litestar

- **Throughput is critical** → Robyn or BlackSheep

- **Reusing Flask code** → Quart

- **Simplicity** → Sanic

12. Django 5.x — the classic full-stack workhorse

Django has been the grown-up since 2005. Still the Python full-stack default in 2026.

Major Django 5.x changes

- **5.0** (Dec 2023) — DB-backed defaults, simplified form templates, GeneratedField.

- **5.1** (Aug 2024) — CSRF middleware reorganization, more queryset exposure in the ORM.

- **5.2** (Apr 2025) — partial async ORM queries, automatic model importing.

The core story is that **async support is maturing in stages**. Async in the ORM is partially stable in 5.2; the full picture is targeted for 6.0 (late 2026).

When Django

- You need an admin (Django Admin remains best in class).

- You need ORM, migrations, auth, forms, templates, and testing in one package.

- A large monolith is the right answer.

- You need a mature CMS like Wagtail or django-CMS.

When not

- A single small API — FastAPI/Litestar are lighter.

- Extreme concurrency / low latency — Django is still sync-first.

- Microservice-sized units — Django's batteries are overhead.

Django Ninja — same ORM, FastAPI-style 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()}

A good answer when you want Django's ORM / auth / admin with a FastAPI-style API on top.

13. Packaging — uv / Briefcase / Nuitka / PyInstaller

Tools differ by distribution form.

Library packaging — uv build / hatchling

uv build # create sdist + wheel

uv publish # upload to PyPI (replaces twine)

Internally calls a PEP 517 build backend like hatchling. setup.py is effectively over.

Single executable — PyInstaller / Nuitka

**PyInstaller**:

uv tool install pyinstaller

pyinstaller --onefile my_app.py

dist/my_app

Upside: works with almost any library. Downside: large binary, AV false positives, slow startup.

**Nuitka**:

uv add --dev nuitka

python -m nuitka --standalone --onefile my_app.py

Upside: compiles Python to actual C, so it is faster and smaller. Downside: slow build, weak on some dynamic imports.

Desktop / mobile — Briefcase (BeeWare)

Packages Python code as native iOS / Android / macOS / Windows apps.

uv tool install briefcase

briefcase new

briefcase create iOS

briefcase build iOS

briefcase run iOS

Combined with Python 3.13's iOS / Android Tier 3 support, running Python on mobile is a realistic scenario.

Others

- **shiv / zipapp** — simple zip-based distribution.

- **conda-pack** — package a whole conda environment.

- **Docker** — the most common distribution unit. The `python:3.14-slim` + uv combo is standard.

14. Cloud — Modal / Replicate / Pyodide

Modal

- Run a Python function on cloud GPU / CPU as-is.

- Infrastructure defined via decorators.

- The flagship "serverless GPU."

app = modal.App("ml-job")

@app.function(gpu="A100", timeout=600)

def train(epochs: int):

training code

return "done"

if __name__ == "__main__":

with app.run():

train.remote(epochs=10)

Replicate

- ML model hosting + API.

- Containerize models with Cog.

- Common for inference of open-source models like Stable Diffusion or LLMs.

Pyodide

- Compiles Python to WebAssembly to run in the browser.

- Underpins JupyterLite, Streamlit-in-browser, marimo's browser mode, and more.

- By 2026 nearly the entire scientific stack — numpy, pandas, scipy — works.

15. Python usage in Korea and Japan

Korea

- **Toss** — backend leans Kotlin, but Python is used for ML / data engineering and internal tooling. Python is listed in job requirements.

- **Kakao** — recommendation/search ML pipelines, ad tech data pipelines, KakaoTalk chatbots — broadly used.

- **Naver** — training and serving infrastructure for Clova / HyperCLOVA, search data pipelines, LINE's ML backend.

- **Coupang** — data science, recommender systems, price optimization with Python + PySpark.

- **Daangn (Karrot)** — ML recommendations, data pipelines, A/B testing.

Startup trend: FastAPI + Polars + uv is becoming the de facto standard. Data roles are nearly Python-only.

Japan

- **Mercari** — ML platform, search relevance, fraud detection in Python. Heavy investment in the internal ML platform Bakuraku and MLOps.

- **PFN (Preferred Networks)** — the company behind Chainer. After moving to PyTorch, still Japan's flagship for Python ML R&D.

- **LINE Yahoo** — ML / data pipelines for search, ads, messenger.

- **DeNA** — Python ML in games, healthcare, MaaS.

- **SmartNews** — recommendation systems.

Japan historically had heavy Ruby usage, but the move to Python in data / ML is strong.

16. Who picks what

Recommended stacks by situation.

Data analysis / science

- Python 3.13 (free-threaded still secondary).

- uv + Ruff.

- Polars (big data) / Pandas 3.0 (ecosystem).

- jupyter / marimo (covered separately).

- scikit-learn, statsmodels, plotly / altair.

ML / AI training workloads

- Python 3.13 (free-threaded or standard).

- uv + Ruff.

- PyTorch / JAX.

- transformers / vLLM / sglang.

- Modal (serverless GPU), or RunPod, or Replicate.

- mlflow / wandb.

Web backend (microservice)

- Python 3.13 or 3.14.

- uv + Ruff + ty (secondary).

- FastAPI or Litestar.

- Pydantic v2.

- SQLModel / SQLAlchemy 2.0 / Tortoise ORM.

- Uvicorn / Granian.

- Docker: python:3.14-slim.

Web backend (monolith + admin)

- Django 5.x.

- uv + Ruff.

- Django Ninja (when REST is needed).

- Celery / Django-Q.

- PostgreSQL.

CLI tool

- Python 3.14 (deferred imports for fast startup).

- uv + Ruff.

- Typer or Click.

- Rich / Textual (TUI).

- PyInstaller or Nuitka for distribution.

Desktop / mobile

- Python 3.13 / 3.14.

- Briefcase (mobile) / Toga (cross-platform UI).

- Nuitka (single executable).

Embedded

- MicroPython or CircuitPython (not CPython).

- However, ARM Linux (Raspberry Pi, etc.) runs regular CPython.

17. Migration checklist — moving an existing project to 2026 style

If you already have a Python project, how do you move it.

Step 1 — adopt uv (low risk)

If pyproject.toml already exists

uv lock # generate uv.lock

uv sync # create/sync venv

If you are on requirements.txt

uv add -r requirements.txt

Coexists with the old workflow. Gradually flip CI to `uv sync && uv run pytest`.

Step 2 — adopt Ruff (low risk)

uv add --dev ruff

Start with lint only; keep black for now and compare

uv run ruff check --select F,E .

As you settle in, expand rules and move format to ruff too

Step 3 — Pydantic v1 to v2 (medium risk)

API changes substantially. Use the converter.

uv tool install bump-pydantic

bump-pydantic src/

Step 4 — Pandas to Polars (optional, big project)

Rather than full migration, pick hot paths. Interop is smooth so it can be gradual.

Step 5 — upgrade to Python 3.13 / 3.14

uv python install 3.14

uv python pin 3.14

uv sync

uv run pytest

The free-threaded build is a separate decision. Check C extension compatibility.

Step 6 — type checker

If you have mypy, keep it as main and add ty as a fast CI gate.

18. Common pitfalls and best practices

- **Do not just `pip install -r requirements.txt` in a Dockerfile** — uv gives 10x faster builds.

- **Do not put `import pandas as pd` at module top in CLIs** — cold start explodes. Lazy-import inside functions, or use 3.14 deferred imports.

- **Do not use the free-threaded build for all workloads** — for I/O-heavy work, the standard build can be faster.

- **Lean on lazy mode when adopting Polars** — eager-only captures only about half of the wins over Pandas.

- **Do not rebuild Pydantic models on every call** — schema compilation has cost. Define at module level.

- **Do not call sync libraries from inside `asyncio.run()`** — blocks the loop. Use `run_in_executor`.

- **Do not blindly apply Ruff's `--fix`** — some rules change meaning. Review the diff.

- **Do not gitignore uv.lock** — it is the heart of team reproducibility.

- **Do not run two type checkers as main at the same time** — conflicting messages. One main + one CI gate.

19. The future — 2027–2028 outlook

- **Free-threaded as default** — likely the standard build becomes free-threaded around 3.16 or 3.17, since maintaining two builds is expensive.

- **Real JIT wins** — 10–30% in 3.15–3.16 is plausible.

- **ty hits stable** — late 2026 to mid-2027.

- **Polars's chase accelerates** — the gap with Pandas grows, or Pandas absorbs Polars-style patterns.

- **An Astral IDE or Python distribution** — plausible. A unified ruff/uv/ty experience.

- **Pyodide goes mainstream** — browser-based data analysis and visualization becomes the SaaS standard.

- **Mobile Python** — Briefcase + Python 3.14 iOS/Android stable makes small native apps realistic.

20. Wrap-up — a new Python forged by two inflection points

Python in 2026 sits at the intersection of two big events.

1. **The language itself started shedding the GIL** (PEP 703, 3.13 preview to 3.14 stable). The biggest runtime change in 30 years. CPU-bound threading actually works, and the combination with asyncio gets clean. But the C extension ecosystem will need another two to three years to fully adapt.

2. **Astral rewrote half of the tool chain in Rust** (uv, Ruff, ty). pip / poetry / flake8 / black / isort / mypy are converging on two or three tools from a single company. With 10–100x speedups, CI cost and developer feel both improve simultaneously.

Add Pydantic v2's Rust core, Polars's Apache Arrow, the ASGI ecosystem of FastAPI / Litestar / Robyn pluralizing, Pandas 3.0 absorbing an Arrow backend, and Django 5.x's gradual async maturation — every layer is moving at once.

If you have seen Python code from five years ago, a modern 2026 Python project looks almost the same on the outside, but the tooling, runtime, and data-handling beneath it have nearly all changed. The good news about migration is you do not have to do it all at once. Adopt uv, then Ruff, then Pydantic v2, then Polars hot paths, then Python 3.14, then free-threaded (only when you need it). One step at a time.

Python is over 30 years old, and yet it is changing faster now than at almost any other point. A change worth keeping up with.

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/

현재 단락 (1/575)

Python was born in 1991. It turns 35 in 2026. Across 1.x to 2.x to 3.x it became the flagship dynami...

작성 글자: 0원문 글자: 30,172작성 단락: 0/575