mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 09:20:06 +08:00
416 lines
8.8 KiB
Python
Vendored
416 lines
8.8 KiB
Python
Vendored
# -*- 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}'",
|
|
]
|