Python 3.14のt-stringはstrではない|Templateの結合エラーと文字列が必要なときの対処

Python3.14のt-stringはstrでなくTemplateを作る。普通の文字列はf-string、構造を使う処理はTemplate対応processorを選ぶ。補間式は作成時に評価され、Templateとstrは結合できない。

Python 3.14のt-stringは通常のstrではなく、string.templatelib.Templateを生成します。最終的な表示文字列だけが必要ならf-stringを使い、静的部分と補間値を分けた構造を後処理したいならt-stringをTemplate対応のprocessorへ渡してください。Templateとstrの+結合はできず、str(template)も補間済み文字列を得る標準的な方法ではありません。

t-stringはPython 3.14で導入済みの構文です。string.templatelib公式資料では、t-stringが静的なstringsと動的なinterpolationsを保持するTemplateを返すと説明されています。

以下は2026年10月4日時点のPython 3.14公式資料とPEP 750に基づきます。

目次

f-stringとt-stringの違い

構文結果の型主な用途
f'Hello {name}'strその場で通常の文字列を作る
t'Hello {name}'Template静的文字列と補間情報をprocessorで後処理する

Python言語リファレンスでは、tまたはT接頭辞を使い、基本構文はf-stringと同じとされています。ただし、返り値と処理方法は異なります。

型と構造、結合エラーを確認する最小例

from string.templatelib import Template


name = 'Ada'
template = t'Hello {name}!'

print(isinstance(template, Template))
print(isinstance(template, str))
print(template.strings)
print(template.values)

try:
    template + ' Welcome'
except TypeError as exc:
    print(type(exc).__name__)

combined = template + t' Welcome'
print(isinstance(combined, Template))

message = f'Hello {name}! Welcome'
print(message)

stringsには静的部分、valuesには作成時に評価された値が入ります。Template + strが禁止されるのは、その文字列を静的本文と動的値のどちらにするか曖昧だからです。Template同士は結合できます。

t-string用途別フロー。普通の文字列ならf-string、構造ならTemplate対応processorを使う。Template同士は結合可、TemplateとstrはTypeError。式評価は作成時で、SQLやHTMLの安全性は自動付与されない。
型、結合、評価時点を確認し、安全性は用途ごとに設計します。

既存のstrを結合するときは役割を明示する

既存文字列を動的な値として保持したい場合は、t-stringの補間に入れます。

from string.templatelib import Template


name = 'Ada'
template = t'Hello {name}!'

prefix = 'Notice: '
combined = t'{prefix}' + template

print(isinstance(combined, Template))
print(combined.values)

一方、信頼済みの固定文としてTemplateへ加えたい場合はTemplate(prefix)のように構築できます。どちらを選ぶかは、processorが静的部分と動的値をどう扱うかで決めます。

str(template)で補間結果にならない理由

PEP 750のTemplate.__str__の説明では、Templateに専用の__str__()を設けていません。processorは文字列だけでなく別の型を返す可能性があり、Templateから文字列への唯一の正解を標準側で決められないためです。

したがって、普通の文字列が欲しいだけなら最初からf-stringを使います。構造を保持する理由があるなら、HTML、ログ、コマンド、独自DSLなど、その用途専用のprocessorへ渡します。t-string自体が自動でHTMLをエスケープしたり、SQLインジェクションを防いだりするわけではありません。

平文へ変換する小さなprocessor例

次は、通常のPython変換フラグとformat specificationを平文へ適用する最小例です。あらゆるTemplateやHTML・SQL向けの安全処理ではありません。

from string.templatelib import Template, convert


def render_plain(template: Template) -> str:
    parts = []

    for part in template:
        if isinstance(part, str):
            parts.append(part)
            continue

        value = convert(part.value, part.conversion)
        parts.append(format(value, part.format_spec))

    return ''.join(parts)


name = 'Ada'
value = 3.14
template = t'Hello {name!r}, value={value:.1f}'

result = render_plain(template)
expected = f'Hello {name!r}, value={value:.1f}'

assert result == expected
print(result)

Templateを反復すると、空でない静的文字列とInterpolationが順番に得られます。このprocessorは、後者のvalueに変換を適用してからformat()を呼ぶ設計です。t-string自身は変換フラグや書式指定を自動では適用しません。

convert()の公式仕様では、!s、!r、!a相当の変換を補助し、変換指定がNoneなら値をそのまま返します。Template全体を自動レンダリングする関数ではありません。また、t-stringのformat_specはprocessorが解釈する情報であり、すべてがPythonのformat()規則に従うとは限りません。この例はPythonの書式指定を使う平文処理に限り、未対応の指定ならformat()が例外を出すことがあります。

補間式は遅延評価ではない

PEP 750の式評価の仕様では、補間式はt-stringを作成した時点のスコープで左から右へ評価されます。関数呼び出しもprocessorへ渡す前に実行されます。Templateが保持するのは未実行の式ではなく、評価済みの値と式のテキストなどです。

よくある質問

Python 3.13でt-stringをtry/exceptすれば使えますか?

できません。3.13以前では構文解析の段階でエラーになるため、通常の実行時例外として回避する設計にはできません。

string.Templateのsubstitute()を使えますか?

以前からある$name形式のstring.Templateと、string.templatelib.Templateは別の型・APIです。substitute()やsafe_substitute()をt-stringへ使うことはできません。

まとめ

t-stringのエラーを直す第一歩は、必要なのが完成済みのstrか、後処理できるTemplateかを決めることです。前者はf-string、後者はTemplate同士の結合と用途専用processorを使い分けてください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次