|
| 1 | +""" |
| 2 | +Test co_consts behavior for Python 3.14+ |
| 3 | +
|
| 4 | +In Python 3.14+: |
| 5 | +- Functions with docstrings have the docstring as co_consts[0] |
| 6 | +- CO_HAS_DOCSTRING flag (0x4000000) indicates docstring presence |
| 7 | +- Functions without docstrings do NOT have None added as placeholder for docstring |
| 8 | +
|
| 9 | +Note: Other constants (small integers, code objects, etc.) may still appear in co_consts |
| 10 | +depending on optimization level. This test focuses on docstring behavior. |
| 11 | +""" |
| 12 | + |
| 13 | + |
| 14 | +# Test function with docstring - docstring should be co_consts[0] |
| 15 | +def with_doc(): |
| 16 | + """This is a docstring""" |
| 17 | + return 1 |
| 18 | + |
| 19 | + |
| 20 | +assert with_doc.__code__.co_consts[0] == "This is a docstring", ( |
| 21 | + with_doc.__code__.co_consts |
| 22 | +) |
| 23 | +assert with_doc.__doc__ == "This is a docstring" |
| 24 | +# Check CO_HAS_DOCSTRING flag (0x4000000) |
| 25 | +assert with_doc.__code__.co_flags & 0x4000000, hex(with_doc.__code__.co_flags) |
| 26 | + |
| 27 | + |
| 28 | +# Test function without docstring - should NOT have HAS_DOCSTRING flag |
| 29 | +def no_doc(): |
| 30 | + return 1 |
| 31 | + |
| 32 | + |
| 33 | +assert not (no_doc.__code__.co_flags & 0x4000000), hex(no_doc.__code__.co_flags) |
| 34 | +assert no_doc.__doc__ is None |
| 35 | + |
| 36 | + |
| 37 | +# Test async function with docstring |
1 | 38 | from asyncio import sleep |
2 | 39 |
|
3 | 40 |
|
4 | | -def f(): |
5 | | - def g(): |
6 | | - return 1 |
| 41 | +async def async_with_doc(): |
| 42 | + """Async docstring""" |
| 43 | + await sleep(1) |
| 44 | + return 1 |
7 | 45 |
|
8 | | - assert g.__code__.co_consts[0] == None |
9 | | - return 2 |
10 | 46 |
|
| 47 | +assert async_with_doc.__code__.co_consts[0] == "Async docstring", ( |
| 48 | + async_with_doc.__code__.co_consts |
| 49 | +) |
| 50 | +assert async_with_doc.__doc__ == "Async docstring" |
| 51 | +assert async_with_doc.__code__.co_flags & 0x4000000 |
11 | 52 |
|
12 | | -assert f.__code__.co_consts[0] == None |
13 | 53 |
|
| 54 | +# Test async function without docstring |
| 55 | +async def async_no_doc(): |
| 56 | + await sleep(1) |
| 57 | + return 1 |
| 58 | + |
| 59 | + |
| 60 | +assert not (async_no_doc.__code__.co_flags & 0x4000000) |
| 61 | +assert async_no_doc.__doc__ is None |
14 | 62 |
|
15 | | -def generator(): |
| 63 | + |
| 64 | +# Test generator with docstring |
| 65 | +def gen_with_doc(): |
| 66 | + """Generator docstring""" |
16 | 67 | yield 1 |
17 | 68 | yield 2 |
18 | 69 |
|
19 | 70 |
|
20 | | -assert generator().gi_code.co_consts[0] == None |
| 71 | +assert gen_with_doc.__code__.co_consts[0] == "Generator docstring" |
| 72 | +assert gen_with_doc.__doc__ == "Generator docstring" |
| 73 | +assert gen_with_doc.__code__.co_flags & 0x4000000 |
21 | 74 |
|
22 | 75 |
|
23 | | -async def async_f(): |
24 | | - await sleep(1) |
25 | | - return 1 |
| 76 | +# Test generator without docstring |
| 77 | +def gen_no_doc(): |
| 78 | + yield 1 |
| 79 | + yield 2 |
| 80 | + |
26 | 81 |
|
| 82 | +assert not (gen_no_doc.__code__.co_flags & 0x4000000) |
| 83 | +assert gen_no_doc.__doc__ is None |
27 | 84 |
|
28 | | -assert async_f.__code__.co_consts[0] == None |
29 | 85 |
|
| 86 | +# Test lambda - cannot have docstring |
30 | 87 | lambda_f = lambda: 0 |
31 | | -assert lambda_f.__code__.co_consts[0] == None |
| 88 | +assert not (lambda_f.__code__.co_flags & 0x4000000) |
| 89 | +assert lambda_f.__doc__ is None |
| 90 | + |
| 91 | + |
| 92 | +# Test class method with docstring |
| 93 | +class cls_with_doc: |
| 94 | + def method(): |
| 95 | + """Method docstring""" |
| 96 | + return 1 |
| 97 | + |
32 | 98 |
|
| 99 | +assert cls_with_doc.method.__code__.co_consts[0] == "Method docstring" |
| 100 | +assert cls_with_doc.method.__doc__ == "Method docstring" |
33 | 101 |
|
34 | | -class cls: |
35 | | - def f(): |
| 102 | + |
| 103 | +# Test class method without docstring |
| 104 | +class cls_no_doc: |
| 105 | + def method(): |
36 | 106 | return 1 |
37 | 107 |
|
38 | 108 |
|
39 | | -assert cls().f.__code__.co_consts[0] == None |
| 109 | +assert not (cls_no_doc.method.__code__.co_flags & 0x4000000) |
| 110 | +assert cls_no_doc.method.__doc__ is None |
| 111 | + |
| 112 | +print("All co_consts tests passed!") |
0 commit comments