python / python/cpython

Consider making `Template` and `Interpolation` generic at runtime

Offen
#133,970 22 Kommentare 3 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

@sobolevn arbeitet bereits daran.

Seit 13.5.2025.

3.14 interpreter-core topic-typing triaged type-feature
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
35.9k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

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

Linked PRs
  • gh-133976
  • gh-134029

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.