Skip to content
Merged
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_strings.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}"))