diff --git a/python-t-strings/README.md b/python-t-strings/README.md new file mode 100644 index 0000000000..eb7430babd --- /dev/null +++ b/python-t-strings/README.md @@ -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/). diff --git a/python-t-strings/asynchronous.py b/python-t-strings/asynchronous.py new file mode 100644 index 0000000000..1e74690cc1 --- /dev/null +++ b/python-t-strings/asynchronous.py @@ -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()) diff --git a/python-t-strings/logging_message.py b/python-t-strings/logging_message.py new file mode 100644 index 0000000000..3b778e1099 --- /dev/null +++ b/python-t-strings/logging_message.py @@ -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) diff --git a/python-t-strings/scape_html.py b/python-t-strings/scape_html.py new file mode 100644 index 0000000000..8c951e0b05 --- /dev/null +++ b/python-t-strings/scape_html.py @@ -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 = "" +# template = t"
Hello, {username}!
" + +# safe_html = render_safe_html(template) +# print(safe_html) diff --git a/python-t-strings/sql.py b/python-t-strings/sql.py new file mode 100644 index 0000000000..5c85a754a5 --- /dev/null +++ b/python-t-strings/sql.py @@ -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) diff --git a/python-t-strings/to_strings.py b/python-t-strings/to_strings.py new file mode 100644 index 0000000000..d51adb05de --- /dev/null +++ b/python-t-strings/to_strings.py @@ -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}"))