Python: Copy Python extractor to codeql repo

This commit is contained in:
Taus
2024-02-28 15:15:21 +00:00
parent 297a17975d
commit 6dec323cfc
369 changed files with 165346 additions and 0 deletions

View File

@@ -0,0 +1 @@
(0, [1, (2, [3, (4, [5, 6])])])

View File

@@ -0,0 +1,17 @@
#foo[bar].baz[(quux := 5)] = 5
foo = 5
baz, quux = 1, 2
blah : int = 5
just_the_type : float
x, y = z, w = 3, 4
(a, (b, (c, (d, e)))) = (j, (k, (l, (m, n))))
s, *t = u
o,p, = q,r,

View File

@@ -0,0 +1,11 @@
foo(x,y,z=1,w=2)
bar()()()
baz(2+2, kw = 3*4)
a(*b, **c)
d(e,)
f(g.h[i])

View File

@@ -0,0 +1,2 @@
class Foo(int, object, metaclass=type):
x = 5

View File

@@ -0,0 +1,37 @@
()
[]
{}
[1,2,3]
(4,5,6)
{7: 8, 9: 10, 11: 12}
{13, 14, 15}
a = {x:y}
b = {z:w, **a}
c = [k,l,*m]
(o,)
(p,q,r,)
s,
t, u,
(#comment
v, w
#comment
)
(#comment
x, y,
#comment
)

View File

@@ -0,0 +1,15 @@
"""
At the time this test was added, when either comment 2 or comment 3 was present, this
would cause the TSG parser to have an error.
"""
# comment 0
print(
# comment 1
(
# comment 2
1
# comment 3
)
# comment 4
)

View File

@@ -0,0 +1,57 @@
(a
for b in c
if d
if e
for f in g
if h
if i
)
(a1 for b1 in c1)
(a2 for b2 in c2 if d2)
[k
for l in m
if n
if o
for p in q
if r
if s
]
[k1 for l1 in m1]
[k2 for l2 in m2 if n2]
{p
for q in r
if s
if t
for u in v
if w
if x
}
{p1 for q1 in r1}
{p2 for q2 in r2 if s2}
{k3: v3
for l3 in m3
if n3
if o3
for p3 in q3
if r3
if s3
}
{k4: v4 for l4 in m4}
{k5: v5 for l5 in m5 if n5}
# Special case for generator expressions inside calls
t = tuple(x for y in z)
[( t, ) for v in w]

View File

View File

@@ -0,0 +1,136 @@
Module: [1, 0] - [22, 0]
body: [
Try: [1, 0] - [1, 4]
body: [
Expr: [2, 4] - [2, 5]
value:
Name: [2, 4] - [2, 5]
variable: Variable('a', None)
ctx: Load
Expr: [3, 4] - [3, 5]
value:
Name: [3, 4] - [3, 5]
variable: Variable('b', None)
ctx: Load
]
orelse: [
Expr: [17, 4] - [17, 5]
value:
Name: [17, 4] - [17, 5]
variable: Variable('s', None)
ctx: Load
Expr: [18, 4] - [18, 5]
value:
Name: [18, 4] - [18, 5]
variable: Variable('t', None)
ctx: Load
]
handlers: [
ExceptGroupStmt: [4, 0] - [6, 5]
type:
Name: [4, 8] - [4, 9]
variable: Variable('c', None)
ctx: Load
name: None
body: [
Expr: [5, 4] - [5, 5]
value:
Name: [5, 4] - [5, 5]
variable: Variable('d', None)
ctx: Load
Expr: [6, 4] - [6, 5]
value:
Name: [6, 4] - [6, 5]
variable: Variable('e', None)
ctx: Load
]
ExceptGroupStmt: [7, 0] - [9, 5]
type:
Name: [7, 8] - [7, 9]
variable: Variable('f', None)
ctx: Load
name:
Name: [7, 13] - [7, 14]
variable: Variable('g', None)
ctx: Store
body: [
Expr: [8, 4] - [8, 5]
value:
Name: [8, 4] - [8, 5]
variable: Variable('h', None)
ctx: Load
Expr: [9, 4] - [9, 5]
value:
Name: [9, 4] - [9, 5]
variable: Variable('i', None)
ctx: Load
]
ExceptGroupStmt: [10, 0] - [12, 5]
type:
Tuple: [10, 9] - [10, 13]
elts: [
Name: [10, 9] - [10, 10]
variable: Variable('j', None)
ctx: Load
Name: [10, 12] - [10, 13]
variable: Variable('k', None)
ctx: Load
]
ctx: Load
parenthesised: True
name: None
body: [
Expr: [11, 4] - [11, 5]
value:
Name: [11, 4] - [11, 5]
variable: Variable('l', None)
ctx: Load
Expr: [12, 4] - [12, 5]
value:
Name: [12, 4] - [12, 5]
variable: Variable('m', None)
ctx: Load
]
ExceptGroupStmt: [13, 0] - [15, 5]
type:
Tuple: [13, 9] - [13, 13]
elts: [
Name: [13, 9] - [13, 10]
variable: Variable('n', None)
ctx: Load
Name: [13, 12] - [13, 13]
variable: Variable('o', None)
ctx: Load
]
ctx: Load
parenthesised: True
name:
Name: [13, 18] - [13, 19]
variable: Variable('p', None)
ctx: Store
body: [
Expr: [14, 4] - [14, 5]
value:
Name: [14, 4] - [14, 5]
variable: Variable('q', None)
ctx: Load
Expr: [15, 4] - [15, 5]
value:
Name: [15, 4] - [15, 5]
variable: Variable('r', None)
ctx: Load
]
]
finalbody: [
Expr: [20, 4] - [20, 5]
value:
Name: [20, 4] - [20, 5]
variable: Variable('u', None)
ctx: Load
Expr: [21, 4] - [21, 5]
value:
Name: [21, 4] - [21, 5]
variable: Variable('v', None)
ctx: Load
]
]

