Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.3k
gh-132661: Document t-strings andtemplatelib
#135229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Changes from18 commits
5a8dbfa
09a1e9e
ec44c2b
d8904b6
550aa6d
a20e058
1f30739
d935dd6
1e47362
7b660be
00a535d
fcd74e6
a796f5d
21d337c
d043381
9a0a301
f2e5ca4
8484b81
56ef703
5a8cf1b
127ebc6
73e1222
530cb6d
eaec534
05b5beb
680189a
71ddbf4
1c0ed70
ecc86c3
64c6758
16a995d
7f376d7
9e87880
574c29c
6f0f95a
95df68f
e562c4e
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1304,6 +1304,11 @@ Glossary | ||||||
See also :term:`borrowed reference`. | ||||||
t-string | ||||||
String literals prefixed with ``'t'`` or ``'T'`` are commonly called | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I think it's better without the quotes, because youdon't quote the prefix, and we have code formatting to mark it as different: Suggested change
This applies to the f-string text too, which could be fixed here or left for a followup. | ||||||
"t-strings" which is short for | ||||||
:ref:`template string literals <t-strings>`. See also :pep:`750`. | ||||||
davepeck marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||||||
text encoding | ||||||
A string in Python is a sequence of Unicode code points (in range | ||||||
``U+0000``--``U+10FFFF``). To store or transfer a string, it needs to be | ||||||
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -1120,6 +1120,45 @@ iterations of the loop. | ||||||||||
.. versionadded:: 3.12 | ||||||||||
.. opcode:: BUILD_TEMPLATE | ||||||||||
Constructs a new :class:`~string.templatelib.Template` from a tuple | ||||||||||
of strings and a tuple of interpolations and pushes the resulting instance | ||||||||||
onto the stack:: | ||||||||||
interpolations = STACK.pop() | ||||||||||
strings = STACK.pop() | ||||||||||
STACK.append(_build_template(strings, interpolations)) | ||||||||||
.. versionadded:: 3.14 | ||||||||||
.. opcode:: BUILD_INTERPOLATION (format) | ||||||||||
Constructs a new :class:`~string.templatelib.Interpolation` from an | ||||||||||
expression and its source text and pushes the resulting instance onto the | ||||||||||
stack. | ||||||||||
If the low bit of ``format`` is set, it indicates that the interpolation | ||||||||||
contains a format specification. | ||||||||||
If ``format >> 2`` is non-zero, it indicates that the interpolation | ||||||||||
contains a conversion. The value of ``format >> 2`` is the conversion type | ||||||||||
(e.g. ``0`` for no conversion, ``1`` for ``!s``, ``2`` for ``!r``, and | ||||||||||
``3`` for ``!a``):: | ||||||||||
Comment on lines +1150 to +1151 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Avoid Latin abbreviations:https://devguide.python.org/documentation/style-guide/#use-simple-language Suggested change
| ||||||||||
if format & 1: | ||||||||||
format_spec = STACK.pop() | ||||||||||
else: | ||||||||||
format_spec = None | ||||||||||
conversion = format >> 2 | ||||||||||
expression = STACK.pop() | ||||||||||
value = STACK.pop() | ||||||||||
STACK.append(_build_interpolation(value, expression, conversion, format_spec)) | ||||||||||
.. versionadded:: 3.14 | ||||||||||
.. opcode:: BUILD_TUPLE (count) | ||||||||||
Creates a tuple consuming *count* items from the stack, and pushes the | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Link to this file fromhttps://cpython-previews--135229.org.readthedocs.build/en/135229/library/index.html |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,184 @@ | ||||||||||
:mod:`!string.templatelib` --- Templates and Interpolations for t-strings | ||||||||||
========================================================================= | ||||||||||
Comment on lines +1 to +2 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Use sentence case for headers: https://devguide.python.org/documentation/style-guide/#capitalization Suggested change
| ||||||||||
.. module:: string.templatelib | ||||||||||
:synopsis: Support for t-string literals. | ||||||||||
**Source code:** :source:`Lib/string/templatelib.py` | ||||||||||
-------------- | ||||||||||
.. seealso:: | ||||||||||
:ref:`Format strings <f-strings>` | ||||||||||
.. _templatelib-template: | ||||||||||
Template | ||||||||||
-------- | ||||||||||
The :class:`!Template` class describes the contents of a template string. | ||||||||||
The most common way to create a new :class:`!Template` instance is to use the t-string literal syntax. This syntax is identical to that of :ref:`f-strings`, except that the string is prefixed with a ``t`` instead of an ``f``. For example, the following code creates a :class:`Template` that can be used to format strings: | ||||||||||
>>> name = "World" | ||||||||||
>>> greeting = t"Hello {name}!" | ||||||||||
>>> type(greeting) | ||||||||||
<class 'string.templatelib.Template'> | ||||||||||
>>> print(list(greeting)) | ||||||||||
['Hello ', Interpolation('World', 'name', None, ''), '!'] | ||||||||||
It is also possible to create a :class:`!Template` directly, using its constructor. This takes an arbitrary collection of strings and :class:`Interpolation` instances: | ||||||||||
>>> from string.templatelib import Interpolation, Template | ||||||||||
>>> name = "World" | ||||||||||
>>> greeting = Template("Hello, ", Interpolation(name, "name"), "!") | ||||||||||
>>> print(list(greeting)) | ||||||||||
['Hello, ', Interpolation('World', 'name', None, ''), '!'] | ||||||||||
.. class:: Template(*args) | ||||||||||
Create a new :class:`!Template` object. | ||||||||||
:param args: A mix of strings and :class:`Interpolation` instances in any order. | ||||||||||
:type args: str | Interpolation | ||||||||||
If two or more consecutive strings are passed, they will be concatenated into a single value in the :attr:`~Template.strings` attribute. For example, the following code creates a :class:`Template` with a single final string: | ||||||||||
>>> from string.templatelib import Template | ||||||||||
>>> greeting = Template("Hello ", "World", "!") | ||||||||||
>>> print(greeting.strings) | ||||||||||
('Hello World!',) | ||||||||||
If two or more consecutive interpolations are passed, they will be treated as separate interpolations and an empty string will be inserted between them. For example, the following code creates a template with a single value in the :attr:`~Template.strings` attribute: | ||||||||||
>>> from string.templatelib import Interpolation, Template | ||||||||||
>>> greeting = Template(Interpolation("World", "name"), Interpolation("!", "punctuation")) | ||||||||||
>>> print(greeting.strings) | ||||||||||
('', '', '') | ||||||||||
.. attribute:: strings | ||||||||||
:type: tuple[str, ...] | ||||||||||
A :ref:`tuple <tut-tuples>` of the static strings in the template. | ||||||||||
>>> name = "World" | ||||||||||
>>> print(t"Hello {name}!".strings) | ||||||||||
('Hello ', '!') | ||||||||||
Empty strings *are* included in the tuple: | ||||||||||
>>> name = "World" | ||||||||||
>>> print(t"Hello {name}{name}!".strings) | ||||||||||
('Hello ', '', '!') | ||||||||||
.. attribute:: interpolations | ||||||||||
:type: tuple[Interpolation, ...] | ||||||||||
A tuple of the interpolations in the template. | ||||||||||
>>> name = "World" | ||||||||||
>>> print(t"Hello {name}!".interpolations) | ||||||||||
(Interpolation('World', 'name', None, ''),) | ||||||||||
.. attribute:: values | ||||||||||
:type: tuple[Any, ...] | ||||||||||
A tuple of all interpolated values in the template. | ||||||||||
>>> name = "World" | ||||||||||
>>> print(t"Hello {name}!".values) | ||||||||||
('World',) | ||||||||||
.. method:: __iter__() | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. For the dunders, consider showing what thecaller writes, rather than the implementor. See e.g.here. Suggested change
| ||||||||||
Iterate over the template, yielding each string and :class:`Interpolation` in order. | ||||||||||
>>> name = "World" | ||||||||||
>>> print(list(t"Hello {name}!")) | ||||||||||
['Hello ', Interpolation('World', 'name', None, ''), '!'] | ||||||||||
Empty strings are *not* included in the iteration: | ||||||||||
>>> name = "World" | ||||||||||
>>> print(list(t"Hello {name}{name}")) | ||||||||||
['Hello ', Interpolation('World', 'name', None, ''), Interpolation('World', 'name', None, '')] | ||||||||||
:returns: An iterable of all the parts in the template. | ||||||||||
:rtype: typing.Iterator[str | Interpolation] | ||||||||||
.. class:: Interpolation(*args) | ||||||||||
Create a new :class:`!Interpolation` object. | ||||||||||
:param value: The evaluated, in-scope result of the interpolation. | ||||||||||
:type value: object | ||||||||||
:param expression: The original *text* of the interpolation's Python :ref:`expressions <expressions>`. | ||||||||||
:type expression: str | ||||||||||
:param conversion: The optional :ref:`conversion <formatstrings>` to be used, one of r, s, and a,. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||||||
:type value: Literal["a", "r", "s"] | None | ||||||||||
:param format_spec: An optional, arbitrary string used as the :ref:`format specification <formatspec>` to present the value. | ||||||||||
The :class:`!Interpolation` type represents an expression inside a template string. It is shallow immutable -- its attributes cannot be reassigned. | ||||||||||
>>> name = "World" | ||||||||||
>>> template = t"Hello {name}" | ||||||||||
>>> template.interpolations[0].value | ||||||||||
'World' | ||||||||||
>>> template.interpolations[0].value = "Galaxy" | ||||||||||
Traceback (most recent call last): | ||||||||||
File "<input>", line 1, in <module> | ||||||||||
AttributeError: readonly attribute | ||||||||||
While f-strings and t-strings are largely similar in syntax and expectations, the :attr:`~Interpolation.conversion` and :attr:`~Interpolation.format_spec` behave differently. With f-strings, these are applied to the resulting value automatically. For example, in this ``format_spec``: | ||||||||||
>>> value = 42 | ||||||||||
>>> f"Value: {value:.2f}" | ||||||||||
'Value: 42.00' | ||||||||||
With a t-string :class:`!Interpolation`, the template function is expected to apply this to the value: | ||||||||||
>>> value = 42 | ||||||||||
>>> template = t"Value: {value:.2f}" | ||||||||||
>>> template.interpolations[0].value | ||||||||||
42 | ||||||||||
.. property:: __match_args__ | ||||||||||
:returns: A tuple of the attributes to use for structural pattern matching. | ||||||||||
:rtype: (Literal["value"], Literal["expression"], Literal["conversion"], Literal["format_spec"]) | ||||||||||
.. property:: value | ||||||||||
:returns: The evaluated value of the interpolation. | ||||||||||
:rtype: object | ||||||||||
.. property:: expression | ||||||||||
:returns: The original text of the interpolation's Python expression if the interpolation was created from a t-string literal | ||||||||||
:rtype: str | ||||||||||
The :attr:`~Interpolation.expression` is the original text of the interpolation's Python expression, if the interpolation was created from a t-string literal. Developers creating | ||||||||||
interpolations manually should either set this to an empty | ||||||||||
string or choose a suitable valid python expression. | ||||||||||
.. property:: conversion | ||||||||||
:returns: The conversion to apply to the value, one of "a", "r", or "s", or None. | ||||||||||
:rtype: Literal["a", "r", "s"] | None | ||||||||||
The :attr:`~Interpolation.conversion` is the optional conversion to apply to the value. This is one of "a", "r", or "s", or None if no conversion is specified. | ||||||||||
.. property:: format_spec | ||||||||||
:returns: The format specification to apply to the value. | ||||||||||
:rtype: str | ||||||||||
The :attr:`~Interpolation.format_spec` is an optional, arbitrary string used as the format specification to present the value. This is similar to the format specification used in :ref:`format strings <formatstrings>`, but it is not limited to a specific set of formats. |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -913,6 +913,44 @@ See also :pep:`498` for the proposal that added formatted string literals, | ||||||
and :meth:`str.format`, which uses a related format string mechanism. | ||||||
.. _t-strings: | ||||||
.. _template-string-literals: | ||||||
t-strings | ||||||
--------- | ||||||
.. versionadded:: 3.14 | ||||||
A :dfn:`template string literal` or :dfn:`t-string` is a string literal | ||||||
that is prefixed with ``'t'`` or ``'T'``. These strings follow the same | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||
syntax and evaluation rules as :ref:`formatted string literals <f-strings>`, with | ||||||
the following differences: | ||||||
- Rather than evaluating to a ``str`` object, t-strings evaluate to a | ||||||
:class:`~string.templatelib.Template` object from the | ||||||
:mod:`string.templatelib` module. | ||||||
- The :func:`format` protocol is not used. Instead, the format specifier and | ||||||
conversions (if any) are passed to a new :class:`~string.templatelib.Interpolation` | ||||||
object that is created for each evaluated expression. It is up to code that | ||||||
processes the resulting :class:`~string.templatelib.Template` object to | ||||||
decide how to handle format specifiers and conversions. | ||||||
- Format specifiers containing nested replacement fields are evaluated eagerly, | ||||||
davepeck marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||||||
prior to being passed to the :class:`~string.templatelib.Interpolation` object. | ||||||
- When the equal sign ``'='`` is provided in an interpolation expression, the | ||||||
resulting :class:`~string.templatelib.Template` object will have the expression | ||||||
text along with a ``'='`` character placed in its | ||||||
:attr:`~string.templatelib.Template.strings` attribute. The | ||||||
:attr:`~string.templatelib.Template.interpolations` attribute will also | ||||||
contain an ``Interpolation`` instance for the expression. By default, the | ||||||
:attr:`~string.templatelib.Interpolation.conversion` attribute will be set to | ||||||
``'r'`` (i.e. :func:`repr`), unless there is a conversion explicitly specified | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
| ||||||
(in which case it overrides the default) or a format specifier is provided (in | ||||||
which case, the ``conversion`` defaults to ``None``). | ||||||
.. _numbers: | ||||||
Numeric literals | ||||||
@@ -1044,7 +1082,7 @@ readability:: | ||||||
Either of these parts, but not both, can be empty. For example:: | ||||||
1. # (equivalent to 10.0) | ||||||
davepeck marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||||||
.001 # (equivalent to 0.001) | ||||||
Optionally, the integer and fraction may be followed by an *exponent*: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Please remove this file. |
Uh oh!
There was an error while loading.Please reload this page.