xref: /aosp_15_r20/external/pytorch/test/jit/test_string_formatting.py (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1# Owner(s): ["oncall: jit"]
2
3import os
4import sys
5from typing import List
6
7import torch
8
9
10# Make the helper files in test/ importable
11pytorch_test_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
12sys.path.append(pytorch_test_dir)
13from torch.testing._internal.jit_utils import JitTestCase
14
15
16if __name__ == "__main__":
17    raise RuntimeError(
18        "This test file is not meant to be run directly, use:\n\n"
19        "\tpython test/test_jit.py TESTNAME\n\n"
20        "instead."
21    )
22
23
24class TestStringFormatting(JitTestCase):
25    def test_modulo_operator(self):
26        def fn(dividend: int, divisor: int) -> int:
27            return dividend % divisor
28
29        self.checkScript(fn, (5, 2))
30
31    def test_string_interpolation_with_string_placeholder_and_string_variable(self):
32        def fn(arg1: str):
33            return "%s in template" % arg1
34
35        self.checkScript(fn, ("foo",))
36
37    def test_string_interpolation_with_string_placeholder_and_format_string_variable(
38        self,
39    ):
40        def fn(arg1: str):
41            return arg1 % "foo"
42
43        self.checkScript(fn, ("%s in template",))
44
45    def test_string_interpolation_with_double_percent_in_string(self):
46        def fn(arg1: str):
47            return "%s in template %%" % arg1
48
49        self.checkScript(fn, ("foo",))
50
51    def test_string_interpolation_with_percent_in_string(self):
52        @torch.jit.script
53        def fn(arg1: str) -> str:
54            return "%s in template %" % arg1  # noqa: F501
55
56        with self.assertRaisesRegexWithHighlight(
57            RuntimeError, "Incomplete format specifier", '"%s in template %" % arg1'
58        ):
59            fn("foo")
60
61    def test_string_interpolation_with_string_placeholder_and_digit_variable(self):
62        def fn(arg1: int) -> str:
63            return "%s in template" % arg1
64
65        self.checkScript(fn, (1,))
66
67    def test_string_interpolation_with_digit_placeholder_and_digit_variable(self):
68        def fn(arg1: int) -> str:
69            return "%d in template" % arg1
70
71        self.checkScript(fn, (1,))
72
73    def test_string_interpolation_with_alternate_digit_placeholder(self):
74        def fn(arg1: int) -> str:
75            return "%i in template" % arg1
76
77        self.checkScript(fn, (1,))
78
79    def test_string_interpolation_with_digit_placeholder_and_string_variable(self):
80        @torch.jit.script
81        def fn(arg1: str) -> str:
82            return "%d in template" % arg1
83
84        with self.assertRaisesRegexWithHighlight(
85            RuntimeError,
86            "%d requires a number for formatting, but got String",
87            '"%d in template" % arg1',
88        ):
89            fn("1")
90
91    def test_string_interpolation_with_exponent_placeholder_and_string_variable(self):
92        @torch.jit.script
93        def fn(arg1: str) -> str:
94            return "%e in template" % arg1
95
96        with self.assertRaisesRegexWithHighlight(
97            RuntimeError,
98            "%e requires a number for formatting, but got String",
99            '"%e in template" % arg1',
100        ):
101            fn("1")
102
103    def test_string_interpolation_with_lowercase_exponent_placeholder_and_digit_variable(
104        self,
105    ):
106        def fn(arg1: int) -> str:
107            return "%e in template" % arg1
108
109        self.checkScript(fn, (1,))
110
111    def test_string_interpolation_with_capital_exponent_placeholder_and_digit_variable(
112        self,
113    ):
114        def fn(arg1: int) -> str:
115            return "%E in template" % arg1
116
117        self.checkScript(fn, (1,))
118
119    def test_string_interpolation_with_float_placeholder_and_float_variable(self):
120        def fn(arg1: float) -> str:
121            return "%f in template" % arg1
122
123        self.checkScript(fn, (1.0,))
124
125    def test_string_interpolation_with_float_placeholder_and_digit_variable(self):
126        def fn(arg1: int) -> str:
127            return "%f in template" % arg1
128
129        self.checkScript(fn, (1,))
130
131    def test_string_interpolation_with_char_placeholder_and_char_variable(self):
132        def fn(arg1: str) -> str:
133            return "%c in template" % arg1
134
135        self.checkScript(fn, ("a",))
136
137    def test_string_interpolation_with_char_placeholder_and_digit_variable(self):
138        def fn(arg1: int) -> str:
139            return "%c in template" % arg1
140
141        self.checkScript(fn, (97,))
142
143    def test_string_interpolation_with_char_placeholder_and_true_string_variable(self):
144        @torch.jit.script
145        def fn(arg1: str) -> str:
146            return "%c in template" % arg1
147
148        with self.assertRaisesRegexWithHighlight(
149            RuntimeError,
150            "%c requires an int or char for formatting, but got String",
151            '"%c in template" % arg1',
152        ):
153            fn("foo")
154
155    def test_string_interpolation_with_multiple_placeholders(self):
156        def fn(arg1: str, arg2: int, arg3: float) -> str:
157            return "%s %d %f in template" % (arg1, arg2, arg3)
158
159        self.checkScript(fn, ("foo", 1, 1))
160
161    def test_string_interpolation_with_subscript(self):
162        def fn(arg1: List[str]) -> str:
163            return "%s in template" % arg1[0]
164
165        self.checkScript(fn, (["foo", "bar"],))
166
167    def test_string_interpolation_with_too_few_arguments(self):
168        @torch.jit.script
169        def fn(arg1: str) -> str:
170            return "%s %s in template" % arg1
171
172        with self.assertRaisesRegexWithHighlight(
173            RuntimeError,
174            "Too few arguments for format string",
175            '"%s %s in template" % arg1',
176        ):
177            fn("foo")
178
179    def test_string_interpolation_with_too_many_arguments(self):
180        @torch.jit.script
181        def fn(arg1: str, arg2: str) -> str:
182            return "%s in template" % (arg1, arg2)  # noqa: F507
183
184        with self.assertRaisesRegexWithHighlight(
185            RuntimeError,
186            "Too many arguments for format string",
187            '"%s in template" % (arg1, arg2',
188        ):
189            fn("foo", "bar")
190
191    def test_string_interpolation_with_unknown_format_specifier(self):
192        @torch.jit.script
193        def fn(arg1: str) -> str:
194            return "%a in template" % arg1  # noqa: F501
195
196        with self.assertRaisesRegexWithHighlight(
197            RuntimeError,
198            "The specifier %a is not supported in TorchScript format strings",
199            '"%a in template" % arg1',
200        ):
201            fn("foo")
202