2.3. Syntax T-String

  • New string literal prefix: t'...'

  • Stands for Template String

  • Similar to f-strings (formatted string literals)

  • Uses string.templatelib module

  • Since Python 3.14

2.3.1. Problem

  • The following code constructs a SQL query using f-strings

  • However, it does not provide a way to analyze the structure of the query

  • It poses security risks (SQL injection) if user inputs are not sanitized

>>> username = 'alice'
>>> password = 'secret'
>>> query = f'SELECT * FROM users WHERE username="{username}" AND password="{password}"'
>>>
>>> print(query)
SELECT * FROM users WHERE username="alice" AND password="secret"

2.3.2. Solution

  • Use t-strings to create a template representation of the SQL query

  • This allows for safer handling and analysis of the query structure

>>> username = 'alice'
>>> password = 'secret'
>>> query = t'SELECT * FROM users WHERE username="{username}" AND password="{password}"'
>>>
>>> print(query)
Template(strings=('SELECT * FROM users WHERE username="', '" AND password="', '"'),
         interpolations=(Interpolation('alice', 'username', None, ''),
                         Interpolation('secret', 'password', None, '')))

2.3.3. Example

>>> name = 'Alice'
>>> day = 'Friday'
>>>
>>> template = t'Hello {name}! Today is {day}.'
>>>
>>> template
Template(strings=('Hello ', '! Today is ', '.'),
         interpolations=(Interpolation('Alice', 'name', None, ''),
                         Interpolation('Friday', 'day', None, '')))

2.3.4. Parsing

  • https://docs.python.org/id/3/library/string.templatelib.html#string.templatelib.Interpolation

  • value - the value of the expression

  • expression - text found inside the curly brackets ({ and }), including any whitespace, excluding the curly brackets themselves, and ending before the first !, :, or = if any is present

  • conversion - a, r, s or None, depending on whether a conversion flag was present, ie. "Hello {user!r}"

  • format_spec - the format specifier, ie. "Hello {value:.2f}" or "Hello {value:myfspec}"

>>> from string.templatelib import Interpolation, Template
>>>
>>>
>>> def parse(template):
...     if not isinstance(template, Template):
...         raise TypeError('t-string expected')
...     result = []
...     for item in template:
...         if isinstance(item, str):
...             # ... <your code here> ...
...             iterpolated = item
...             result.append(iterpolated)
...         elif isinstance(item, Interpolation):
...             value = item.value
...             expression = item.expression
...             conversion = item.conversion
...             format_spec = item.format_spec
...             iterpolated = format(value, format_spec)
...             result.append(iterpolated)
...     return ''.join(result)
>>>
>>>
>>> name = 'Alice'
>>> day = 'Friday'
>>>
>>> template = t'Hello {name}! Today is {day}.'
>>>
>>> parse(template)
'Hello Alice! Today is Friday.'

2.3.5. Assignments

# %% About
# - Name: Syntax T-String Usage
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Create t-string with text 'Hello Alice' using variable `NAME`
# 2. Define variable `result` with the solution
# 3. Run doctests - all must succeed

# %% Polish
# 1. Stwórz t-string z tekstem 'Hello Alice' używając zmiennej `NAME`
# 2. Zdefiniuj zmienną `result` z rozwiązaniem
# 3. Uruchom doctesty - wszystkie muszą się powieść

# %% Expected
# >>> print(result)
# Template(strings=('Hello ', ''), interpolations=(Interpolation('Alice', 'NAME', None, ''),))

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0

>>> assert sys.version_info >= (3, 14), \
'Python has an is invalid version; expected: `3.14` or newer.'

>>> assert 'result' in globals(), \
'Variable `result` is not defined; assign result of your program to it.'

>>> assert result is not Ellipsis, \
'Variable `result` has an invalid value; assign result of your program to it.'

>>> assert type(result) is Template, \
'Variable `result` has an invalid type; expected: `Template`.'

>>> assert 'Hello ' in result.strings, \
'Word `Hello` must be in the `result`'

>>> assert result.interpolations, \
'Variable `result.interpolations` has invalid value; expected not empty.'

>>> result
Template(strings=('Hello ', ''), interpolations=(Interpolation('Alice', 'NAME', None, ''),))
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`

# %% Imports

# %% Types
from string.templatelib import Template, Interpolation
result: Template

# %% Data
NAME = 'Alice'

# %% Result
result = ...

# %% About
# - Name: Syntax T-String Validation
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Create function `result` that checks if argument is a t-string Template
# 2. If not, raise `TypeError` with message 'Expected a Template instance'
# 3. If yes, return `True`
# 4. Run doctests - all must succeed

# %% Polish
# 1. Stwórz funkcję `result`, która sprawdza czy argument jest t-stringowym Template
# 2. Jeśli nie, rzuć `TypeError` z komunikatem 'Expected
# 3. Jeśli tak, zwróć `True`
# 4. Uruchom doctesty - wszystkie muszą się powieść

# %% Expected
# >>> result(t'Hello')
# True
#
# >>> result('Hello')
# Traceback (most recent call last):
# TypeError: Expected a Template instance
#
# >>> result(f'Hello')
# Traceback (most recent call last):
# TypeError: Expected a Template instance
#
# >>> result(r'Hello')
# Traceback (most recent call last):
# TypeError: Expected a Template instance

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0

>>> assert sys.version_info >= (3, 14), \
'Python has an is invalid version; expected: `3.14` or newer.'

>>> assert 'result' in globals(), \
'Function `result` is not defined; assign result of your program to it.'

>>> assert result is not Ellipsis, \
'Function `result` has an invalid value; assign result of your program to it.'

>>> assert callable(result), \
'Function `result` has an invalid type; expected: `callable`.'

>>> result(t'Hello')
True

>>> result('Hello')
Traceback (most recent call last):
TypeError: Expected a Template instance

>>> result(f'Hello')
Traceback (most recent call last):
TypeError: Expected a Template instance

>>> result(r'Hello')
Traceback (most recent call last):
TypeError: Expected a Template instance
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`

# %% Imports

# %% Types
from string.templatelib import Template
from typing import Callable
result: Callable[[Template|str], None|bool]

# %% Data

# %% Result
def result(x):
    ...