"string.templatelib" --- テンプレート文字列リテラルのサポート
*************************************************************

**ソースコード:** Lib/string/templatelib.py

======================================================================

参考:

  * フォーマット済み文字列リテラル

  * テンプレート文字列リテラル(t-string)の構文

  * **PEP 750**


テンプレート文字列
==================

Added in version 3.14.

テンプレート文字列は、文字列処理をカスタマイズするための仕組みです。
Python の f-strings と同じ柔軟性を持ちますが、静的な部分と波括弧で囲ん
だ補間部分に、それらが結合される *前に* アクセスできる "Template" イン
スタンスを返します。

t-stringを書くには、このようにプレフィックスとして "'f'" の代わりに
"'t'" を使用します:

   >>> pi = 3.14
   >>> t't-strings are new in Python {pi!s}!'
   Template(
      strings=('t-strings are new in Python ', '!'),
      interpolations=(Interpolation(3.14, 'pi', 's', ''),)
   )


型
==

class string.templatelib.Template

   "Template" クラスはテンプレート文字列の内容を表します。 イミュータ
   ブルであり、テンプレートの属性には再代入できません。

   "Template" インスタンスを作成する最も一般的な方法は、テンプレート文
   字列リテラルの構文 を使うことです。 この構文は、"f" の代わりに "t"
   を前に付ける点を除いて、f 文字列 と同じです。

   >>> cheese = 'Red Leicester'
   >>> template = t"We're fresh out of {cheese}, sir."
   >>> type(template)
   <class 'string.templatelib.Template'>

   テンプレートは、リテラル部分の "strings" と動的な部分の
   "interpolations" のシーケンスとして格納されます。 "values" 属性は補
   間される値を保持します。

   >>> cheese = 'Camembert'
   >>> template = t'Ah! We do have {cheese}.'
   >>> template.strings
   ('Ah! We do have ', '.')
   >>> template.interpolations
   (Interpolation('Camembert', ...),)
   >>> template.values
   ('Camembert',)

   "strings" タプルは "interpolations" と "values" より要素が 1 つ多く
   、補間部分は文字列の間に入ります。 タプルの要素の位置をそろえて並べ
   ると分かりやすくなります。

      template.strings:  ('Ah! We do have ',              '.')
      template.values:   (                   'Camembert',    )

   -[ 属性 ]-

   strings: tuple[str, ...]

      テンプレート内の静的な文字列の "tuple"。

      >>> cheese = 'Camembert'
      >>> template = t'Ah! We do have {cheese}.'
      >>> template.strings
      ('Ah! We do have ', '.')

      タプルには空文字列も *含まれます*。

      >>> response = 'We do have '
      >>> cheese = 'Camembert'
      >>> template = t'Ah! {response}{cheese}.'
      >>> template.strings
      ('Ah! ', '', '.')

      "strings" タプルは空になることはなく、"interpolations" タプルや
      "values" タプルより常に文字列が 1 つ多く含まれます。

      >>> t''.strings
      ('',)
      >>> t''.values
      ()
      >>> t'{'cheese'}'.strings
      ('', '')
      >>> t'{'cheese'}'.values
      ('cheese',)

   interpolations: tuple[Interpolation, ...]

      テンプレート内の補間部分の "tuple"。

      >>> cheese = 'Camembert'
      >>> template = t'Ah! We do have {cheese}.'
      >>> template.interpolations
      (Interpolation('Camembert', 'cheese', None, ''),)

      "interpolations" タプルは空の場合もあり、常に "strings" タプルよ
      り値が 1 つ少なくなります。

      >>> t'Red Leicester'.interpolations
      ()

   values: tuple[object, ...]

      テンプレート内で補間されるすべての値のタプル。

      >>> cheese = 'Camembert'
      >>> template = t'Ah! We do have {cheese}.'
      >>> template.values
      ('Camembert',)

      "values" タプルの長さは、常に "interpolations" タプルと同じです
      。 常に "tuple(i.value for i in template.interpolations)" と等価
      です。

   -[ メソッド ]-

   __new__(*args: str | Interpolation)

      "Template" はリテラル構文で作成するのが一般的ですが、コンストラ
      クタを使って直接作成することもできます。

      >>> from string.templatelib import Interpolation, Template
      >>> cheese = 'Camembert'
      >>> template = Template(
      ...     'Ah! We do have ', Interpolation(cheese, 'cheese'), '.'
      ... )
      >>> list(template)
      ['Ah! We do have ', Interpolation('Camembert', 'cheese', None, ''), '.']

      複数の文字列を続けて渡すと、"strings" 属性内の 1 つの値に連結さ
      れます。 例えば次のコードは、最終的に文字列が 1 つだけになる
      "Template" を作成します。

      >>> from string.templatelib import Template
      >>> template = Template('Ah! We do have ', 'Camembert', '.')
      >>> template.strings
      ('Ah! We do have Camembert.',)

      複数の補間を続けて渡すと、それぞれ別の補間として扱われ、間に空文
      字列が挿入されます。 例えば次のコードは、"strings" 属性に空文字
      列のプレースホルダーを持つテンプレートを作成します。

      >>> from string.templatelib import Interpolation, Template
      >>> template = Template(
      ...     Interpolation('Camembert', 'cheese'),
      ...     Interpolation('.', 'punctuation'),
      ... )
      >>> template.strings
      ('', '', '')

   iter(template)

      テンプレートを反復処理し、空でない各文字列と "Interpolation" を
      正しい順序で yield します。

      >>> cheese = 'Camembert'
      >>> list(t'Ah! We do have {cheese}.')
      ['Ah! We do have ', Interpolation('Camembert', 'cheese', None, ''), '.']

      注意:

        反復処理には空文字列は **含まれません**。

        >>> response = 'We do have '
        >>> cheese = 'Camembert'
        >>> list(t'Ah! {response}{cheese}.')
        ['Ah! ',
         Interpolation('We do have ', 'response', None, ''),
         Interpolation('Camembert', 'cheese', None, ''),
         '.']

   template + other
   template += other

      このテンプレートを別のテンプレートと連結し、新しい "Template" イ
      ンスタンスを返します。

      >>> cheese = 'Camembert'
      >>> list(t'Ah! ' + t'We do have {cheese}.')
      ['Ah! We do have ', Interpolation('Camembert', 'cheese', None, ''), '.']

      "Template" と "str" の連結はサポート **していません**。 文字列を
      静的な文字列として扱うのか、補間として扱うのかが不明確なためです
      。 "Template" と文字列を連結するには、文字列を直接 "Template" で
      包んで静的な文字列として扱うか、"Interpolation" を使って動的な部
      分として扱ってください。

      >>> from string.templatelib import Interpolation, Template
      >>> template = t'Ah! '
      >>> # Treat 'We do have ' as a static string
      >>> template += Template('We do have ')
      >>> # Treat cheese as an interpolation
      >>> cheese = 'Camembert'
      >>> template += Template(Interpolation(cheese, 'cheese'))
      >>> list(template)
      ['Ah! We do have ', Interpolation('Camembert', 'cheese', None, '')]