View File

@@ -0,0 +1,21 @@
try:
a
b
except* c:
d
e
except* f as g:
h
i
except* (j, k):
l
m
except* (n, o) as p:
q
r
else:
s
t
finally:
u
v

View File

@@ -0,0 +1,18 @@
try:
a
b
except c as d:
e
f
except g:
h
i
except:
j
k
else:
l
m
finally:
n
o

View File

@@ -0,0 +1,14 @@
1
2 + 3
4 * 5 / 6
(7 + 8) * 9
(10, 11)
( 12, 13 )
14 , 15
(match := 16)

View File

@@ -0,0 +1,15 @@
async for x in y:
if z: continue
if w: break
else:
v
for ham in eggs:
spam
for (a,b) in c:
pass
for d, *e in f:
pass

View File

@@ -0,0 +1,58 @@
def a(b): pass
def c(*d): pass
def foo(a, b, c=d, e:f, g:h=i, *j) -> t:
x
y
def foo(l):
pass
def bar(*k):
x1
y1
def bar(*k, l, m:n, o:p=q, r=s, **u):
x1
y1
def klef(*): pass
def main(): pass
@dec1(a,b)
@dec2(c,d)
def func(e,f,g):
h
i
lambda: a
lambda b: c
lambda d, *e: f
lambda *g, h: i
lambda j=k: l
lambda *m: n
lambda **o: p
lambda *p, q=r: s
def typed_dictionary_splat(**kw : KEYWORD):
pass
def typed_list_splat(*args : ARGS):
pass
@False or True
def decorated(): pass
def all_separators(pos_only, /, pos_or_keyword, *, keyword_only): pass
@decorator #comment
def decorated_with_comment():
pass

View File

@@ -0,0 +1,11 @@
if x: do_x
elif y: do_y
elif z: do_z
else: do_else
if a and b:
c
# comment
elif d or e:
f

View File

@@ -0,0 +1,8 @@
# This is a comment
# it goes on for many lines...
# (Well, okay. Three lines.)
# Here's one that's separated with some whitespace.
# More whitespace at the end.

View File

@@ -0,0 +1,3 @@

View File

