docs/library: Document string.templatelib module.
Some checks are pending
JavaScript code lint and formatting with Biome / eslint (push) Waiting to run
Check code formatting / code-formatting (push) Waiting to run
Check spelling with codespell / codespell (push) Waiting to run
Build docs / build (push) Waiting to run
Check examples / embedding (push) Waiting to run
Package mpremote / build (push) Waiting to run
.mpy file format and tools / test (push) Waiting to run
Build ports metadata / build (push) Waiting to run
alif port / build_alif (alif_ae3_build) (push) Waiting to run
cc3200 port / build (push) Waiting to run
esp32 port / build_idf (esp32_build_c2_c5_c6) (push) Waiting to run
esp32 port / build_idf (esp32_build_cmod_spiram_s2) (push) Waiting to run
esp32 port / build_idf (esp32_build_p4) (push) Waiting to run
esp32 port / build_idf (esp32_build_s3_c3) (push) Waiting to run
esp8266 port / build (push) Waiting to run
mimxrt port / build (push) Waiting to run
nrf port / build (push) Waiting to run
powerpc port / build (push) Waiting to run
qemu port / build_and_test_arm (bigendian) (push) Waiting to run
qemu port / build_and_test_arm (sabrelite) (push) Waiting to run
qemu port / build_and_test_arm (thumb_hardfp) (push) Waiting to run
qemu port / build_and_test_arm (thumb_softfp) (push) Waiting to run
qemu port / build_and_test_rv32 (push) Waiting to run
qemu port / build_and_test_rv64 (push) Waiting to run
renesas-ra port / build_renesas_ra_board (push) Waiting to run
rp2 port / build (push) Waiting to run
samd port / build (push) Waiting to run
stm32 port / build_stm32 (stm32_misc_build) (push) Waiting to run
stm32 port / build_stm32 (stm32_nucleo_build) (push) Waiting to run
stm32 port / build_stm32 (stm32_pyb_build) (push) Waiting to run
unix port / minimal (push) Waiting to run
unix port / reproducible (push) Waiting to run
unix port / standard (push) Waiting to run
unix port / standard_v2 (push) Waiting to run
unix port / coverage (push) Waiting to run
unix port / coverage_32bit (push) Waiting to run
unix port / nanbox (push) Waiting to run
unix port / longlong (push) Waiting to run
unix port / float (push) Waiting to run
unix port / gil_enabled (push) Waiting to run
unix port / stackless_clang (push) Waiting to run
unix port / float_clang (push) Waiting to run
unix port / settrace_stackless (push) Waiting to run
unix port / repr_b (push) Waiting to run
unix port / macos (push) Waiting to run
unix port / qemu_mips (push) Waiting to run
unix port / qemu_arm (push) Waiting to run
unix port / qemu_riscv64 (push) Waiting to run
unix port / sanitize_address (push) Waiting to run
unix port / sanitize_undefined (push) Waiting to run
webassembly port / build (push) Waiting to run
windows port / build-vs (Debug, true, x64, dev, 2017, [15, 16)) (push) Waiting to run
windows port / build-vs (Debug, true, x86, dev, 2017, [15, 16)) (push) Waiting to run
windows port / build-vs (Debug, x64, dev, 2022, [17, 18)) (push) Waiting to run
windows port / build-vs (Debug, x86, dev, 2022, [17, 18)) (push) Waiting to run
windows port / build-vs (Release, true, x64, dev, 2017, [15, 16)) (push) Waiting to run
windows port / build-vs (Release, true, x64, dev, 2019, [16, 17)) (push) Waiting to run
windows port / build-vs (Release, true, x64, standard, 2017, [15, 16)) (push) Waiting to run
windows port / build-vs (Release, true, x64, standard, 2019, [16, 17)) (push) Waiting to run
windows port / build-vs (Release, true, x86, dev, 2017, [15, 16)) (push) Waiting to run
windows port / build-vs (Release, true, x86, dev, 2019, [16, 17)) (push) Waiting to run
windows port / build-vs (Release, true, x86, standard, 2017, [15, 16)) (push) Waiting to run
windows port / build-vs (Release, true, x86, standard, 2019, [16, 17)) (push) Waiting to run
windows port / build-vs (Release, x64, dev, 2022, [17, 18)) (push) Waiting to run
windows port / build-vs (Release, x64, standard, 2022, [17, 18)) (push) Waiting to run
windows port / build-vs (Release, x86, dev, 2022, [17, 18)) (push) Waiting to run
windows port / build-vs (Release, x86, standard, 2022, [17, 18)) (push) Waiting to run
windows port / build-mingw (i686, mingw32, dev) (push) Waiting to run
windows port / build-mingw (i686, mingw32, standard) (push) Waiting to run
windows port / build-mingw (x86_64, mingw64, dev) (push) Waiting to run
windows port / build-mingw (x86_64, mingw64, standard) (push) Waiting to run
windows port / cross-build-on-linux (push) Waiting to run
zephyr port / build (push) Waiting to run
Python code lint and formatting with ruff / ruff (push) Waiting to run

This documents all of the available functionality in the new
`string.templatelib` module, which is associated with template strings.

Signed-off-by: Koudai Aono <koxudaxi@gmail.com>
Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Koudai Aono
2025-11-10 17:13:28 +00:00
committed by Damien George
parent bdef10a92b
commit 68c2d4e457
2 changed files with 231 additions and 0 deletions

View File

@@ -78,6 +78,7 @@ library.
select.rst
socket.rst
ssl.rst
string.templatelib.rst
struct.rst
sys.rst
time.rst

View File