class string.templatelib.Interpolation

   "Interpolation" 型は、テンプレート文字列内の式を表します。 イミュー
   タブルであり、補間オブジェクトの属性には再代入できません。

   補間オブジェクトはパターンマッチングをサポートしているため、match
   文 で属性に対してマッチングできます。

   >>> from string.templatelib import Interpolation
   >>> interpolation = t'{1. + 2.:.2f}'.interpolations[0]
   >>> interpolation
   Interpolation(3.0, '1. + 2.', None, '.2f')
   >>> match interpolation:
   ...     case Interpolation(value, expression, conversion, format_spec):
   ...         print(value, expression, conversion, format_spec, sep=' | ')
   ...
   3.0 | 1. + 2. | None | .2f

   補間オブジェクトは、その値の型を指定できる ジェネリック型 です。

   -[ 属性 ]-

   value: object

      補間する式の評価結果。

      >>> t'{1 + 2}'.interpolations[0].value
      3

   expression: str

      For interpolations created by t-string literals, "expression" is
      the expression text found inside the curly brackets ("{" & "}"),
      including any whitespace, excluding the curly brackets
      themselves, and ending before the first "!", ":", or "=" if any
      is present. For manually created interpolations, "expression" is
      the arbitrary string provided when constructing the
      interpolation instance.

      手動で作成する "Interpolation" インスタンスの "expression" フィ
      ールドには、有効な Python の式か空文字列を使うことを推奨します。
      ただし、実行時には強制されません。

      >>> t'{1 + 2}'.interpolations[0].expression
      '1 + 2'

   conversion: Literal['a', 'r', 's'] | None

      値に適用する変換、または "None"。

      "conversion" は、値に適用する省略可能な変換です。

      >>> t'{1 + 2!a}'.interpolations[0].conversion
      'a'

      注釈:

        f 文字列では変換が自動的に適用されますが、t 文字列では
        "Template" を *処理する* コードが、"conversion" の解釈方法と適
        用するかどうかを決めることが想定されています。 便利な機能とし
        て、"convert()" 関数で f 文字列の変換の動作を再現できます。

   format_spec: str

      値に適用する書式指定。

      "format_spec" は、値を表示する際の書式指定として使う、省略可能な
      任意の文字列です。

      >>> t'{1 + 2:.2f}'.interpolations[0].format_spec
      '.2f'

      注釈:

        f 文字列では "format()" プロトコルを通じて書式指定が自動的に適
        用されますが、t 文字列では補間を *処理する* コードが、書式指定
        の解釈方法と適用するかどうかを決めることが想定されています。
        そのため、補間の "format_spec" には、"format()" プロトコルに従
        わないものも含め、任意の文字列を指定できます。

   -[ メソッド ]-

   __new__(value: object, expression: str, conversion: Literal['a', 'r', 's'] | None = None, format_spec: str = '')

      構成要素から新しい "Interpolation" オブジェクトを作成します。

      パラメータ:
         * **value** -- そのスコープ内で補間する式を評価した結果。

         * **expression** -- 有効な Python の式のテキスト、または空文
           字列。

         * **conversion** -- 使用する 変換。 "None"、"'a'"、"'r'"、
           "'s'" のいずれかです。

         * **format_spec** -- 値を表示する際の 書式指定 として使う、省
           略可能な任意の文字列。


ヘルパー関数
============

string.templatelib.convert(obj, /, conversion)

   指定したオブジェクト *obj* に、フォーマット済み文字列リテラルの 変
   換 と同じ処理を適用します。 テンプレート文字列のカスタム処理で役立
   つことがよくあります。

   現在サポートされている変換フラグは次の 3 つです。

   * "'s'" は、"!s" と同様に値に対して "str()" を呼び出します。

   * "'r'" は、"!r" と同様に "repr()" を呼び出します。

   * "'a'" は、"!a" と同様に "ascii()" を呼び出します。

   変換フラグが "None" の場合、*obj* をそのまま返します。
