cython

Форк
0
/
fstring.pyx 
633 строки · 14.5 Кб
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

8
cimport cython
9

10
import sys
11
IS_PYPY = hasattr(sys, 'pypy_version_info')
12

13
from libc.limits cimport INT_MAX, LONG_MAX, LONG_MIN
14

15
max_int = INT_MAX
16
max_long = LONG_MAX
17
min_long = LONG_MIN
18

19

20
@cython.test_fail_if_path_exists(
21
    "//JoinedStrNode",
22
)
23
@cython.test_assert_path_exists(
24
    "//AddNode",
25
)
26
def concat_strings(a, b):
27
    """
28
    >>> concat_strings("", "")
29
    x
30
    <BLANKLINE>
31
    x
32
    x
33
    x
34
    xx
35
    >>> concat_strings("a", "")
36
    ax
37
    a
38
    x
39
    ax
40
    ax
41
    axx
42
    >>> concat_strings("", "b")
43
    x
44
    b
45
    xb
46
    xb
47
    xb
48
    xxb
49
    >>> concat_strings("a", "b")
50
    ax
51
    ab
52
    xb
53
    axb
54
    axb
55
    axxb
56
    >>> concat_strings("".join(["a", "b"]), "")  # fresh temp string left
57
    abx
58
    ab
59
    x
60
    abx
61
    abx
62
    abxx
63
    >>> concat_strings("", "".join(["a", "b"]))  # fresh temp string right
64
    x
65
    ab
66
    xab
67
    xab
68
    xab
69
    xxab
70
    """
71
    print(f"{a}x")
72
    print(f"{a}{b}")
73
    print(f"x{b}")
74
    print(f"{a+'x'}{b}")      # fresh temp string left
75
    print(f"{a}{'x'+b}")      # fresh temp string right
76
    print(f"{a+'x'}{'x'+b}")  # fresh temp strings right and left
77

78

79
@cython.test_fail_if_path_exists(
80
    "//FormattedValueNode",
81
    "//JoinedStrNode",
82
    "//AddNode",
83
)
84
def escaping():
85
    """
86
    >>> escaping()
87
    """
88
    assert f'{{{{{"abc"}}}}}{{}}{{' == '{{abc}}{}{'
89
    s = f'{{{{{"abc"}}}}}{{}}{{'
90
    assert s == '{{abc}}{}{', s
91

92
    assert f'\x7b}}' == '{}'
93
    s = f'\x7b}}'
94
    assert s == '{}', s
95

96
    assert f'{"{{}}"}' == '{{}}'
97
    s = f'{"{{}}"}'
98
    assert s == '{{}}', s
99

100

101
@cython.test_fail_if_path_exists(
102
    "//FormattedValueNode",
103
    "//JoinedStrNode",
104
    "//AddNode",
105
)
106
def nested_constant():
107
    """
108
    >>> print(nested_constant())
109
    xyabc123321
110
    """
111
    return f"""{f'''xy{f"abc{123}{'321'}"!s}'''}"""
112

113

114
def format2(ab, cd):
115
    """
116
    >>> a, b, c = format2(1, 2)
117
    >>> print(a)
118
    ab2
119
    >>> print(b)
120
    1cd
121
    >>> print(c)
122
    12
123

124
    >>> a, b, c = format2('ab', 'cd')
125
    >>> print(a)
126
    abcd
127
    >>> print(b)
128
    abcd
129
    >>> print(c)
130
    abcd
131
    """
132
    a = f"ab{cd}"
133
    assert isinstance(a, unicode), type(a)
134
    b = f"{ab}cd"
135
    assert isinstance(b, unicode), type(b)
136
    c = f"{ab}{cd}"
137
    assert isinstance(c, unicode) or (IS_PYPY and isinstance(c, str)), type(c)
138
    return a, b, c
139

140

141
ctypedef enum TestValues:
142
    enum_ABC = 1
143
    enum_XYZ = 2
144

145

146
@cython.test_fail_if_path_exists(
147
    "//CoerceToPyTypeNode",
148
)
149
def format_c_enum():
150
    """
151
    >>> s = format_c_enum()
152
    >>> s == '1-2' or s
153
    True
154
    """
155
    return f"{enum_ABC}-{enum_XYZ}"
156

157

