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