@@ -0,0 +1,382 @@
Module: [1, 0] - [43, 0]
body: [
Match: [1, 0] - [3, 19]
subject:
List: [1, 6] - [1, 11]
elts: [
Num: [1, 7] - [1, 8]
n: 1
text: '1'
Num: [1, 9] - [1, 10]
n: 2
text: '2'
]
ctx: Load
cases: [
Case: [2, 4] - [3, 19]
pattern:
MatchSequencePattern: [2, 9] - [2, 15]
patterns: [
MatchCapturePattern: [2, 10] - [2, 11]
variable:
Name: [2, 10] - [2, 11]
variable: Variable('a', None)
ctx: Store
MatchCapturePattern: [2, 13] - [2, 14]
variable:
Name: [2, 13] - [2, 14]
variable: Variable('b', None)
ctx: Store
]
guard: None
body: [
Expr: [3, 8] - [3, 19]
value:
Call: [3, 8] - [3, 19]
func:
Name: [3, 8] - [3, 13]
variable: Variable('print', None)
ctx: Load
positional_args: [
Name: [3, 14] - [3, 15]
variable: Variable('b', None)
ctx: Load
Name: [3, 17] - [3, 18]
variable: Variable('a', None)
ctx: Load
]
named_args: []
]
]
Match: [5, 0] - [15, 12]
subject:
BinOp: [5, 6] - [5, 10]
left:
Num: [5, 6] - [5, 7]
n: 1
text: '1'
op: Add
right:
Num: [5, 8] - [5, 10]
n: 2j
text: '2j'
cases: [
Case: [6, 4] - [7, 12]
pattern:
MatchLiteralPattern: [6, 9] - [6, 13]
literal:
BinOp: [6, 9] - [6, 13]
left:
Num: [6, 9] - [6, 10]
n: 1
text: '1'
op: Add
right:
Num: [6, 11] - [6, 13]
n: 2j
text: '2j'
guard: None
body: [
Pass: [7, 8] - [7, 12]
]
Case: [8, 4] - [9, 12]
pattern:
MatchLiteralPattern: [8, 9] - [8, 18]
literal:
BinOp: [8, 9] - [8, 18]
left:
UnaryOp: [8, 10] - [8, 11]
op: USub
operand:
Num: [8, 10] - [8, 11]
n: 1
text: '1'
op: Sub
right:
Num: [8, 12] - [8, 18]
n: 26000000j
text: '2.6e7j'
guard: None
body: [
Pass: [9, 8] - [9, 12]
]
Case: [10, 4] - [11, 12]
pattern:
MatchLiteralPattern: [10, 9] - [10, 11]
literal:
UnaryOp: [10, 10] - [10, 11]
op: USub
operand:
Num: [10, 10] - [10, 11]
n: 1
text: '1'
guard: None
body: [
Pass: [11, 8] - [11, 12]
]
Case: [12, 4] - [13, 12]
pattern:
MatchLiteralPattern: [12, 9] - [12, 10]
literal:
Num: [12, 9] - [12, 10]
n: 2
text: '2'
guard: None
body: [
Pass: [13, 8] - [13, 12]
]
Case: [14, 4] - [15, 12]
pattern:
MatchLiteralPattern: [14, 9] - [14, 16]
literal:
BinOp: [14, 9] - [14, 16]
left:
UnaryOp: [14, 10] - [14, 13]
op: USub
operand:
Num: [14, 10] - [14, 13]
n: 1.5
text: '1.5'
op: Add
right:
Num: [14, 14] - [14, 16]
n: 5j
text: '5j'
guard: None
body: [
Pass: [15, 8] - [15, 12]
]
]
Assign: [17, 0] - [17, 20]
targets: [
Name: [17, 4] - [17, 17]
variable: Variable('soft_keywords', None)
ctx: Store
]
value:
FunctionExpr: [17, 0] - [17, 20]
name: 'soft_keywords'
args:
arguments
defaults: []
kw_defaults: []
annotations: []
varargannotation: None
kwargannotation: None
kw_annotations: []
returns: None
inner_scope:
Function: [17, 0] - [17, 20]
name: 'soft_keywords'
type_parameters: []
args: []
vararg: None
kwonlyargs: []
kwarg: None
body: [
Assign: [18, 4] - [18, 13]
targets: [
Name: [18, 4] - [18, 9]
variable: Variable('match', None)
ctx: Store
]
value:
Num: [18, 12] - [18, 13]
n: 0
text: '0'
Assign: [19, 4] - [19, 12]
targets: [
Name: [19, 4] - [19, 8]
variable: Variable('case', None)
ctx: Store
]
value:
Num: [19, 11] - [19, 12]
n: 0
text: '0'
Match: [20, 4] - [22, 17]
subject:
Name: [20, 10] - [20, 15]
variable: Variable('match', None)
ctx: Load
cases: [
Case: [21, 8] - [22, 17]
pattern:
MatchCapturePattern: [21, 13] - [21, 17]
variable:
Name: [21, 13] - [21, 17]
variable: Variable('case', None)
ctx: Store
guard: None
body: [
Assign: [22, 12] - [22, 17]
targets: [
Name: [22, 12] - [22, 13]
variable: Variable('x', None)
ctx: Store
]
value:
Num: [22, 16] - [22, 17]
n: 0
text: '0'
]
]
]
Match: [24, 0] - [26, 12]
subject:
Tuple: [24, 7] - [24, 10]
elts: [
Num: [24, 7] - [24, 8]
n: 0
text: '0'
Num: [24, 9] - [24, 10]
n: 1
text: '1'
]
ctx: Load
parenthesised: True
cases: [
Case: [25, 4] - [26, 12]
pattern:
MatchSequencePattern: [25, 9] - [25, 12]
patterns: [
MatchStarPattern: [25, 9] - [25, 11]
target:
MatchCapturePattern: [25, 10] - [25, 11]
variable:
Name: [25, 10] - [25, 11]
variable: Variable('x', None)
ctx: Store
]
guard: None
body: [
Pass: [26, 8] - [26, 12]
]
]
Match: [28, 0] - [30, 12]
subject:
Tuple: [28, 7] - [28, 10]
elts: [
Num: [28, 7] - [28, 8]
n: 2
text: '2'
Num: [28, 9] - [28, 10]
n: 3
text: '3'
]
ctx: Load
parenthesised: True
cases: [
Case: [29, 4] - [30, 12]
pattern:
MatchSequencePattern: [29, 9] - [29, 14]
patterns: [
MatchStarPattern: [29, 10] - [29, 12]
target:
MatchCapturePattern: [29, 11] - [29, 12]
variable:
Name: [29, 11] - [29, 12]
variable: Variable('x', None)
ctx: Store
]
guard: None
body: [
Pass: [30, 8] - [30, 12]
]
]
Match: [32, 0] - [34, 13]
subject:
Tuple: [32, 6] - [32, 10]
elts: [
Name: [32, 6] - [32, 7]
variable: Variable('w', None)
ctx: Load
Name: [32, 9] - [32, 10]
variable: Variable('x', None)
ctx: Load
]
ctx: Load
parenthesised: True
cases: [
Case: [33, 4] - [34, 13]
pattern:
MatchSequencePattern: [33, 9] - [33, 13]
patterns: [
MatchCapturePattern: [33, 9] - [33, 10]
variable:
Name: [33, 9] - [33, 10]
variable: Variable('y', None)
ctx: Store
MatchCapturePattern: [33, 12] - [33, 13]
variable:
Name: [33, 12] - [33, 13]
variable: Variable('z', None)
ctx: Store
]
guard: None
body: [
Assign: [34, 8] - [34, 13]
targets: [
Name: [34, 8] - [34, 9]
variable: Variable('v', None)
ctx: Store
]
value:
Num: [34, 12] - [34, 13]
n: 0
text: '0'
]
]
Match: [36, 0] - [38, 12]
subject:
Tuple: [36, 6] - [36, 10]
elts: [
Name: [36, 6] - [36, 7]
variable: Variable('x', None)
ctx: Load
Name: [36, 9] - [36, 10]
variable: Variable('y', None)
ctx: Load
]
ctx: Load
parenthesised: True
cases: [
Case: [37, 4] - [38, 12]
pattern:
MatchSequencePattern: [37, 9] - [37, 13]
patterns: [
MatchLiteralPattern: [37, 9] - [37, 10]
literal:
Num: [37, 9] - [37, 10]
n: 1
text: '1'
MatchLiteralPattern: [37, 12] - [37, 13]
literal:
Num: [37, 12] - [37, 13]
n: 2
text: '2'
]
guard: None
body: [
Pass: [38, 8] - [38, 12]
]
]
Match: [40, 0] - [42, 12]
subject:
Name: [40, 6] - [40, 7]
variable: Variable('z', None)
ctx: Load
cases: [
Case: [41, 4] - [42, 12]
pattern:
MatchCapturePattern: [41, 9] - [41, 10]
variable:
Name: [41, 9] - [41, 10]
variable: Variable('w', None)
ctx: Store
guard: None
body: [
Pass: [42, 8] - [42, 12]
]
]
]