158
def format_c_numbers(signed char c, short s, int n, long l, float f, double d):
159
    """
160
    >>> s1, s2, s3, s4 = format_c_numbers(123, 135, 12, 12312312, 2.3456, 3.1415926)
161
    >>> print(s1)
162
    123 13512312312122.35
163
    >>> print(s2)
164
    3.14 2.3
165
    >>> print(s3)
166
      12f
167
    >>> print(s4)
168
    0C014 3.14
169

170
    >>> s1, s2, s3, s4 = format_c_numbers(-123, -135, -12, -12312312, -2.3456, -3.1415926)
171
    >>> print(s1)
172
    -123-135-12312312-12-2.35
173
    >>> print(s2)
174
    -3.14-2.3
175
    >>> print(s3)
176
     -12f
177
    >>> print(s4)
178
    -C-14-3.14
179

180
    >>> s1, s2, s3, s4 = format_c_numbers(0, 0, 0, 0, -2.3456, -0.1415926)
181
    >>> print(s1)
182
    0   000-2.35
183
    >>> print(s2)
184
    -0.142-2.3
185
    >>> print(s3)
186
       0f
187
    >>> print(s4)
188
    00000-0.142
189

190
    """
191
    s1 = f"{c}{s:4}{l}{n}{f:.3}"
192
    assert isinstance(s1, unicode), type(s1)
193
    s2 = f"{d:.3}{f:4.2}"
194
    assert isinstance(s2, unicode), type(s2)
195
    s3 = f"{n:-4}f"
196
    assert isinstance(s3, unicode), type(s3)
197
    s4 = f"{n:02X}{n:03o}{d:5.3}"
198
    assert isinstance(s4, unicode), type(s4)
199
    return s1, s2, s3, s4
200

201

202
def format_c_numbers_unsigned(unsigned char c, unsigned short s, unsigned int n, unsigned long l):
203
    """
204
    >>> s1, s2, s3 = format_c_numbers_unsigned(123, 135, 12, 12312312)
205
    >>> print(s1)
206
    123 135 5675737012
207
    >>> print(s2)
208
      12f
209
    >>> print(s3)
210
    0C014    bbdef8
211

212
    """
213
    s1 = f"{c}{s:4} {l:o}{n}"
214
    assert isinstance(s1, unicode), type(s1)
215
    s2 = f"{n:-4}f"
216
    assert isinstance(s2, unicode), type(s2)
217
    s3 = f"{n:02X}{n:03o}{l:10x}"
218
    assert isinstance(s3, unicode), type(s3)
219
    return s1, s2, s3
220

221

222
@cython.test_fail_if_path_exists(
223
    "//CoerceToPyTypeNode",
224
)
225
def format_c_numbers_max(int n, long l):
226
    """
227
    >>> n, l = max_int, max_long
228
    >>> s1, s2 = format_c_numbers_max(n, l)
229
    >>> s1 == '{n}:{l}'.format(n=n, l=l) or s1
230
    True
231
    >>> s2 == '{n:012X}:{l:020X}'.format(n=n, l=l) or s2
232
    True
233

234
    >>> n, l = -max_int-1, -max_long-1
235
    >>> s1, s2 = format_c_numbers_max(n, l)
236
    >>> s1 == '{n}:{l}'.format(n=n, l=l) or s1
237
    True
238
    >>> s2 == '{n:012X}:{l:020X}'.format(n=n, l=l) or s2
239
    True
240
    """
241
    s1 = f"{n}:{l}"
242
    assert isinstance(s1, unicode), type(s1)
243
    s2 = f"{n:012X}:{l:020X}"
244
    assert isinstance(s2, unicode), type(s2)
245
    return s1, s2
246

247

248
def format_c_number_const():
249
    """
250
    >>> s = format_c_number_const()
251
    >>> s == '{0}'.format(max_long) or s
252
    True
253
    """
254
    return f"{LONG_MAX}"
255

256

257
@cython.test_fail_if_path_exists(
258
    "//CoerceToPyTypeNode",
259
)
260
def format_c_number_range(int n):
261
    """
262
    >>> for i in range(-1000, 1001):
263
    ...     assert format_c_number_range(i) == str(i)
264
    """
265
    return f'{n}'
266

267

268
@cython.test_fail_if_path_exists(
269
    "//CoerceToPyTypeNode",
270
)
271
def format_c_number_range_width(int n):
272
    """
273
    >>> for i in range(-1000, 1001):
274
    ...     formatted = format_c_number_range_width(i)
275
    ...     expected = '{n:04d}'.format(n=i)
276
    ...     assert formatted == expected, "%r != %r" % (formatted, expected)
277
    """
