github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/third_party/stdlib/test/test_string.py (about) 1 import unittest 2 import string 3 # from string import Template 4 Template = string.Template 5 from test import test_support, string_tests 6 # from UserList import UserList 7 import UserList as _UserList 8 UserList = _UserList.UserList 9 10 class StringTest( 11 string_tests.CommonTest, 12 string_tests.MixinStrStringUserStringTest 13 ): 14 15 type2test = str 16 17 def checkequal(self, result, object, methodname, *args): 18 realresult = getattr(string, methodname)(object, *args) 19 self.assertEqual( 20 result, 21 realresult 22 ) 23 24 def checkraises(self, exc, obj, methodname, *args): 25 with self.assertRaises(exc) as cm: 26 getattr(string, methodname)(obj, *args) 27 self.assertNotEqual(cm.exception.args[0], '') 28 29 def checkcall(self, object, methodname, *args): 30 getattr(string, methodname)(object, *args) 31 32 @unittest.expectedFailure 33 def test_join(self): 34 # These are the same checks as in string_test.ObjectTest.test_join 35 # but the argument order ist different 36 self.checkequal('a b c d', ['a', 'b', 'c', 'd'], 'join', ' ') 37 self.checkequal('abcd', ('a', 'b', 'c', 'd'), 'join', '') 38 self.checkequal('w x y z', string_tests.Sequence(), 'join', ' ') 39 self.checkequal('abc', ('abc',), 'join', 'a') 40 self.checkequal('z', UserList(['z']), 'join', 'a') 41 if test_support.have_unicode: 42 self.checkequal(unicode('a.b.c'), ['a', 'b', 'c'], 'join', unicode('.')) 43 self.checkequal(unicode('a.b.c'), [unicode('a'), 'b', 'c'], 'join', '.') 44 self.checkequal(unicode('a.b.c'), ['a', unicode('b'), 'c'], 'join', '.') 45 self.checkequal(unicode('a.b.c'), ['a', 'b', unicode('c')], 'join', '.') 46 self.checkraises(TypeError, ['a', unicode('b'), 3], 'join', '.') 47 for i in [5, 25, 125]: 48 self.checkequal( 49 ((('a' * i) + '-') * i)[:-1], 50 ['a' * i] * i, 'join', '-') 51 self.checkequal( 52 ((('a' * i) + '-') * i)[:-1], 53 ('a' * i,) * i, 'join', '-') 54 55 self.checkraises(TypeError, string_tests.BadSeq1(), 'join', ' ') 56 self.checkequal('a b c', string_tests.BadSeq2(), 'join', ' ') 57 try: 58 def f(): 59 yield 4 + "" 60 self.fixtype(' ').join(f()) 61 except TypeError, e: 62 if '+' not in str(e): 63 self.fail('join() ate exception message') 64 else: 65 self.fail('exception not raised') 66 67 68 class ModuleTest(unittest.TestCase): 69 70 def test_attrs(self): 71 string.whitespace 72 string.lowercase 73 string.uppercase 74 string.letters 75 string.digits 76 string.hexdigits 77 string.octdigits 78 string.punctuation 79 string.printable 80 81 def test_atoi(self): 82 self.assertEqual(string.atoi(" 1 "), 1) 83 self.assertRaises(ValueError, string.atoi, " 1x") 84 self.assertRaises(ValueError, string.atoi, " x1 ") 85 86 def test_atol(self): 87 self.assertEqual(string.atol(" 1 "), 1L) 88 self.assertRaises(ValueError, string.atol, " 1x ") 89 self.assertRaises(ValueError, string.atol, " x1 ") 90 91 @unittest.expectedFailure 92 def test_atof(self): 93 self.assertAlmostEqual(string.atof(" 1 "), 1.0) 94 self.assertRaises(ValueError, string.atof, " 1x ") 95 self.assertRaises(ValueError, string.atof, " x1 ") 96 97 def test_maketrans(self): 98 transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' 99 100 self.assertEqual(string.maketrans('abc', 'xyz'), transtable) 101 self.assertRaises(ValueError, string.maketrans, 'abc', 'xyzq') 102 103 @unittest.expectedFailure 104 def test_capwords(self): 105 self.assertEqual(string.capwords('abc def ghi'), 'Abc Def Ghi') 106 self.assertEqual(string.capwords('abc\tdef\nghi'), 'Abc Def Ghi') 107 self.assertEqual(string.capwords('abc\t def \nghi'), 'Abc Def Ghi') 108 self.assertEqual(string.capwords('ABC DEF GHI'), 'Abc Def Ghi') 109 self.assertEqual(string.capwords('ABC-DEF-GHI', '-'), 'Abc-Def-Ghi') 110 self.assertEqual(string.capwords('ABC-def DEF-ghi GHI'), 'Abc-def Def-ghi Ghi') 111 self.assertEqual(string.capwords(' aBc DeF '), 'Abc Def') 112 self.assertEqual(string.capwords('\taBc\tDeF\t'), 'Abc Def') 113 self.assertEqual(string.capwords('\taBc\tDeF\t', '\t'), '\tAbc\tDef\t') 114 115 @unittest.expectedFailure 116 def test_formatter(self): 117 fmt = string.Formatter() 118 self.assertEqual(fmt.format("foo"), "foo") 119 120 self.assertEqual(fmt.format("foo{0}", "bar"), "foobar") 121 self.assertEqual(fmt.format("foo{1}{0}-{1}", "bar", 6), "foo6bar-6") 122 self.assertEqual(fmt.format("-{arg!r}-", arg='test'), "-'test'-") 123 124 # override get_value ############################################ 125 class NamespaceFormatter(string.Formatter): 126 def __init__(self, namespace={}): 127 string.Formatter.__init__(self) 128 self.namespace = namespace 129 130 def get_value(self, key, args, kwds): 131 if isinstance(key, str): 132 try: 133 # Check explicitly passed arguments first 134 return kwds[key] 135 except KeyError: 136 return self.namespace[key] 137 else: 138 string.Formatter.get_value(key, args, kwds) 139 140 fmt = NamespaceFormatter({'greeting':'hello'}) 141 self.assertEqual(fmt.format("{greeting}, world!"), 'hello, world!') 142 143 144 # override format_field ######################################### 145 class CallFormatter(string.Formatter): 146 def format_field(self, value, format_spec): 147 return format(value(), format_spec) 148 149 fmt = CallFormatter() 150 self.assertEqual(fmt.format('*{0}*', lambda : 'result'), '*result*') 151 152 153 # override convert_field ######################################## 154 class XFormatter(string.Formatter): 155 def convert_field(self, value, conversion): 156 if conversion == 'x': 157 return None 158 return super(XFormatter, self).convert_field(value, conversion) 159 160 fmt = XFormatter() 161 self.assertEqual(fmt.format("{0!r}:{0!x}", 'foo', 'foo'), "'foo':None") 162 163 164 # override parse ################################################ 165 class BarFormatter(string.Formatter): 166 # returns an iterable that contains tuples of the form: 167 # (literal_text, field_name, format_spec, conversion) 168 def parse(self, format_string): 169 for field in format_string.split('|'): 170 if field[0] == '+': 171 # it's markup 172 field_name, _, format_spec = field[1:].partition(':') 173 yield '', field_name, format_spec, None 174 else: 175 yield field, None, None, None 176 177 fmt = BarFormatter() 178 self.assertEqual(fmt.format('*|+0:^10s|*', 'foo'), '* foo *') 179 180 # test all parameters used 181 class CheckAllUsedFormatter(string.Formatter): 182 def check_unused_args(self, used_args, args, kwargs): 183 # Track which arguments actually got used 184 unused_args = set(kwargs.keys()) 185 unused_args.update(range(0, len(args))) 186 187 for arg in used_args: 188 unused_args.remove(arg) 189 190 if unused_args: 191 raise ValueError("unused arguments") 192 193 fmt = CheckAllUsedFormatter() 194 self.assertEqual(fmt.format("{0}", 10), "10") 195 self.assertEqual(fmt.format("{0}{i}", 10, i=100), "10100") 196 self.assertEqual(fmt.format("{0}{i}{1}", 10, 20, i=100), "1010020") 197 self.assertRaises(ValueError, fmt.format, "{0}{i}{1}", 10, 20, i=100, j=0) 198 self.assertRaises(ValueError, fmt.format, "{0}", 10, 20) 199 self.assertRaises(ValueError, fmt.format, "{0}", 10, 20, i=100) 200 self.assertRaises(ValueError, fmt.format, "{i}", 10, 20, i=100) 201 202 # Alternate formatting is not supported 203 self.assertRaises(ValueError, format, '', '#') 204 self.assertRaises(ValueError, format, '', '#20') 205 206 @unittest.expectedFailure 207 def test_format_keyword_arguments(self): 208 fmt = string.Formatter() 209 self.assertEqual(fmt.format("-{arg}-", arg='test'), '-test-') 210 self.assertRaises(KeyError, fmt.format, "-{arg}-") 211 self.assertEqual(fmt.format("-{self}-", self='test'), '-test-') 212 self.assertRaises(KeyError, fmt.format, "-{self}-") 213 self.assertEqual(fmt.format("-{format_string}-", format_string='test'), 214 '-test-') 215 self.assertRaises(KeyError, fmt.format, "-{format_string}-") 216 self.assertEqual(fmt.format(arg='test', format_string="-{arg}-"), 217 '-test-') 218 219 class BytesAliasTest(unittest.TestCase): 220 221 @unittest.expectedFailure 222 def test_builtin(self): 223 self.assertTrue(str is bytes) 224 225 def test_syntax(self): 226 self.assertEqual(b"spam", "spam") 227 self.assertEqual(br"egg\foo", "egg\\foo") 228 self.assertTrue(type(b""), str) 229 self.assertTrue(type(br""), str) 230 231 232 # Template tests (formerly housed in test_pep292.py) 233 234 class Bag(object): 235 pass 236 237 class Mapping(object): 238 def __getitem__(self, name): 239 obj = self 240 for part in name.split('.'): 241 try: 242 obj = getattr(obj, part) 243 except AttributeError: 244 raise KeyError(name) 245 return obj 246 247 248 class TestTemplate(unittest.TestCase): 249 def test_regular_templates(self): 250 s = Template('$who likes to eat a bag of $what worth $$100') 251 self.assertEqual(s.substitute(dict(who='tim', what='ham')), 252 'tim likes to eat a bag of ham worth $100') 253 self.assertRaises(KeyError, s.substitute, dict(who='tim')) 254 self.assertRaises(TypeError, Template.substitute) 255 256 def test_regular_templates_with_braces(self): 257 s = Template('$who likes ${what} for ${meal}') 258 d = dict(who='tim', what='ham', meal='dinner') 259 self.assertEqual(s.substitute(d), 'tim likes ham for dinner') 260 self.assertRaises(KeyError, s.substitute, 261 dict(who='tim', what='ham')) 262 263 def test_escapes(self): 264 eq = self.assertEqual 265 s = Template('$who likes to eat a bag of $$what worth $$100') 266 eq(s.substitute(dict(who='tim', what='ham')), 267 'tim likes to eat a bag of $what worth $100') 268 s = Template('$who likes $$') 269 eq(s.substitute(dict(who='tim', what='ham')), 'tim likes $') 270 271 def test_percents(self): 272 eq = self.assertEqual 273 s = Template('%(foo)s $foo ${foo}') 274 d = dict(foo='baz') 275 eq(s.substitute(d), '%(foo)s baz baz') 276 eq(s.safe_substitute(d), '%(foo)s baz baz') 277 278 def test_stringification(self): 279 eq = self.assertEqual 280 s = Template('tim has eaten $count bags of ham today') 281 d = dict(count=7) 282 eq(s.substitute(d), 'tim has eaten 7 bags of ham today') 283 eq(s.safe_substitute(d), 'tim has eaten 7 bags of ham today') 284 s = Template('tim has eaten ${count} bags of ham today') 285 eq(s.substitute(d), 'tim has eaten 7 bags of ham today') 286 287 def test_tupleargs(self): 288 eq = self.assertEqual 289 s = Template('$who ate ${meal}') 290 d = dict(who=('tim', 'fred'), meal=('ham', 'kung pao')) 291 eq(s.substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')") 292 eq(s.safe_substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')") 293 294 def test_SafeTemplate(self): 295 eq = self.assertEqual 296 s = Template('$who likes ${what} for ${meal}') 297 eq(s.safe_substitute(dict(who='tim')), 'tim likes ${what} for ${meal}') 298 eq(s.safe_substitute(dict(what='ham')), '$who likes ham for ${meal}') 299 eq(s.safe_substitute(dict(what='ham', meal='dinner')), 300 '$who likes ham for dinner') 301 eq(s.safe_substitute(dict(who='tim', what='ham')), 302 'tim likes ham for ${meal}') 303 eq(s.safe_substitute(dict(who='tim', what='ham', meal='dinner')), 304 'tim likes ham for dinner') 305 306 @unittest.expectedFailure 307 def test_invalid_placeholders(self): 308 raises = self.assertRaises 309 s = Template('$who likes $') 310 raises(ValueError, s.substitute, dict(who='tim')) 311 s = Template('$who likes ${what)') 312 raises(ValueError, s.substitute, dict(who='tim')) 313 s = Template('$who likes $100') 314 raises(ValueError, s.substitute, dict(who='tim')) 315 316 def test_idpattern_override(self): 317 class PathPattern(Template): 318 idpattern = r'[_a-z][._a-z0-9]*' 319 m = Mapping() 320 m.bag = Bag() 321 m.bag.foo = Bag() 322 m.bag.foo.who = 'tim' 323 m.bag.what = 'ham' 324 s = PathPattern('$bag.foo.who likes to eat a bag of $bag.what') 325 self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham') 326 327 def test_pattern_override(self): 328 class MyPattern(Template): 329 pattern = r""" 330 (?P<escaped>@{2}) | 331 @(?P<named>[_a-z][._a-z0-9]*) | 332 @{(?P<braced>[_a-z][._a-z0-9]*)} | 333 (?P<invalid>@) 334 """ 335 m = Mapping() 336 m.bag = Bag() 337 m.bag.foo = Bag() 338 m.bag.foo.who = 'tim' 339 m.bag.what = 'ham' 340 s = MyPattern('@bag.foo.who likes to eat a bag of @bag.what') 341 self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham') 342 343 class BadPattern(Template): 344 pattern = r""" 345 (?P<badname>.*) | 346 (?P<escaped>@{2}) | 347 @(?P<named>[_a-z][._a-z0-9]*) | 348 @{(?P<braced>[_a-z][._a-z0-9]*)} | 349 (?P<invalid>@) | 350 """ 351 s = BadPattern('@bag.foo.who likes to eat a bag of @bag.what') 352 self.assertRaises(ValueError, s.substitute, {}) 353 self.assertRaises(ValueError, s.safe_substitute, {}) 354 355 def test_braced_override(self): 356 class MyTemplate(Template): 357 pattern = r""" 358 \$(?: 359 (?P<escaped>$) | 360 (?P<named>[_a-z][_a-z0-9]*) | 361 @@(?P<braced>[_a-z][_a-z0-9]*)@@ | 362 (?P<invalid>) | 363 ) 364 """ 365 366 tmpl = 'PyCon in $@@location@@' 367 t = MyTemplate(tmpl) 368 self.assertRaises(KeyError, t.substitute, {}) 369 val = t.substitute({'location': 'Cleveland'}) 370 self.assertEqual(val, 'PyCon in Cleveland') 371 372 def test_braced_override_safe(self): 373 class MyTemplate(Template): 374 pattern = r""" 375 \$(?: 376 (?P<escaped>$) | 377 (?P<named>[_a-z][_a-z0-9]*) | 378 @@(?P<braced>[_a-z][_a-z0-9]*)@@ | 379 (?P<invalid>) | 380 ) 381 """ 382 383 tmpl = 'PyCon in $@@location@@' 384 t = MyTemplate(tmpl) 385 self.assertEqual(t.safe_substitute(), tmpl) 386 val = t.safe_substitute({'location': 'Cleveland'}) 387 self.assertEqual(val, 'PyCon in Cleveland') 388 389 def test_unicode_values(self): 390 s = Template('$who likes $what') 391 d = dict(who=u't\xffm', what=u'f\xfe\fed') 392 self.assertEqual(s.substitute(d), u't\xffm likes f\xfe\x0ced') 393 394 def test_keyword_arguments(self): 395 eq = self.assertEqual 396 s = Template('$who likes $what') 397 eq(s.substitute(who='tim', what='ham'), 'tim likes ham') 398 eq(s.substitute(dict(who='tim'), what='ham'), 'tim likes ham') 399 eq(s.substitute(dict(who='fred', what='kung pao'), 400 who='tim', what='ham'), 401 'tim likes ham') 402 s = Template('the mapping is $mapping') 403 eq(s.substitute(dict(foo='none'), mapping='bozo'), 404 'the mapping is bozo') 405 eq(s.substitute(dict(mapping='one'), mapping='two'), 406 'the mapping is two') 407 408 s = Template('the self is $self') 409 eq(s.substitute(self='bozo'), 'the self is bozo') 410 411 def test_keyword_arguments_safe(self): 412 eq = self.assertEqual 413 raises = self.assertRaises 414 s = Template('$who likes $what') 415 eq(s.safe_substitute(who='tim', what='ham'), 'tim likes ham') 416 eq(s.safe_substitute(dict(who='tim'), what='ham'), 'tim likes ham') 417 eq(s.safe_substitute(dict(who='fred', what='kung pao'), 418 who='tim', what='ham'), 419 'tim likes ham') 420 s = Template('the mapping is $mapping') 421 eq(s.safe_substitute(dict(foo='none'), mapping='bozo'), 422 'the mapping is bozo') 423 eq(s.safe_substitute(dict(mapping='one'), mapping='two'), 424 'the mapping is two') 425 d = dict(mapping='one') 426 raises(TypeError, s.substitute, d, {}) 427 raises(TypeError, s.safe_substitute, d, {}) 428 429 s = Template('the self is $self') 430 eq(s.safe_substitute(self='bozo'), 'the self is bozo') 431 432 def test_delimiter_override(self): 433 eq = self.assertEqual 434 raises = self.assertRaises 435 class AmpersandTemplate(Template): 436 delimiter = '&' 437 s = AmpersandTemplate('this &gift is for &{who} &&') 438 eq(s.substitute(gift='bud', who='you'), 'this bud is for you &') 439 raises(KeyError, s.substitute) 440 eq(s.safe_substitute(gift='bud', who='you'), 'this bud is for you &') 441 eq(s.safe_substitute(), 'this &gift is for &{who} &') 442 s = AmpersandTemplate('this &gift is for &{who} &') 443 raises(ValueError, s.substitute, dict(gift='bud', who='you')) 444 eq(s.safe_substitute(), 'this &gift is for &{who} &') 445 446 class PieDelims(Template): 447 delimiter = '@' 448 s = PieDelims('@who likes to eat a bag of @{what} worth $100') 449 self.assertEqual(s.substitute(dict(who='tim', what='ham')), 450 'tim likes to eat a bag of ham worth $100') 451 452 453 def test_main(): 454 test_support.run_unittest(StringTest, ModuleTest, BytesAliasTest, TestTemplate) 455 456 if __name__ == '__main__': 457 test_main()