View File

@@ -0,0 +1,42 @@
match [1,2]:
case (a, b):
print(b, a)
match 1+2j:
case 1+2j:
pass
case -1-2.6e7j:
pass
case -1:
pass
case 2:
pass
case -1.5+5j:
pass
def soft_keywords():
match = 0
case = 0
match match:
case case:
x = 0
match (0,1):
case *x,:
pass
match (2,3):
case (*x,):
pass
match w, x:
case y, z:
v = 0
match x, y:
case 1, 2:
pass
match z:
case w:
pass

View File

@@ -0,0 +1,15 @@
...
a = (b := c)
d = e if f else g
h1[h2] = h3[h4]
i[i1:i2]
j[j1:j2:j3]
k.l = m.n
o[p,q]

View File

@@ -0,0 +1,12 @@
1
2.0
3j
0x4
0o5
0b110

View File

@@ -0,0 +1,54 @@
1 and 2
3 or 4
5 == 6
7 > 8
9 >= 10
11 in 12
13 is 14
15 is not 16
17 < 18
19 <= 20
21 != 22
23 <> 24
25 not in 26
27 > 28 >= 29 < 30 <= 31 == 32 != 33 <> 34
+35
-36
~37
not 38
# or(not(a), b)
not a or b
# and(c, d, e, f, g)
c and d and e and f and g
# or(h, i, j, k, l)
h or i or j or k or l
# or(and(m, n), and(o, p))
m and n or o and p
# or(q, and(s, t), u)
q or s and t or u
a1 or b1 and c1
d1 and e1 or f1

View File

@@ -0,0 +1,70 @@
# Statements that do not contain any other statements.
pass
a = b
c : int = 1
d += e
del f
del f1, f2
global h
global h1, h2
nonlocal i
nonlocal i1, i2
import j
import j1, j2
import j3.j4.j5, j6.j7.j8 as j9
import j10.j11 as j12
from k import l
from ..k1.k2 import l1 as l2, l3
from __future__ import print_function, goto_statement
from . import l4
from l5 import *
from ..l6 import *
from ... import *
raise
raise m
raise m1 from m2
raise m3, m4
raise m5, m6, m7
assert n
assert n1, n2
return o
return *o1,
return 1, *o2
return 2, *o3,
yield p
yield from q
await r

View File

@@ -0,0 +1,8 @@
exec "ls"
print "Hello"
print "two parts", "no newline",
print >> f, "World"

View File