278
    return f'{n:04}'
279

280

281
def format_c_number_range_width0(int n):
282
    """
283
    >>> for i in range(-100, 101):
284
    ...     formatted = format_c_number_range_width0(i)
285
    ...     expected = '{n:00d}'.format(n=i)
286
    ...     assert formatted == expected, "%r != %r" % (formatted, expected)
287
    """
288
    return f'{n:00}'
289

290

291
@cython.test_fail_if_path_exists(
292
    "//CoerceToPyTypeNode",
293
)
294
def format_c_number_range_width1(int n):
295
    """
296
    >>> for i in range(-100, 101):
297
    ...     formatted = format_c_number_range_width1(i)
298
    ...     expected = '{n:01d}'.format(n=i)
299
    ...     assert formatted == expected, "%r != %r" % (formatted, expected)
300
    """
301
    return f'{n:01}'
302

303

304
@cython.test_fail_if_path_exists(
305
    "//CoerceToPyTypeNode",
306
)
307
def format_c_number_range_width_m4(int n):
308
    """
309
    >>> for i in range(-100, 101):
310
    ...     formatted = format_c_number_range_width_m4(i)
311
    ...     expected = '{n:-4d}'.format(n=i)
312
    ...     assert formatted == expected, "%r != %r" % (formatted, expected)
313
    """
314
    return f'{n:-4}'
315

316

317
def format_c_number_range_dyn_width(int n, int width):
318
    """
319
    >>> for i in range(-1000, 1001):
320
    ...     assert format_c_number_range_dyn_width(i, 0) == str(i), format_c_number_range_dyn_width(i, 0)
321
    ...     assert format_c_number_range_dyn_width(i, 1) == '%01d' % i, format_c_number_range_dyn_width(i, 1)
322
    ...     assert format_c_number_range_dyn_width(i, 4) == '%04d' % i, format_c_number_range_dyn_width(i, 4)
323
    ...     assert format_c_number_range_dyn_width(i, 5) == '%05d' % i, format_c_number_range_dyn_width(i, 5)
324
    ...     assert format_c_number_range_dyn_width(i, 6) == '%06d' % i, format_c_number_range_dyn_width(i, 6)
325
    """
326
    return f'{n:0{width}}'
327

328

329
@cython.test_fail_if_path_exists(
330
    "//CoerceToPyTypeNode",
331
)
332
def format_bool(bint x):
333
    """
334
    >>> a, b, c, d = format_bool(1)
335
    >>> print(a)  # 1
336
    True
337
    >>> print(b)  # 1
338
    True
339
    >>> print(c)  # 1
340
    False
341
    >>> print(d)  # 1
342
    False
343

344
    >>> a, b, c, d = format_bool(2)
345
    >>> print(a)  # 2
346
    True
347
    >>> print(b)  # 2
348
    True
349
    >>> print(c)  # 2
350
    False
351
    >>> print(d)  # 2
352
    False
353

354
    >>> a, b, c, d = format_bool(0)
355
    >>> print(a)  # 3
356
    False
357
    >>> print(b)  # 3
358
    True
359
    >>> print(c)  # 3
360
    False
361
    >>> print(d)  # 3
362
    False
363
    """
364
    return f'{x}', f'{True}', f'{x == 2}', f'{2 > 3}'
365

366

367
def format_c_values(Py_UCS4 uchar, Py_UNICODE pyunicode):
368
    """
369
    >>> s, s1, s2, s3 = format_c_values(b'A'.decode('ascii'), b'X'.decode('ascii'))
370
    >>> print(s)
371
    AXAX
372
    >>> print(s1)
373
    A
374
    >>> print(s2)
375
    X
376
    >>> print(s3)
377
    None
378

379
    """
380
    s = f"{uchar}{pyunicode}{uchar!s}{pyunicode!s}"
381
    assert isinstance(s, unicode), type(s)
382
    s1 = f"{uchar}"
383
    assert isinstance(s1, unicode), type(s1)
384
    s2 = f"{pyunicode}"
385
    assert isinstance(s2, unicode), type(s2)
386
    l = [1, 2, 3]
387
    s3 = f"{l.reverse()}"  # C int return value => 'None'
388
    assert isinstance(s3, unicode), type(s3)
389
    assert l == [3, 2, 1]
390
    return s, s1, s2, s3
391

392

393
xyz_ustring = u'xÄyÖz'
394

