From 2ae0eb1a87a6cb991f9639aedb756841cd5dca69 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 15 Jul 2025 12:22:24 +0200 Subject: [3.14] GH-132661: Add ``string.templatelib.convert()`` (GH-135217) (#136671) GH-132661: Add ``string.templatelib.convert()`` (GH-135217) (cherry picked from commit 5b969fd64502a6e2ba6513e2b18beaeae58b8aa1) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- Lib/string/templatelib.py | 17 ++++++++++++----- Lib/test/test_string/test_templatelib.py | 22 +++++++++++++++++++++- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Lib/string/templatelib.py b/Lib/string/templatelib.py index 14b40e1..8164872 100644 --- a/Lib/string/templatelib.py +++ b/Lib/string/templatelib.py @@ -1,15 +1,22 @@ """Support for template string literals (t-strings).""" -__all__ = [ - "Interpolation", - "Template", -] - t = t"{0}" Template = type(t) Interpolation = type(t.interpolations[0]) del t +def convert(obj, /, conversion): + """Convert *obj* using formatted string literal semantics.""" + if conversion is None: + return obj + if conversion == 'r': + return repr(obj) + if conversion == 's': + return str(obj) + if conversion == 'a': + return ascii(obj) + raise ValueError(f'invalid conversion specifier: {conversion}') + def _template_unpickle(*args): import itertools diff --git a/Lib/test/test_string/test_templatelib.py b/Lib/test/test_string/test_templatelib.py index adaf590..1c86717 100644 --- a/Lib/test/test_string/test_templatelib.py +++ b/Lib/test/test_string/test_templatelib.py @@ -1,7 +1,7 @@ import pickle import unittest from collections.abc import Iterator, Iterable -from string.templatelib import Template, Interpolation +from string.templatelib import Template, Interpolation, convert from test.test_string._support import TStringBaseCase, fstring @@ -169,5 +169,25 @@ class TemplateIterTests(unittest.TestCase): self.assertRaises(StopIteration, next, template_iter) +class TestFunctions(unittest.TestCase): + def test_convert(self): + from fractions import Fraction + + for obj in ('Café', None, 3.14, Fraction(1, 2)): + with self.subTest(f'{obj=}'): + self.assertEqual(convert(obj, None), obj) + self.assertEqual(convert(obj, 's'), str(obj)) + self.assertEqual(convert(obj, 'r'), repr(obj)) + self.assertEqual(convert(obj, 'a'), ascii(obj)) + + # Invalid conversion specifier + with self.assertRaises(ValueError): + convert(obj, 'z') + with self.assertRaises(ValueError): + convert(obj, 1) + with self.assertRaises(ValueError): + convert(obj, object()) + + if __name__ == '__main__': unittest.main() -- cgit v0.12