@@ -0,0 +1,79 @@
if 1:
"double quotes"
if 2:
'single quotes'
if 3:
"""triple double quotes (sextuple quotes?)"""
if 4:
'''triple single quotes'''
if 5:
r"raw string"
if 6:
b"byte string"
if 7:
u"unicode string"
if 8:
br"raw byte string"
if 9:
"Let's put some control\tcharacters in here\n"
if 10:
"""
Multiline
string
time
"""
if 11:
"escaped \"quotes\" here"
if 12:
"""Unescaped "quotes" inside triple quotes"""
if 13:
"string" """concatenation""" 'here' '''oh yeah'''
if 14:
f"format string with no funny business"
if 15:
f"format string with {1} interpolation"
if 16:
f"{2}{3}{4}"
if 17:
f"and a format string with {'nested'} string"
if 18:
f"foo{x}bar" "regular string"
if 19:
pass
# This doesn't quite give the right result, but it's close enough.
#f"no interpolation" ' but still implicit concatenation'
if 20:
f"{9}" "blah" f'{10}'
if 21:
f"format{129}string" "not format"
if 21.1:
# regression from https://github.com/github/codeql/issues/9940
f"format{123}string" f"technically format string\n"
if 22:
"again not format" f"format again{foo}hello"
if 23:
f"""f-string with {"inner " 'implicit ' '''concatenation'''} how awful"""
if 24:
f'''oh no python { f'why do you {"allow"} such'} absolute horrors?'''
if 25:
b"""5""" b"byte format"
if 26:
r'X(\u0061|a)*Y'
if 27:
f"""triple-quoted {11}""f-st""" fr"""ri'''ng\\\\\""{12} with an inner quoted part"""
if 28:
f'{value:{width + padding!r}.{precision}}'
if 29:
f'{1,}'
if 30:
fr"""quotes before interpolation "{123}" are okay."""
if 31:
fr"""backslash before an interpolation \{456}\ are okay."""
if 32:
f''
if 33:
''
if 34:
b'\xc5\xe5'
if 35:
f"{x=}"

View File