@@ -0,0 +1,230 @@
:mod:`string.templatelib` -- Template String Support
====================================================
.. module:: string.templatelib
:synopsis: PEP 750 template string support
This module provides support for template strings (t-strings) as defined in
`PEP 750 <https://peps.python.org/pep-0750/>`_. Template strings are created
using the ``t`` prefix and provide access to both the literal string parts and
interpolated values before they are combined.
**Availability:** template strings require ``MICROPY_PY_TSTRINGS`` to be enabled
at compile time. They are enabled by default at the full feature level, which
includes the alif, mimxrt and samd (SAMD51 only) ports, the unix coverage variant
and the webassembly pyscript variant.
Classes
-------
.. class:: Template(*args)
Represents a template string. Template objects are typically created by
t-string syntax (``t"..."``) but can also be constructed directly using
the constructor.
.. attribute:: strings
A tuple of string literals that appear between interpolations.
.. attribute:: interpolations
A tuple of :class:`Interpolation` objects representing the interpolated
expressions.
.. attribute:: values
A read-only property that returns a tuple containing the ``value``
attribute from each interpolation in the template.
.. method:: __iter__()
Iterate over the template contents, yielding string parts and
:class:`Interpolation` objects in the order they appear. Empty strings
are omitted.
.. method:: __add__(other)
Concatenate two templates. Returns a new :class:`Template` combining
the strings and interpolations from both templates.
:raises TypeError: if *other* is not a :class:`Template`
Template concatenation with ``str`` is prohibited to avoid ambiguity
about whether the string should be treated as a literal or interpolation::
t1 = t"Hello "
t2 = t"World"
result = t1 + t2 # Valid
# TypeError: cannot concatenate str to Template
result = t1 + "World"
.. class:: Interpolation(value, expression='', conversion=None, format_spec='')
Represents an interpolated expression within a template string. All
arguments can be passed as keyword arguments.
.. attribute:: value
The evaluated value of the interpolated expression.
.. attribute:: expression
The string representation of the expression as it appeared in the
template string.
.. attribute:: conversion
The conversion specifier (``'s'`` or ``'r'``) if present, otherwise ``None``.
Note that MicroPython does not support the ``'a'`` conversion.
.. attribute:: format_spec
The format specification string if present, otherwise an empty string.
Template String Syntax
----------------------
Template strings use the same syntax as f-strings but with a ``t`` prefix::
name = "World"
template = t"Hello {name}!"
# Access template components
print(template.strings) # ('Hello ', '!')
print(template.values) # ('World',)
print(template.interpolations[0].expression) # 'name'
Conversion Specifiers
~~~~~~~~~~~~~~~~~~~~~
Template strings store conversion specifiers as metadata. Unlike f-strings,
the conversion is not applied automatically::
value = "test"
t = t"{value!r}"
# t.interpolations[0].value == "test" (not repr(value))
# t.interpolations[0].conversion == "r"
Processing code must explicitly apply conversions when needed.
Format Specifications
~~~~~~~~~~~~~~~~~~~~~
Format specifications are stored as metadata in the ``Interpolation`` object.
Unlike f-strings, formatting is not applied automatically::
pi = 3.14159
t = t"{pi:.2f}"
# t.interpolations[0].value == 3.14159 (not formatted)
# t.interpolations[0].format_spec == ".2f"
Per PEP 750, processing code is not required to use format specifications, but
when present they should be respected and match f-string behavior where possible.
Debug Format
~~~~~~~~~~~~
The debug format ``{expr=}`` is supported::
x = 42
t = t"{x=}"
# t.strings == ("x=", "")
# t.interpolations[0].expression == "x"
# t.interpolations[0].conversion == "r"
.. admonition:: Important
:class: attention
As per PEP 750, unlike f-strings, template strings do not automatically
apply conversions or format specifications. This is by design to allow
processing code to control how these are handled. Processing code must
explicitly handle these attributes.
MicroPython does not provide the ``format()`` built-in function. Use
string formatting methods like ``str.format()`` instead.
Example Usage
-------------
Basic processing without format support::
def simple_process(template):
"""Simple template processing"""
parts = []
for item in template:
if isinstance(item, str):
parts.append(item)
else:
parts.append(str(item.value))
return "".join(parts)
Processing template with format support::
from string.templatelib import Template, Interpolation
def convert(value, conversion):
"""Apply conversion specifier to value"""
if conversion == "r":
return repr(value)
elif conversion == "s":
return str(value)
return value
def process_template(template):
"""Process template with conversion and format support"""
result = []
for part in template:
if isinstance(part, str):
result.append(part)
else: # Interpolation
value = convert(part.value, part.conversion)
if part.format_spec:
# Apply format specification using str.format
value = ("{:" + part.format_spec + "}").format(value)
else:
value = str(value)
result.append(value)
return "".join(result)
pi = 3.14159
name = "Alice"
t = t"{name!r}: {pi:.2f}"
print(process_template(t))
# Output: "'Alice': 3.14"
# Other format specifications work too
value = 42
print(process_template(t"{value:>10}")) # " 42"
print(process_template(t"{value:04d}")) # "0042"
HTML escaping example::
def html_escape(value):
"""Escape HTML special characters"""
if not isinstance(value, str):
value = str(value)
return value.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
def safe_html(template):
"""Convert template to HTML-safe string"""
result = []
for part in template:
if isinstance(part, str):
result.append(part)
else:
result.append(html_escape(part.value))
return "".join(result)
user_input = "<script>alert('xss')</script>"
t = t"User said: {user_input}"
print(safe_html(t))
# Output: "User said: &lt;script&gt;alert('xss')&lt;/script&gt;"
See Also
--------
* `PEP 750 <https://peps.python.org/pep-0750/>`_ - Template Strings specification
* :ref:`python:formatstrings` - Format string syntax
* `Formatted string literals <https://docs.python.org/3/reference/lexical_analysis.html#f-strings>`_ - f-strings in Python