395
def format_strings(str s, unicode u):
396
    u"""
397
    >>> a, b, c, d, e, f, g = format_strings('abc', b'xyz'.decode('ascii'))
398
    >>> print(a)
399
    abcxyz
400
    >>> print(b)
401
    xyzabc
402
    >>> print(c)
403
    uxyzsabc
404
    >>> print(d)
405
    sabcuxyz
406
    >>> print(e)
407
    sabcuÄÄuxyz
408
    >>> print(f)
409
    sabcu\N{SNOWMAN}uxyz
410
    >>> print(g)
411
    sabcu\N{OLD PERSIAN SIGN A}uxyz\N{SNOWMAN}
412

413
    >>> a, b, c, d, e, f, g = format_strings('abc', xyz_ustring)
414
    >>> print(a)
415
    abcxÄyÖz
416
    >>> print(b)
417
    xÄyÖzabc
418
    >>> print(c)
419
    uxÄyÖzsabc
420
    >>> print(d)
421
    sabcuxÄyÖz
422
    >>> print(e)
423
    sabcuÄÄuxÄyÖz
424
    >>> print(f)
425
    sabcu\N{SNOWMAN}uxÄyÖz
426
    >>> print(g)
427
    sabcu\N{OLD PERSIAN SIGN A}uxÄyÖz\N{SNOWMAN}
428
    """
429
    a = f"{s}{u}"
430
    assert isinstance(a, unicode), type(a)
431
    b = f"{u}{s}"
432
    assert isinstance(b, unicode), type(b)
433
    c = f"u{u}s{s}"
434
    assert isinstance(c, unicode), type(c)
435
    d = f"s{s}u{u}"
436
    assert isinstance(d, unicode), type(d)
437
    e = f"s{s}uÄÄu{u}"
438
    assert isinstance(e, unicode), type(e)
439
    f = f"s{s}u\N{SNOWMAN}u{u}"
440
    assert isinstance(f, unicode), type(f)
441
    g = f"s{s}u\N{OLD PERSIAN SIGN A}u{u}\N{SNOWMAN}"
442
    assert isinstance(g, unicode), type(g)
443
    return a, b, c, d, e, f, g
444

445

446
def format_pystr(str s1, str s2):
447
    """
448
    >>> a, b, c, d = format_pystr('abc', 'xyz')
449
    >>> print(a)
450
    abcxyz
451
    >>> print(b)
452
    xyzabc
453
    >>> print(c)
454
    uxyzsabc
455
    >>> print(d)
456
    sabcuxyz
457
    """
458
    a = f"{s1}{s2}"
459
    assert isinstance(a, unicode) or (IS_PYPY and isinstance(a, str)), type(a)
460
    b = f"{s2}{s1}"
461
    assert isinstance(b, unicode) or (IS_PYPY and isinstance(a, str)), type(b)
462
    c = f"u{s2}s{s1}"
463
    assert isinstance(c, unicode), type(c)
464
    d = f"s{s1}u{s2}"
465
    assert isinstance(d, unicode), type(d)
466
    return a, b, c, d
467

468

469
def raw_fstring(value):
470
    """
471
    >>> print(raw_fstring('abc'))
472
    abc\\x61
473
    """
474
    return fr'{value}\x61'
475

476

477
def format_repr(value):
478
    """
479
    >>> a, b = format_repr('abc')
480
    >>> print('x{value!r}x'.format(value='abc'))
481
    x'abc'x
482
    >>> print('x{value!r:6}x'.format(value='abc'))
483
    x'abc' x
484
    >>> print(a)
485
    x'abc'x
486
    >>> print(b)
487
    x'abc' x
488
    """
489
    a = f'x{value!r}x'
490
    assert isinstance(a, unicode), type(a)
491
    b = f'x{value!r:6}x'
492
    assert isinstance(b, unicode), type(b)
493
    return a, b
494

495

496
def format_str(value):
497
    """
498
    >>> a, b = format_str('abc')
499
    >>> print('x{value!s}x'.format(value='abc'))
500
    xabcx
501
    >>> print('x{value!s:6}x'.format(value='abc'))
502
    xabc   x
503
    >>> print(a)
504
    xabcx
505
    >>> print(b)
506
    xabc   x
507
    """
508
    a = f'x{value!s}x'
509
    assert isinstance(a, unicode), type(a)
510
    b = f'x{value!s:6}x'
511
    assert isinstance(b, unicode), type(b)
512
    return a, b
513

514