@@ -0,0 +1,305 @@
Module: [2, 0] - [22, 0]
body: [
Assign: [2, 0] - [2, 60]
targets: [
Name: [2, 0] - [2, 5]
variable: Variable('songs', None)
ctx: Store
]
value:
List: [2, 8] - [2, 60]
elts: [
Str: [2, 9] - [2, 31]
s: 'Take me back to Eden'
prefix: "'"
implicitly_concatenated_parts: None
Str: [2, 33] - [2, 43]
s: 'Alkaline'
prefix: "'"
implicitly_concatenated_parts: None
Str: [2, 45] - [2, 59]
s: 'Ascensionism'
prefix: "'"
implicitly_concatenated_parts: None
]
ctx: Load
Expr: [3, 0] - [3, 43]
value:
JoinedStr: [3, 0] - [3, 43]
values: [
Str: [3, 0] - [3, 25]
s: 'This is the playlist: '
prefix: 'f"'
implicitly_concatenated_parts: None
Call: [3, 25] - [3, 41]
func:
Attribute: [3, 25] - [3, 34]
value:
Str: [3, 25] - [3, 29]
s: ', '
prefix: '"'
implicitly_concatenated_parts: None
attr: 'join'
ctx: Load
positional_args: [
Name: [3, 35] - [3, 40]
variable: Variable('songs', None)
ctx: Load
]
named_args: []
Str: [3, 41] - [3, 43]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
Expr: [6, 0] - [6, 31]
value:
JoinedStr: [6, 0] - [6, 31]
values: [
Str: [6, 0] - [6, 5]
s: ''
prefix: 'f"""'
implicitly_concatenated_parts: None
JoinedStr: [6, 5] - [6, 27]
values: [
Str: [6, 5] - [6, 10]
s: ''
prefix: "f'''"
implicitly_concatenated_parts: None
JoinedStr: [6, 10] - [6, 23]
values: [
Str: [6, 10] - [6, 13]
s: ''
prefix: "f'"
implicitly_concatenated_parts: None
JoinedStr: [6, 13] - [6, 21]
values: [
Str: [6, 13] - [6, 16]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
BinOp: [6, 16] - [6, 19]
left:
Num: [6, 16] - [6, 17]
n: 1
text: '1'
op: Add
right:
Num: [6, 18] - [6, 19]
n: 1
text: '1'
Str: [6, 19] - [6, 21]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
Str: [6, 21] - [6, 23]
s: ''
prefix: "f'"
implicitly_concatenated_parts: None
]
Str: [6, 23] - [6, 27]
s: ''
prefix: "f'''"
implicitly_concatenated_parts: None
]
Str: [6, 27] - [6, 31]
s: ''
prefix: 'f"""'
implicitly_concatenated_parts: None
]
Expr: [9, 0] - [9, 33]
value:
JoinedStr: [9, 0] - [9, 33]
values: [
Str: [9, 0] - [9, 3]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
JoinedStr: [9, 3] - [9, 31]
values: [
Str: [9, 3] - [9, 6]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
JoinedStr: [9, 6] - [9, 29]
values: [
Str: [9, 6] - [9, 9]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
JoinedStr: [9, 9] - [9, 27]
values: [
Str: [9, 9] - [9, 12]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
JoinedStr: [9, 12] - [9, 25]
values: [
Str: [9, 12] - [9, 15]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
JoinedStr: [9, 15] - [9, 23]
values: [
Str: [9, 15] - [9, 18]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
BinOp: [9, 18] - [9, 21]
left:
Num: [9, 18] - [9, 19]
n: 1
text: '1'
op: Add
right:
Num: [9, 20] - [9, 21]
n: 1
text: '1'
Str: [9, 21] - [9, 23]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
Str: [9, 23] - [9, 25]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
Str: [9, 25] - [9, 27]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
Str: [9, 27] - [9, 29]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
Str: [9, 29] - [9, 31]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
Str: [9, 31] - [9, 33]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
Expr: [12, 0] - [16, 4]
value:
JoinedStr: [12, 0] - [16, 4]
values: [
Str: [12, 0] - [12, 25]
s: 'This is the playlist: '
prefix: 'f"'
implicitly_concatenated_parts: None
Call: [12, 25] - [16, 2]
func:
Attribute: [12, 25] - [12, 34]
value:
Str: [12, 25] - [12, 29]
s: ', '
prefix: '"'
implicitly_concatenated_parts: None
attr: 'join'
ctx: Load
positional_args: [
List: [12, 35] - [16, 1]
elts: [
Str: [13, 4] - [13, 26]
s: 'Take me back to Eden'
prefix: "'"
implicitly_concatenated_parts: None
Str: [14, 4] - [14, 14]
s: 'Alkaline'
prefix: "'"
implicitly_concatenated_parts: None
Str: [15, 4] - [15, 18]
s: 'Ascensionism'
prefix: "'"
implicitly_concatenated_parts: None
]
ctx: Load
]
named_args: []
Str: [16, 2] - [16, 4]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
Expr: [19, 0] - [19, 50]
value:
Call: [19, 0] - [19, 50]
func:
Name: [19, 0] - [19, 5]
variable: Variable('print', None)
ctx: Load
positional_args: [
JoinedStr: [19, 6] - [19, 49]
values: [
Str: [19, 6] - [19, 31]
s: 'This is the playlist: '
prefix: 'f"'
implicitly_concatenated_parts: None
Call: [19, 31] - [19, 47]
func:
Attribute: [19, 31] - [19, 40]
value:
Str: [19, 31] - [19, 35]
s: '\n'
prefix: '"'
implicitly_concatenated_parts: None
attr: 'join'
ctx: Load
positional_args: [
Name: [19, 41] - [19, 46]
variable: Variable('songs', None)
ctx: Load
]
named_args: []
Str: [19, 47] - [19, 49]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
]
named_args: []
Expr: [21, 0] - [21, 68]
value:
Call: [21, 0] - [21, 68]
func:
Name: [21, 0] - [21, 5]
variable: Variable('print', None)
ctx: Load
positional_args: [
JoinedStr: [21, 6] - [21, 67]
values: [
Str: [21, 6] - [21, 31]
s: 'This is the playlist: '
prefix: 'f"'
implicitly_concatenated_parts: None
Call: [21, 31] - [21, 65]
func:
Attribute: [21, 31] - [21, 58]
value:
Str: [21, 31] - [21, 53]
s: '♥'
prefix: '"'
implicitly_concatenated_parts: None
attr: 'join'
ctx: Load
positional_args: [
Name: [21, 59] - [21, 64]
variable: Variable('songs', None)
ctx: Load
]
named_args: []
Str: [21, 65] - [21, 67]
s: ''
prefix: 'f"'
implicitly_concatenated_parts: None
]
]
named_args: []
]

View File

@@ -0,0 +1,21 @@
# An expression containing the same kind of quotes as the outer f-string
songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism']
f"This is the playlist: {", ".join(songs)}"
# An example of the previously maximal level of nesting
f"""{f'''{f'{f"{1+1}"}'}'''}"""
# An example of the new, unlimited level of nesting
f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"
# An f-string with newlines inside the expression part
f"This is the playlist: {", ".join([
'Take me back to Eden', # My, my, those eyes like fire
'Alkaline', # Not acid nor alkaline
'Ascensionism' # Take to the broken skies at last
])}"
# Two instances of string escaping used inside the expression part
print(f"This is the playlist: {"\n".join(songs)}")
print(f"This is the playlist: {"\N{BLACK HEART SUIT}".join(songs)}")

View File

@@ -0,0 +1,265 @@
Module: [1, 0] - [31, 0]
body: [
If: [1, 0] - [1, 5]
test:
Num: [1, 3] - [1, 4]
n: 1
text: '1'
body: [
Expr: [2, 4] - [2, 72]
value:
JoinedStr: [2, 4] - [2, 72]
values: [
Str: [2, 4] - [2, 61]
s: 'this is not a unicode escape but an interpolation: \\N'
prefix: 'fr"'
implicitly_concatenated_parts: None
Name: [2, 61] - [2, 70]
variable: Variable('AMPERSAND', None)
ctx: Load
Str: [2, 70] - [2, 72]
s: ''
prefix: 'fr"'
implicitly_concatenated_parts: None
]
]
orelse: None
If: [3, 0] - [3, 5]
test:
Num: [3, 3] - [3, 4]
n: 2
text: '2'
body: [
Expr: [4, 4] - [4, 44]
value:
JoinedStr: [4, 4] - [4, 44]
values: [
Str: [4, 4] - [4, 33]
s: 'also an interpolation: \\N'
prefix: "f'"
implicitly_concatenated_parts: None
Name: [4, 33] - [4, 42]
variable: Variable('AMPERSAND', None)
ctx: Load
Str: [4, 42] - [4, 44]
s: ''
prefix: "f'"
implicitly_concatenated_parts: None
]
]
orelse: None
If: [5, 0] - [5, 5]
test:
Num: [5, 3] - [5, 4]
n: 3
text: '3'
body: [
Expr: [6, 4] - [6, 14]
value:
Str: [6, 4] - [6, 14]
s: '\\Nspam'
prefix: "f'"
implicitly_concatenated_parts: None
]
orelse: None
If: [7, 0] - [7, 5]
test:
Num: [7, 3] - [7, 4]
n: 4
text: '4'
body: [
Expr: [8, 4] - [8, 46]
value:
Str: [8, 4] - [8, 46]
s: 'this is a unicode escape: &'
prefix: 'f"'
implicitly_concatenated_parts: None
]
orelse: None
If: [9, 0] - [9, 5]
test:
Num: [9, 3] - [9, 4]
n: 5
text: '5'
body: [
Expr: [10, 4] - [10, 55]
value:
Str: [10, 4] - [10, 55]
s: 'this is also not a unicode escape: \\N{AMPERSAND}'
prefix: 'r"'
implicitly_concatenated_parts: None
]
orelse: None
If: [11, 0] - [11, 5]
test:
Num: [11, 3] - [11, 4]
n: 6
text: '6'
body: [
Expr: [12, 4] - [12, 20]
value:
Str: [12, 4] - [12, 20]
s: '\\N{AMPERSAND}'
prefix: "'"
implicitly_concatenated_parts: None
]
orelse: None
If: [13, 0] - [13, 5]
test:
Num: [13, 3] - [13, 4]
n: 7
text: '7'
body: [
Expr: [14, 4] - [14, 13]
value:
Str: [14, 4] - [14, 13]
s: '\\Nspam'
prefix: "'"
implicitly_concatenated_parts: None
]
orelse: None
If: [15, 0] - [15, 5]
test:
Num: [15, 3] - [15, 4]
n: 8
text: '8'
body: [
Expr: [16, 4] - [16, 55]
value:
Str: [16, 4] - [16, 55]
s: 'this is also also a unicode escape: &'
prefix: '"'
implicitly_concatenated_parts: None
]
orelse: None
If: [17, 0] - [17, 5]
test:
Num: [17, 3] - [17, 4]
n: 9
text: '9'
body: [
Expr: [18, 4] - [18, 56]
value:
Str: [18, 4] - [18, 56]
s: 'this is also not a unicode escape: \\N{AMPERSAND}'
prefix: 'rb"'
implicitly_concatenated_parts: None
]
orelse: None
If: [19, 0] - [19, 6]
test:
Num: [19, 3] - [19, 5]
n: 10
text: '10'
body: [
Expr: [20, 4] - [20, 21]
value:
Str: [20, 4] - [20, 21]
s: '\\N{AMPERSAND}'
prefix: "b'"
implicitly_concatenated_parts: None
]
orelse: None
If: [21, 0] - [21, 6]
test:
Num: [21, 3] - [21, 5]
n: 11
text: '11'
body: [
Expr: [22, 4] - [22, 14]
value:
Str: [22, 4] - [22, 14]
s: '\\Nspam'
prefix: "b'"
implicitly_concatenated_parts: None
]
orelse: None
If: [23, 0] - [23, 6]
test:
Num: [23, 3] - [23, 5]
n: 12
text: '12'
body: [
Expr: [24, 4] - [24, 81]
value:
Str: [24, 4] - [24, 81]
s: 'this is not a unicode escape because we are in a bytestring: \\N{AMPERSAND}'
prefix: 'b"'
implicitly_concatenated_parts: None
]
orelse: None
If: [25, 0] - [25, 6]
test:
Num: [25, 3] - [25, 5]
n: 13
text: '13'
body: [
Expr: [26, 4] - [26, 55]
value:
JoinedStr: [26, 4] - [26, 55]
values: [
Str: [26, 4] - [26, 39]
s: 'quotes before interpolation "'
prefix: 'fr"""'
implicitly_concatenated_parts: None
Num: [26, 39] - [26, 40]
n: 0
text: '0'
Str: [26, 40] - [26, 55]
s: '" are okay.'
prefix: 'fr"""'
implicitly_concatenated_parts: None
]
]
orelse: None
If: [27, 0] - [27, 6]
test:
Num: [27, 3] - [27, 5]
n: 14
text: '14'
body: [
Expr: [28, 4] - [28, 61]
value:
JoinedStr: [28, 4] - [28, 61]
values: [
Str: [28, 4] - [28, 45]
s: 'backslash before an interpolation \\'
prefix: 'fr"""'
implicitly_concatenated_parts: None
Num: [28, 45] - [28, 46]
n: 1
text: '1'
Str: [28, 46] - [28, 61]
s: '\\ are okay.'
prefix: 'fr"""'
implicitly_concatenated_parts: None
]
]
orelse: None
If: [29, 0] - [29, 6]
test:
Num: [29, 3] - [29, 5]
n: 15
text: '15'
body: [
Expr: [30, 4] - [30, 54]
value:
JoinedStr: [30, 4] - [30, 54]
values: [
Str: [30, 4] - [30, 33]
s: 'Yield inside an f-string: '
prefix: 'f"'
implicitly_concatenated_parts: None
Yield: [30, 33] - [30, 40]
value:
Num: [30, 39] - [30, 40]
n: 5
text: '5'
Str: [30, 40] - [30, 54]
s: ' is allowed.'
prefix: 'f"'
implicitly_concatenated_parts: None
]
]
orelse: None
]

View File

@@ -0,0 +1,30 @@
if 1:
fr"this is not a unicode escape but an interpolation: \N{AMPERSAND}"
if 2:
f'also an interpolation: \\N{AMPERSAND}'
if 3:
f'\\Nspam'
if 4:
f"this is a unicode escape: \N{AMPERSAND}"
if 5:
r"this is also not a unicode escape: \N{AMPERSAND}"
if 6:
'\\N{AMPERSAND}'
if 7:
'\\Nspam'
if 8:
"this is also also a unicode escape: \N{AMPERSAND}"
if 9:
rb"this is also not a unicode escape: \N{AMPERSAND}"
if 10:
b'\\N{AMPERSAND}'
if 11:
b'\\Nspam'
if 12:
b"this is not a unicode escape because we are in a bytestring: \N{AMPERSAND}"
if 13:
fr"""quotes before interpolation "{0}" are okay."""
if 14:
fr"""backslash before an interpolation \{1}\ are okay."""
if 15:
f"Yield inside an f-string: {yield 5} is allowed."

View File

@@ -0,0 +1,142 @@
Module: [1, 0] - [6, 0]
body: [
TypeAlias: [1, 0] - [1, 34]
name:
Name: [1, 5] - [1, 6]
variable: Variable('T', None)
ctx: Store
type_parameters: [
TypeVar: [1, 7] - [1, 9]
name:
Name: [1, 7] - [1, 9]
variable: Variable('T1', None)
ctx: Store
bound: None
TypeVar: [1, 11] - [1, 17]
name:
Name: [1, 11] - [1, 13]
variable: Variable('T2', None)
ctx: Store
bound:
Name: [1, 15] - [1, 17]
variable: Variable('E1', None)
ctx: Load
TypeVarTuple: [1, 19] - [1, 22]
name:
Name: [1, 20] - [1, 22]
variable: Variable('T3', None)
ctx: Store
ParamSpec: [1, 24] - [1, 28]
name:
Name: [1, 26] - [1, 28]
variable: Variable('T4', None)
ctx: Store
]
value:
Name: [1, 32] - [1, 34]
variable: Variable('T5', None)
ctx: Load
Assign: [3, 0] - [3, 31]
targets: [
Name: [3, 4] - [3, 5]
variable: Variable('f', None)
ctx: Store
]
value:
FunctionExpr: [3, 0] - [3, 31]
name: 'f'
args:
arguments
defaults: []
kw_defaults: []
annotations: []
varargannotation: None
kwargannotation: None
kw_annotations: []
returns: None
inner_scope:
Function: [3, 0] - [3, 31]
name: 'f'
type_parameters: [
TypeVar: [3, 6] - [3, 8]
name:
Name: [3, 6] - [3, 8]
variable: Variable('T6', None)
ctx: Store
bound: None
TypeVar: [3, 10] - [3, 16]
name:
Name: [3, 10] - [3, 12]
variable: Variable('T7', None)
ctx: Store
bound:
Name: [3, 14] - [3, 16]
variable: Variable('E2', None)
ctx: Load
TypeVarTuple: [3, 18] - [3, 21]
name:
Name: [3, 19] - [3, 21]
variable: Variable('T8', None)
ctx: Store
ParamSpec: [3, 23] - [3, 27]
name:
Name: [3, 25] - [3, 27]
variable: Variable('T9', None)
ctx: Store
]
args: []
vararg: None
kwonlyargs: []
kwarg: None
body: [
Expr: [3, 32] - [3, 35]
value:
Ellipsis: [3, 32] - [3, 35]
]
Assign: [5, 0] - [5, 35]
targets: [
Name: [5, 6] - [5, 7]
variable: Variable('C', None)
ctx: Store
]
value:
ClassExpr: [5, 0] - [5, 35]
name: 'C'
type_parameters: [
TypeVar: [5, 8] - [5, 11]
name:
Name: [5, 8] - [5, 11]
variable: Variable('T10', None)
ctx: Store
bound: None
TypeVar: [5, 13] - [5, 20]
name:
Name: [5, 13] - [5, 16]
variable: Variable('T11', None)
ctx: Store
bound:
Name: [5, 18] - [5, 20]
variable: Variable('E3', None)
ctx: Load
TypeVarTuple: [5, 22] - [5, 26]
name:
Name: [5, 23] - [5, 26]
variable: Variable('T12', None)
ctx: Store
ParamSpec: [5, 28] - [5, 33]
name:
Name: [5, 30] - [5, 33]
variable: Variable('T13', None)
ctx: Store
]
bases: []
keywords: []
inner_scope:
Class: [5, 0] - [5, 35]
name: 'C'
body: [
Expr: [5, 36] - [5, 39]
value:
Ellipsis: [5, 36] - [5, 39]
]
]

View File

@@ -0,0 +1,5 @@
type T[T1, T2: E1, *T3, **T4] = T5
def f[T6, T7: E2, *T8, **T9](): ...
class C[T10, T11: E3, *T12, **T13]: ...

View File

@@ -0,0 +1,6 @@
while a:
b
c
else:
d
e

View File

@@ -0,0 +1,9 @@
with a as b:
c
d
with f as g, h as i:
j
with k, l:
m