Feature or enhancement
Template and Interpolation will once be supported by type-checkers. And it might be worth adding generics support for these types.
Example
from string.templatelib import Template, Interpolation from urllib.parse import quote_plus domain = 'example.com' query = 'python string formatting is too complex' template = t'https://{domain}?q={query}' def quote_url(interp: Interpolation[str]) -> str: return quote_plus(interp.value) def format_url(template: Template) -> str: parts = [] for part in template: match part: case str() as s: # regular string parts.append(s) case Interpolation(str(), expression='query') as interp: parts.append(quote_url(interp)) case Interpolation(value): parts.append(value) return ''.join(parts) print(format_url(template))
Here we can see that Interpolation[str] can be useful in users' code.
We can also benefit from generic Template, where we can make it generic based on exact TypeVarTuple. Demo:
from typing import Any, TypeVarTuple, Generic, Unpack Ts = TypeVarTuple('Ts', default=Unpack[tuple[Any, ...]]) class Template(Generic[*Ts]): def __new__(cls, *args: *Ts) -> Template[*Ts]: ... # type: ignore[empty-body] class Interpolation: ... reveal_type(Template('a', 'b', Interpolation(), 'd')) # Revealed type is "__main__.Template[Literal['a']?, Literal['b']?, __main__.Interpolation, Literal['d']?]"
https://mypy-play.net/?mypy=latest&python=3.13&gist=0dc13b3b926e1efb9783ab9b70d39ceb
This can potentially help type checkers to infer correct Template type.
Current state
Current typeshed definitions: https://github.com/python/typeshed/blob/main/stdlib/string/templatelib.pyi
Here's how Template is defined:
@final class Template: # TODO: consider making `Template` generic on `TypeVarTuple` strings: tuple[str, ...] interpolations: tuple[Interpolation, ...] def __new__(cls, *args: str | Interpolation) -> Template: ... def __iter__(self) -> Iterator[str | Interpolation]: ... def __add__(self, other: Template | str) -> Template: ... @property def values(self) -> tuple[Any, ...]: ... # Tuple of interpolation values, which can have any type
Ideally, it should be generic on TypeVarTuple
Here's how Interpolation is defined:
@final class Interpolation: value: Any # TODO: consider making `Interpolation` generic in runtime expression: str conversion: Literal["a", "r", "s"] | None format_spec: str __match_args__ = ("value", "expression", "conversion", "format_spec") def __new__( cls, value: Any, expression: str, conversion: Literal["a", "r", "s"] | None = None, format_spec: str = "" ) -> Interpolation: ...
Ideally, it should be generic on value. Interpolation[str] means that value is str and Interpolation[tuple[int, int]] means that Interpolation has a value for type tuple[int, int]
Proposal
From runtime's part with only need to add Py_GenericAlias, that's it.
Is it too late for feature freeze? This is a minor detail, so I hope it is not :)
I have a PR ready.
CC @srittau @JelleZijlstra @lysnikolaou