515
@cython.test_fail_if_path_exists(
516
    "//FormattedValueNode",  # bytes.decode() returns unicode => formatting is useless
517
    "//JoinedStrNode",       # replaced by call to PyUnicode_Concat()
518
    "//PythonCapiCallNode//PythonCapiCallNode",
519
)
520
def format_decoded_bytes(bytes value):
521
    """
522
    >>> print(format_decoded_bytes(b'xyz'))
523
    U-xyz
524
    """
525
    return f"U-{value.decode('utf-8')}"
526

527

528
@cython.test_fail_if_path_exists(
529
    "//CoerceToPyTypeNode",
530
)
531
def format_uchar(int x):
532
    """
533
    >>> format_uchar(0)
534
    ('\\x00', '           \\x00', '       \\x00')
535
    >>> format_uchar(13)
536
    ('\\r', '           \\r', '       \\r')
537
    >>> format_uchar(1114111 + 1)
538
    Traceback (most recent call last):
539
    OverflowError: %c arg not in range(0x110000)
540
    """
541
    return f"{x:c}", f"{x:12c}", f"{x:>8c}"
542

543

544
@cython.test_fail_if_path_exists(
545
    "//AddNode",
546
    "//ModNode",
547
)
548
@cython.test_assert_path_exists(
549
    "//FormattedValueNode",
550
    "//JoinedStrNode",
551
)
552
def generated_fstring(int i, float f, unicode u not None, o):
553
    """
554
    >>> i, f, u, o = 11, 1.3125, u'xyz', [1]
555
    >>> print(((
556
    ...     u"(i) %s-%.3s-%r-%.3r-%d-%3d-%-3d-%o-%04o-%x-%4x-%X-%03X-%.1f-%04.2f %% "
557
    ...     u"(u) %s-%.2s-%r-%.7r-%05s-%-5s %% "
558
    ...     u"(o) %s-%.2s-%r-%.2r %% "
559
    ...     u"(f) %.2f-%d"
560
    ... ) % (
561
    ...     i, i, i, i, i, i, i, i, i, i, i, i, i, i, i,
562
    ...     u, u, u, u, u, u,
563
    ...     o, o, o, o,
564
    ...     f, f,
565
    ... )).replace("-u'xyz'", "-'xyz'"))
566
    (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
567

568
    >>> print(generated_fstring(i, f, u, o).replace("-u'xyz'", "-'xyz'"))
569
    (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
570
    """
571
    return (
572
        u"(i) %s-%.3s-%r-%.3r-%d-%3d-%-3d-%o-%04o-%x-%4x-%X-%03X-%.1f-%04.2f %% "
573
        u"(u) %s-%.2s-%r-%.7r-%05s-%-5s %% "
574
        u"(o) %s-%.2s-%r-%.2r %% "
575
        u"(f) %.2f-%d"
576
    ) % (
577
        i, i, i, i, i, i, i, i, i, i, i, i, i, i, i,
578
        u, u, u, u, u, u,
579
        o, o, o, o,
580
        f, f,
581
    )
582

583

584
@cython.test_assert_path_exists(
585
    "//FormattedValueNode",
586
    "//JoinedStrNode",
587
)
588
def percent_s_unicode(u, int i):
589
    u"""
590
    >>> u = u'x\\u0194z'
591
    >>> print(percent_s_unicode(u, 12))
592
    x\\u0194z-12
593
    """
594
    return u"%s-%d" % (u, i)
595

596

597
@cython.test_assert_path_exists(
598
    "//FormattedValueNode",
599
)
600
def sideeffect(l):
601
    """
602
    >>> class Listish(list):
603
    ...     def __format__(self, format_spec):
604
    ...         self.append("format called")
605
    ...         return repr(self)
606
    ...     def append(self, item):
607
    ...         list.append(self, item)
608
    ...         return self
609

610
    >>> l = Listish()
611
    >>> sideeffect(l)  if getattr(sys, 'pypy_version_info', ())[:2] != (7,3) else [123, 'format called']   # 7.3.4, 7.3.5
612
    [123, 'format called']
613
    """
614
    f"{l.append(123)}"  # unused f-string !
615
    return list(l)
616

617

618
########################################
619
# await inside f-string
620

621
def test_await_inside_f_string():
622
    """
623
    >>> test_await_inside_f_string()
624
    PARSED_SUCCESSFULLY
625
    """
626

627
    async def f():
628
        return "some value"
629

630
    async def main():
631
        print(f"{await f()}")
632

633
    print("PARSED_SUCCESSFULLY")
634

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.