Skip to content

Sample code for the article on t-strings #671

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions python-t-strings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Python 3.14 Preview: Template Strings (T-Strings)

This folder provides the code examples for the Real Python tutorial [Python 3.14 Preview: Template Strings (T-Strings)](https://realpython.com/python-t-string/).
20 changes: 20 additions & 0 deletions python-t-strings/asynchronous.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import asyncio


async def get_name():
# Simulate an asynchronous operation
await asyncio.sleep(1)
return "Pythonista"


async def greeting_template():
"Uncomment in Python 3.14+"
# return t"Hello, {await get_name()}!"


async def main():
greeting = await greeting_template()
print(greeting)


asyncio.run(main())
39 changes: 39 additions & 0 deletions python-t-strings/logging_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import json
import logging
from string.templatelib import Template

logging.basicConfig(level=logging.INFO, format="%(message)s")


class TemplateMessage:
def __init__(self, template):
if not isinstance(template, Template):
raise TypeError("t-string expected")
self.template = template

@property
def message(self):
parts = []
for item in self.template:
if isinstance(item, str):
parts.append(item)
else:
parts.append(str(item.value))
return "".join(parts)

@property
def values_dict(self):
values = {}
for item in self.template:
if not isinstance(item, str):
values[item.expression] = item.value
return values

def __str__(self):
return f"{self.message} >>> {json.dumps(self.values_dict)}"


# Uncomment in Python 3.14+
# action, amount, item = "refund", 7, "keyboard"
# msg_template = TemplateMessage(t"Process {action}: {amount:.2f} {item}")
# logging.info(msg_template)
22 changes: 22 additions & 0 deletions python-t-strings/scape_html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import html
from string.templatelib import Template


def generate_safe_html(template):
if not isinstance(template, Template):
raise TypeError("t-string expected")
parts = []
for item in template:
if isinstance(item, str):
parts.append(item)
else:
parts.append(html.escape(item.value))
return "".join(parts)


# Uncomment in Python 3.14+
# username = "<script>alert('Hacked!')</script>"
# template = t"<p>Hello, {username}!</p>"

# safe_html = render_safe_html(template)
# print(safe_html)
27 changes: 27 additions & 0 deletions python-t-strings/sql.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from string.templatelib import Template


def sanitized_sql(template):
if not isinstance(template, Template):
raise TypeError("t-string expected")
parts = []
params = []

for item in template:
if isinstance(item, str):
parts.append(item)
else:
parts.append("?")
params.append(item.value)

query = "".join(parts)
return query, tuple(params)


# Uncomment in Python 3.14+
# username = "john'); DROP TABLE students;--"
# template = t"SELECT * FROM students WHERE name = {username}"
# query, params = sanitized_sql(template)
# print("Sanitized SQL Query:", query)

# print("Parameters:", params)
23 changes: 23 additions & 0 deletions python-t-strings/to_stirngs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
def to_string(template):
def convert(value, conversion):
func = {"a": ascii, "r": repr, "s": str}.get(conversion, lambda x: x)
return func(value)

parts = []
for item in template:
if isinstance(item, str):
parts.append(item)
else:
value = format(
convert(item.value, item.conversion), item.format_spec
)
parts.append(value)
return "".join(parts)


# Uncomment in Python 3.14+
# price = 234.8765
# print(to_string(t"The price is ${price:.2f}"))

# header = "Report"
# print(to_string(t"{header:=^20}"))