123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- # -*- coding: utf-8 -*-
- import sys
- from textwrap import dedent
- def indent(code):
- lines = code.splitlines(True)
- return ''.join([' ' * 2 + line for line in lines])
- def build_nested(code, depth, base='def f():\n'):
- if depth == 0:
- return code
- new_code = base + indent(code)
- return build_nested(new_code, depth - 1, base=base)
- FAILING_EXAMPLES = [
- '1 +',
- '?',
- 'continue',
- 'break',
- 'return',
- 'yield',
- # SyntaxError from Python/ast.c
- 'f(x for x in bar, 1)',
- 'from foo import a,',
- 'from __future__ import whatever',
- 'from __future__ import braces',
- 'from .__future__ import whatever',
- 'def f(x=3, y): pass',
- 'lambda x=3, y: x',
- '__debug__ = 1',
- 'with x() as __debug__: pass',
- '[]: int',
- '[a, b]: int',
- '(): int',
- '(()): int',
- '((())): int',
- '{}: int',
- 'True: int',
- '(a, b): int',
- '*star,: int',
- 'a, b: int = 3',
- 'foo(+a=3)',
- 'f(lambda: 1=1)',
- 'f(x=1, x=2)',
- 'f(**x, y)',
- 'f(x=2, y)',
- 'f(**x, *y)',
- 'f(**x, y=3, z)',
- # augassign
- 'a, b += 3',
- '(a, b) += 3',
- '[a, b] += 3',
- '[a, 1] += 3',
- 'f() += 1',
- 'lambda x:None+=1',
- '{} += 1',
- '{a:b} += 1',
- '{1} += 1',
- '{*x} += 1',
- '(x,) += 1',
- '(x, y if a else q) += 1',
- '[] += 1',
- '[1,2] += 1',
- '[] += 1',
- 'None += 1',
- '... += 1',
- 'a > 1 += 1',
- '"test" += 1',
- '1 += 1',
- '1.0 += 1',
- '(yield) += 1',
- '(yield from x) += 1',
- '(x if x else y) += 1',
- 'a() += 1',
- 'a + b += 1',
- '+a += 1',
- 'a and b += 1',
- '*a += 1',
- 'a, b += 1',
- 'f"xxx" += 1',
- # All assignment tests
- 'lambda a: 1 = 1',
- '[x for x in y] = 1',
- '{x for x in y} = 1',
- '{x:x for x in y} = 1',
- '(x for x in y) = 1',
- 'None = 1',
- '... = 1',
- 'a == b = 1',
- '{a, b} = 1',
- '{a: b} = 1',
- '1 = 1',
- '"" = 1',
- 'b"" = 1',
- 'b"" = 1',
- '"" "" = 1',
- '1 | 1 = 3',
- '1**1 = 3',
- '~ 1 = 3',
- 'not 1 = 3',
- '1 and 1 = 3',
- 'def foo(): (yield 1) = 3',
- 'def foo(): x = yield 1 = 3',
- 'async def foo(): await x = 3',
- '(a if a else a) = a',
- 'a, 1 = x',
- 'foo() = 1',
- # Cases without the equals but other assignments.
- 'with x as foo(): pass',
- 'del bar, 1',
- 'for x, 1 in []: pass',
- 'for (not 1) in []: pass',
- '[x for 1 in y]',
- '[x for a, 3 in y]',
- '(x for 1 in y)',
- '{x for 1 in y}',
- '{x:x for 1 in y}',
- # Unicode/Bytes issues.
- r'u"\x"',
- r'u"\"',
- r'u"\u"',
- r'u"""\U"""',
- r'u"\Uffffffff"',
- r"u'''\N{}'''",
- r"u'\N{foo}'",
- r'b"\x"',
- r'b"\"',
- 'b"ä"',
- '*a, *b = 3, 3',
- 'async def foo(): yield from []',
- 'yield from []',
- '*a = 3',
- 'del *a, b',
- 'def x(*): pass',
- '(%s *d) = x' % ('a,' * 256),
- '{**{} for a in [1]}',
- '(True,) = x',
- '([False], a) = x',
- 'def x(): from math import *',
- # invalid del statements
- 'del x + y',
- 'del x(y)',
- 'async def foo(): del await x',
- 'def foo(): del (yield x)',
- 'del [x for x in range(10)]',
- 'del *x',
- 'del *x,',
- 'del (*x,)',
- 'del [*x]',
- 'del x, *y',
- 'del *x.y,',
- 'del *x[y],',
- 'del *x[y::], z',
- 'del x, (y, *z)',
- 'del (x, *[y, z])',
- 'del [x, *(y, [*z])]',
- 'del {}',
- 'del {x}',
- 'del {x, y}',
- 'del {x, *y}',
- # invalid starred expressions
- '*x',
- '(*x)',
- '((*x))',
- '1 + (*x)',
- '*x; 1',
- '1; *x',
- '1\n*x',
- 'x = *y',
- 'x: int = *y',
- 'def foo(): return *x',
- 'def foo(): yield *x',
- 'f"{*x}"',
- 'for *x in 1: pass',
- '[1 for *x in 1]',
- # str/bytes combinations
- '"s" b""',
- '"s" b"" ""',
- 'b"" "" b"" ""',
- 'f"s" b""',
- 'b"s" f""',
- # Parser/tokenize.c
- r'"""',
- r'"',
- r"'''",
- r"'",
- r"\blub",
- # IndentationError: too many levels of indentation
- build_nested('pass', 100),
- # SyntaxErrors from Python/symtable.c
- 'def f(x, x): pass',
- 'nonlocal a',
- # IndentationError
- ' foo',
- 'def x():\n 1\n 2',
- 'def x():\n 1\n 2',
- 'if 1:\nfoo',
- 'if 1: blubb\nif 1:\npass\nTrue and False',
- # f-strings
- 'f"{}"',
- r'f"{\}"',
- 'f"{\'\\\'}"',
- 'f"{#}"',
- "f'{1!b}'",
- "f'{1:{5:{3}}}'",
- "f'{'",
- "f'{'",
- "f'}'",
- "f'{\"}'",
- "f'{\"}'",
- # Now nested parsing
- "f'{continue}'",
- "f'{1;1}'",
- "f'{a;}'",
- "f'{b\"\" \"\"}'",
- # f-string expression part cannot include a backslash
- r'''f"{'\n'}"''',
- 'async def foo():\n yield x\n return 1',
- 'async def foo():\n yield x\n return 1',
- '[*[] for a in [1]]',
- 'async def bla():\n def x(): await bla()',
- 'del None',
- 'del True',
- 'del False',
- 'del ...',
- # Errors of global / nonlocal
- dedent('''
- def glob():
- x = 3
- x.z
- global x'''),
- dedent('''
- def glob():
- x = 3
- global x'''),
- dedent('''
- def glob():
- x
- global x'''),
- dedent('''
- def glob():
- x = 3
- x.z
- nonlocal x'''),
- dedent('''
- def glob():
- x = 3
- nonlocal x'''),
- dedent('''
- def glob():
- x
- nonlocal x'''),
- # Annotation issues
- dedent('''
- def glob():
- x[0]: foo
- global x'''),
- dedent('''
- def glob():
- x.a: foo
- global x'''),
- dedent('''
- def glob():
- x: foo
- global x'''),
- dedent('''
- def glob():
- x: foo = 5
- global x'''),
- dedent('''
- def glob():
- x: foo = 5
- x
- global x'''),
- dedent('''
- def glob():
- global x
- x: foo = 3
- '''),
- # global/nonlocal + param
- dedent('''
- def glob(x):
- global x
- '''),
- dedent('''
- def glob(x):
- nonlocal x
- '''),
- dedent('''
- def x():
- a =3
- def z():
- nonlocal a
- a = 3
- nonlocal a
- '''),
- dedent('''
- def x():
- a = 4
- def y():
- global a
- nonlocal a
- '''),
- # Missing binding of nonlocal
- dedent('''
- def x():
- nonlocal a
- '''),
- dedent('''
- def x():
- def y():
- nonlocal a
- '''),
- dedent('''
- def x():
- a = 4
- def y():
- global a
- print(a)
- def z():
- nonlocal a
- '''),
- # Name is assigned before nonlocal declaration
- dedent('''
- def x(a):
- def y():
- a = 10
- nonlocal a
- '''),
- ]
- if sys.version_info[:2] >= (3, 7):
- # This is somehow ok in previous versions.
- FAILING_EXAMPLES += [
- 'class X(base for base in bases): pass',
- ]
- if sys.version_info[:2] < (3, 8):
- FAILING_EXAMPLES += [
- # Python/compile.c
- dedent('''\
- for a in [1]:
- try:
- pass
- finally:
- continue
- '''), # 'continue' not supported inside 'finally' clause"
- ]
- if sys.version_info[:2] >= (3, 8):
- # assignment expressions from issue#89
- FAILING_EXAMPLES += [
- # Case 2
- '(lambda: x := 1)',
- '((lambda: x) := 1)',
- # Case 3
- '(a[i] := x)',
- '((a[i]) := x)',
- '(a(i) := x)',
- # Case 4
- '(a.b := c)',
- '[(i.i:= 0) for ((i), j) in range(5)]',
- # Case 5
- '[i:= 0 for i, j in range(5)]',
- '[(i:= 0) for ((i), j) in range(5)]',
- '[(i:= 0) for ((i), j), in range(5)]',
- '[(i:= 0) for ((i), j.i), in range(5)]',
- '[[(i:= i) for j in range(5)] for i in range(5)]',
- '[i for i, j in range(5) if True or (i:= 1)]',
- '[False and (i:= 0) for i, j in range(5)]',
- # Case 6
- '[i+1 for i in (i:= range(5))]',
- '[i+1 for i in (j:= range(5))]',
- '[i+1 for i in (lambda: (j:= range(5)))()]',
- # Case 7
- 'class Example:\n [(j := i) for i in range(5)]',
- # Not in that issue
- '(await a := x)',
- '((await a) := x)',
- # new discoveries
- '((a, b) := (1, 2))',
- '([a, b] := [1, 2])',
- '({a, b} := {1, 2})',
- '({a: b} := {1: 2})',
- '(a + b := 1)',
- '(True := 1)',
- '(False := 1)',
- '(None := 1)',
- '(__debug__ := 1)',
- # Unparenthesized walrus not allowed in dict literals, dict comprehensions and slices
- '{a:="a": b:=1}',
- '{y:=1: 2 for x in range(5)}',
- 'a[b:=0:1:2]',
- ]
- # f-string debugging syntax with invalid conversion character
- FAILING_EXAMPLES += [
- "f'{1=!b}'",
- ]
|