1# mode: run 2# tag: f_strings, pep498, werror 3 4#### 5# Cython specific PEP 498 tests in addition to test_fstring.pyx from CPython 6#### 7 8cimport cython 9 10import sys 11IS_PYPY = hasattr(sys, 'pypy_version_info') 12 13from libc.limits cimport INT_MAX, LONG_MAX, LONG_MIN 14 15max_int = INT_MAX 16max_long = LONG_MAX 17min_long = LONG_MIN 18 19 20@cython.test_fail_if_path_exists( 21 "//FormattedValueNode", 22 "//JoinedStrNode", 23 "//AddNode", 24) 25def escaping(): 26 """ 27 >>> escaping() 28 """ 29 assert f'{{{{{"abc"}}}}}{{}}{{' == '{{abc}}{}{' 30 s = f'{{{{{"abc"}}}}}{{}}{{' 31 assert s == '{{abc}}{}{', s 32 33 assert f'\x7b}}' == '{}' 34 s = f'\x7b}}' 35 assert s == '{}', s 36 37 assert f'{"{{}}"}' == '{{}}' 38 s = f'{"{{}}"}' 39 assert s == '{{}}', s 40 41 42@cython.test_fail_if_path_exists( 43 "//FormattedValueNode", 44 "//JoinedStrNode", 45 "//AddNode", 46) 47def nested_constant(): 48 """ 49 >>> print(nested_constant()) 50 xyabc123321 51 """ 52 return f"""{f'''xy{f"abc{123}{'321'}"!s}'''}""" 53 54 55def format2(ab, cd): 56 """ 57 >>> a, b, c = format2(1, 2) 58 >>> print(a) 59 ab2 60 >>> print(b) 61 1cd 62 >>> print(c) 63 12 64 65 >>> a, b, c = format2('ab', 'cd') 66 >>> print(a) 67 abcd 68 >>> print(b) 69 abcd 70 >>> print(c) 71 abcd 72 """ 73 a = f"ab{cd}" 74 assert isinstance(a, unicode), type(a) 75 b = f"{ab}cd" 76 assert isinstance(b, unicode), type(b) 77 c = f"{ab}{cd}" 78 assert isinstance(c, unicode) or (IS_PYPY and isinstance(c, str)), type(c) 79 return a, b, c 80 81 82ctypedef enum TestValues: 83 enum_ABC = 1 84 enum_XYZ = 2 85 86 87@cython.test_fail_if_path_exists( 88 "//CoerceToPyTypeNode", 89) 90def format_c_enum(): 91 """ 92 >>> s = format_c_enum() 93 >>> s == '1-2' or s 94 True 95 """ 96 return f"{enum_ABC}-{enum_XYZ}" 97 98 99def format_c_numbers(signed char c, short s, int n, long l, float f, double d): 100 """ 101 >>> s1, s2, s3, s4 = format_c_numbers(123, 135, 12, 12312312, 2.3456, 3.1415926) 102 >>> print(s1) 103 123 13512312312122.35 104 >>> print(s2) 105 3.14 2.3 106 >>> print(s3) 107 12f 108 >>> print(s4) 109 0C014 3.14 110 111 >>> s1, s2, s3, s4 = format_c_numbers(-123, -135, -12, -12312312, -2.3456, -3.1415926) 112 >>> print(s1) 113 -123-135-12312312-12-2.35 114 >>> print(s2) 115 -3.14-2.3 116 >>> print(s3) 117 -12f 118 >>> print(s4) 119 -C-14-3.14 120 121 >>> s1, s2, s3, s4 = format_c_numbers(0, 0, 0, 0, -2.3456, -0.1415926) 122 >>> print(s1) 123 0 000-2.35 124 >>> print(s2) 125 -0.142-2.3 126 >>> print(s3) 127 0f 128 >>> print(s4) 129 00000-0.142 130 131 """ 132 s1 = f"{c}{s:4}{l}{n}{f:.3}" 133 assert isinstance(s1, unicode), type(s1) 134 s2 = f"{d:.3}{f:4.2}" 135 assert isinstance(s2, unicode), type(s2) 136 s3 = f"{n:-4}f" 137 assert isinstance(s3, unicode), type(s3) 138 s4 = f"{n:02X}{n:03o}{d:5.3}" 139 assert isinstance(s4, unicode), type(s4) 140 return s1, s2, s3, s4 141 142 143def format_c_numbers_unsigned(unsigned char c, unsigned short s, unsigned int n, unsigned long l): 144 """ 145 >>> s1, s2, s3 = format_c_numbers_unsigned(123, 135, 12, 12312312) 146 >>> print(s1) 147 123 135 5675737012 148 >>> print(s2) 149 12f 150 >>> print(s3) 151 0C014 bbdef8 152 153 """ 154 s1 = f"{c}{s:4} {l:o}{n}" 155 assert isinstance(s1, unicode), type(s1) 156 s2 = f"{n:-4}f" 157 assert isinstance(s2, unicode), type(s2) 158 s3 = f"{n:02X}{n:03o}{l:10x}" 159 assert isinstance(s3, unicode), type(s3) 160 return s1, s2, s3 161 162 163@cython.test_fail_if_path_exists( 164 "//CoerceToPyTypeNode", 165) 166def format_c_numbers_max(int n, long l): 167 """ 168 >>> n, l = max_int, max_long 169 >>> s1, s2 = format_c_numbers_max(n, l) 170 >>> s1 == '{n}:{l}'.format(n=n, l=l) or s1 171 True 172 >>> s2 == '{n:012X}:{l:020X}'.format(n=n, l=l) or s2 173 True 174 175 >>> n, l = -max_int-1, -max_long-1 176 >>> s1, s2 = format_c_numbers_max(n, l) 177 >>> s1 == '{n}:{l}'.format(n=n, l=l) or s1 178 True 179 >>> s2 == '{n:012X}:{l:020X}'.format(n=n, l=l) or s2 180 True 181 """ 182 s1 = f"{n}:{l}" 183 assert isinstance(s1, unicode), type(s1) 184 s2 = f"{n:012X}:{l:020X}" 185 assert isinstance(s2, unicode), type(s2) 186 return s1, s2 187 188 189def format_c_number_const(): 190 """ 191 >>> s = format_c_number_const() 192 >>> s == '{0}'.format(max_long) or s 193 True 194 """ 195 return f"{LONG_MAX}" 196 197 198@cython.test_fail_if_path_exists( 199 "//CoerceToPyTypeNode", 200) 201def format_c_number_range(int n): 202 """ 203 >>> for i in range(-1000, 1001): 204 ... assert format_c_number_range(i) == str(i) 205 """ 206 return f'{n}' 207 208 209@cython.test_fail_if_path_exists( 210 "//CoerceToPyTypeNode", 211) 212def format_c_number_range_width(int n): 213 """ 214 >>> for i in range(-1000, 1001): 215 ... formatted = format_c_number_range_width(i) 216 ... expected = '{n:04d}'.format(n=i) 217 ... assert formatted == expected, "%r != %r" % (formatted, expected) 218 """ 219 return f'{n:04}' 220 221 222def format_c_number_range_width0(int n): 223 """ 224 >>> for i in range(-100, 101): 225 ... formatted = format_c_number_range_width0(i) 226 ... expected = '{n:00d}'.format(n=i) 227 ... assert formatted == expected, "%r != %r" % (formatted, expected) 228 """ 229 return f'{n:00}' 230 231 232@cython.test_fail_if_path_exists( 233 "//CoerceToPyTypeNode", 234) 235def format_c_number_range_width1(int n): 236 """ 237 >>> for i in range(-100, 101): 238 ... formatted = format_c_number_range_width1(i) 239 ... expected = '{n:01d}'.format(n=i) 240 ... assert formatted == expected, "%r != %r" % (formatted, expected) 241 """ 242 return f'{n:01}' 243 244 245@cython.test_fail_if_path_exists( 246 "//CoerceToPyTypeNode", 247) 248def format_c_number_range_width_m4(int n): 249 """ 250 >>> for i in range(-100, 101): 251 ... formatted = format_c_number_range_width_m4(i) 252 ... expected = '{n:-4d}'.format(n=i) 253 ... assert formatted == expected, "%r != %r" % (formatted, expected) 254 """ 255 return f'{n:-4}' 256 257 258def format_c_number_range_dyn_width(int n, int width): 259 """ 260 >>> for i in range(-1000, 1001): 261 ... assert format_c_number_range_dyn_width(i, 0) == str(i), format_c_number_range_dyn_width(i, 0) 262 ... assert format_c_number_range_dyn_width(i, 1) == '%01d' % i, format_c_number_range_dyn_width(i, 1) 263 ... assert format_c_number_range_dyn_width(i, 4) == '%04d' % i, format_c_number_range_dyn_width(i, 4) 264 ... assert format_c_number_range_dyn_width(i, 5) == '%05d' % i, format_c_number_range_dyn_width(i, 5) 265 ... assert format_c_number_range_dyn_width(i, 6) == '%06d' % i, format_c_number_range_dyn_width(i, 6) 266 """ 267 return f'{n:0{width}}' 268 269 270@cython.test_fail_if_path_exists( 271 "//CoerceToPyTypeNode", 272) 273def format_bool(bint x): 274 """ 275 >>> a, b, c, d = format_bool(1) 276 >>> print(a) # 1 277 True 278 >>> print(b) # 1 279 True 280 >>> print(c) # 1 281 False 282 >>> print(d) # 1 283 False 284 285 >>> a, b, c, d = format_bool(2) 286 >>> print(a) # 2 287 True 288 >>> print(b) # 2 289 True 290 >>> print(c) # 2 291 False 292 >>> print(d) # 2 293 False 294 295 >>> a, b, c, d = format_bool(0) 296 >>> print(a) # 3 297 False 298 >>> print(b) # 3 299 True 300 >>> print(c) # 3 301 False 302 >>> print(d) # 3 303 False 304 """ 305 return f'{x}', f'{True}', f'{x == 2}', f'{2 > 3}' 306 307 308def format_c_values(Py_UCS4 uchar, Py_UNICODE pyunicode): 309 """ 310 >>> s, s1, s2, s3 = format_c_values(b'A'.decode('ascii'), b'X'.decode('ascii')) 311 >>> print(s) 312 AXAX 313 >>> print(s1) 314 A 315 >>> print(s2) 316 X 317 >>> print(s3) 318 None 319 320 """ 321 s = f"{uchar}{pyunicode}{uchar!s}{pyunicode!s}" 322 assert isinstance(s, unicode), type(s) 323 s1 = f"{uchar}" 324 assert isinstance(s1, unicode), type(s1) 325 s2 = f"{pyunicode}" 326 assert isinstance(s2, unicode), type(s2) 327 l = [1, 2, 3] 328 s3 = f"{l.reverse()}" # C int return value => 'None' 329 assert isinstance(s3, unicode), type(s3) 330 assert l == [3, 2, 1] 331 return s, s1, s2, s3 332 333 334xyz_ustring = u'xÄyÖz' 335 336def format_strings(str s, unicode u): 337 u""" 338 >>> a, b, c, d, e, f, g = format_strings('abc', b'xyz'.decode('ascii')) 339 >>> print(a) 340 abcxyz 341 >>> print(b) 342 xyzabc 343 >>> print(c) 344 uxyzsabc 345 >>> print(d) 346 sabcuxyz 347 >>> print(e) 348 sabcuÄÄuxyz 349 >>> print(f) 350 sabcu\N{SNOWMAN}uxyz 351 >>> print(g) 352 sabcu\N{OLD PERSIAN SIGN A}uxyz\N{SNOWMAN} 353 354 >>> a, b, c, d, e, f, g = format_strings('abc', xyz_ustring) 355 >>> print(a) 356 abcxÄyÖz 357 >>> print(b) 358 xÄyÖzabc 359 >>> print(c) 360 uxÄyÖzsabc 361 >>> print(d) 362 sabcuxÄyÖz 363 >>> print(e) 364 sabcuÄÄuxÄyÖz 365 >>> print(f) 366 sabcu\N{SNOWMAN}uxÄyÖz 367 >>> print(g) 368 sabcu\N{OLD PERSIAN SIGN A}uxÄyÖz\N{SNOWMAN} 369 """ 370 a = f"{s}{u}" 371 assert isinstance(a, unicode), type(a) 372 b = f"{u}{s}" 373 assert isinstance(b, unicode), type(b) 374 c = f"u{u}s{s}" 375 assert isinstance(c, unicode), type(c) 376 d = f"s{s}u{u}" 377 assert isinstance(d, unicode), type(d) 378 e = f"s{s}uÄÄu{u}" 379 assert isinstance(e, unicode), type(e) 380 f = f"s{s}u\N{SNOWMAN}u{u}" 381 assert isinstance(f, unicode), type(f) 382 g = f"s{s}u\N{OLD PERSIAN SIGN A}u{u}\N{SNOWMAN}" 383 assert isinstance(g, unicode), type(g) 384 return a, b, c, d, e, f, g 385 386 387def format_pystr(str s1, str s2): 388 """ 389 >>> a, b, c, d = format_pystr('abc', 'xyz') 390 >>> print(a) 391 abcxyz 392 >>> print(b) 393 xyzabc 394 >>> print(c) 395 uxyzsabc 396 >>> print(d) 397 sabcuxyz 398 """ 399 a = f"{s1}{s2}" 400 assert isinstance(a, unicode) or (IS_PYPY and isinstance(a, str)), type(a) 401 b = f"{s2}{s1}" 402 assert isinstance(b, unicode) or (IS_PYPY and isinstance(a, str)), type(b) 403 c = f"u{s2}s{s1}" 404 assert isinstance(c, unicode), type(c) 405 d = f"s{s1}u{s2}" 406 assert isinstance(d, unicode), type(d) 407 return a, b, c, d 408 409 410def raw_fstring(value): 411 """ 412 >>> print(raw_fstring('abc')) 413 abc\\x61 414 """ 415 return fr'{value}\x61' 416 417 418def format_repr(value): 419 """ 420 >>> a, b = format_repr('abc') 421 >>> print('x{value!r}x'.format(value='abc')) 422 x'abc'x 423 >>> print('x{value!r:6}x'.format(value='abc')) 424 x'abc' x 425 >>> print(a) 426 x'abc'x 427 >>> print(b) 428 x'abc' x 429 """ 430 a = f'x{value!r}x' 431 assert isinstance(a, unicode), type(a) 432 b = f'x{value!r:6}x' 433 assert isinstance(b, unicode), type(b) 434 return a, b 435 436 437def format_str(value): 438 """ 439 >>> a, b = format_str('abc') 440 >>> print('x{value!s}x'.format(value='abc')) 441 xabcx 442 >>> print('x{value!s:6}x'.format(value='abc')) 443 xabc x 444 >>> print(a) 445 xabcx 446 >>> print(b) 447 xabc x 448 """ 449 a = f'x{value!s}x' 450 assert isinstance(a, unicode), type(a) 451 b = f'x{value!s:6}x' 452 assert isinstance(b, unicode), type(b) 453 return a, b 454 455 456@cython.test_fail_if_path_exists( 457 "//FormattedValueNode", # bytes.decode() returns unicode => formatting is useless 458 "//JoinedStrNode", # replaced by call to PyUnicode_Concat() 459 "//PythonCapiCallNode//PythonCapiCallNode", 460) 461def format_decoded_bytes(bytes value): 462 """ 463 >>> print(format_decoded_bytes(b'xyz')) 464 U-xyz 465 """ 466 return f"U-{value.decode('utf-8')}" 467 468 469@cython.test_fail_if_path_exists( 470 "//AddNode", 471 "//ModNode", 472) 473@cython.test_assert_path_exists( 474 "//FormattedValueNode", 475 "//JoinedStrNode", 476) 477def generated_fstring(int i, float f, unicode u not None, o): 478 """ 479 >>> i, f, u, o = 11, 1.3125, u'xyz', [1] 480 >>> print((( 481 ... u"(i) %s-%.3s-%r-%.3r-%d-%3d-%-3d-%o-%04o-%x-%4x-%X-%03X-%.1f-%04.2f %% " 482 ... u"(u) %s-%.2s-%r-%.7r-%05s-%-5s %% " 483 ... u"(o) %s-%.2s-%r-%.2r %% " 484 ... u"(f) %.2f-%d" 485 ... ) % ( 486 ... i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, 487 ... u, u, u, u, u, u, 488 ... o, o, o, o, 489 ... f, f, 490 ... )).replace("-u'xyz'", "-'xyz'")) 491 (i) 11-11-11-11-11- 11-11 -13-0013-b- b-B-00B-11.0-11.00 % (u) xyz-xy-'xyz'-'xyz'- xyz-xyz % (o) [1]-[1-[1]-[1 % (f) 1.31-1 492 493 >>> print(generated_fstring(i, f, u, o).replace("-u'xyz'", "-'xyz'")) 494 (i) 11-11-11-11-11- 11-11 -13-0013-b- b-B-00B-11.0-11.00 % (u) xyz-xy-'xyz'-'xyz'- xyz-xyz % (o) [1]-[1-[1]-[1 % (f) 1.31-1 495 """ 496 return ( 497 u"(i) %s-%.3s-%r-%.3r-%d-%3d-%-3d-%o-%04o-%x-%4x-%X-%03X-%.1f-%04.2f %% " 498 u"(u) %s-%.2s-%r-%.7r-%05s-%-5s %% " 499 u"(o) %s-%.2s-%r-%.2r %% " 500 u"(f) %.2f-%d" 501 ) % ( 502 i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, 503 u, u, u, u, u, u, 504 o, o, o, o, 505 f, f, 506 ) 507 508 509@cython.test_assert_path_exists( 510 "//FormattedValueNode", 511 "//JoinedStrNode", 512) 513def percent_s_unicode(u, int i): 514 u""" 515 >>> u = u'x\u0194z' 516 >>> print(percent_s_unicode(u, 12)) 517 x\u0194z-12 518 """ 519 return u"%s-%d" % (u, i) 520 521 522######################################## 523# await inside f-string 524 525def test_await_inside_f_string(): 526 """ 527 >>> test_await_inside_f_string() 528 PARSED_SUCCESSFULLY 529 """ 530 531 async def f(): 532 return "some value" 533 534 async def main(): 535 print(f"{await f()}") 536 537 print("PARSED_SUCCESSFULLY") 538