1"""The common base for anything `select()` can pull back as a column.
2
3`Field[T]` carries a real value type and subclasses `Selectable[T]`, so a
4field contributes its `T` to the selected row. Expressions subclass
5`Selectable[Any]` — they stay un-generic for now and contribute `Any`, which is
6honest (an aggregate's output type isn't tracked yet) and can be tightened later
7without touching `select()`.
8
9The overload ladder on `QuerySet.select()` binds each argument's `T` through
10this shared base: a checker solves `T0` from `Field[str] <: Selectable[T0]` by
11specializing the base class, so the marker needs no members of its own. The
12ladder's per-column types are asserted in `tests/typing/select_rows.py`, which
13is what would catch a checker that can't.
14"""
15
16from __future__ import annotations
17
18
19class Selectable[T]:
20 pass