Move failing examples to a separate file.

This commit is contained in:
Dave Halter
2017-08-06 00:46:05 +02:00
parent d33e45f4cd
commit 97525958b6
2 changed files with 290 additions and 288 deletions

285
test/failing_examples.py Normal file
View File

@@ -0,0 +1,285 @@
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 +',
'?',
# Python/compile.c
dedent('''\
for a in [1]:
try:
pass
finally:
continue
'''), # 'continue' not supported inside 'finally' clause"
'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',
# Mostly 3.6 relevant
'[]: 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)',
'a, b += 3',
'(a, b) += 3',
'[a, b] += 3',
# 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"\"',
'*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]}',
# 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',
]
GLOBAL_NONLOCAL_ERROR = [
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
'''),
]
if sys.version_info >= (3, 6):
FAILING_EXAMPLES += GLOBAL_NONLOCAL_ERROR
FAILING_EXAMPLES += [
# Raises multiple errors in previous versions.
'async def foo():\n def nofoo():[x async for x in []]',
]
if sys.version_info >= (3, 5):
FAILING_EXAMPLES += [
# Raises different errors so just ignore them for now.
'[*[] for a in [1]]',
# Raises multiple errors in previous versions.
'async def bla():\n def x(): await bla()',
]
if sys.version_info >= (3, 4):
# Before that del None works like del list, it gives a NameError.
FAILING_EXAMPLES.append('del None')
if sys.version_info >= (3,):
FAILING_EXAMPLES += [
# Unfortunately assigning to False and True do not raise an error in
# 2.x.
'(True,) = x',
'([False], a) = x',
# A symtable error that raises only a SyntaxWarning in Python 2.
'def x(): from math import *',
# unicode chars in bytes are allowed in python 2
'b"ä"',
# combining strings and unicode is allowed in Python 2.
'"s" b""',
]
if sys.version_info >= (2, 7):
# This is something that raises a different error in 2.6 than in the other
# versions. Just skip it for 2.6.
FAILING_EXAMPLES.append('[a, 1] += 3')
if sys.version_info[:2] == (3, 5):
# yields are not allowed in 3.5 async functions. Therefore test them
# separately, here.
FAILING_EXAMPLES += [
'async def foo():\n yield x',
'async def foo():\n yield x',
]
else:
FAILING_EXAMPLES += [
'async def foo():\n yield x\n return 1',
'async def foo():\n yield x\n return 1',
]

View File

@@ -4,294 +4,11 @@ Testing if parso finds syntax errors and indentation errors.
""" """
import sys import sys
import warnings import warnings
from textwrap import dedent
import pytest import pytest
import parso import parso
from .failing_examples import FAILING_EXAMPLES, indent, build_nested
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 +',
'?',
# Python/compile.c
dedent('''\
for a in [1]:
try:
pass
finally:
continue
'''), # 'continue' not supported inside 'finally' clause"
'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',
# Mostly 3.6 relevant
'[]: 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)',
'a, b += 3',
'(a, b) += 3',
'[a, b] += 3',
# 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"\"',
'*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]}',
# 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',
]
GLOBAL_NONLOCAL_ERROR = [
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
'''),
]
if sys.version_info >= (3, 6):
FAILING_EXAMPLES += GLOBAL_NONLOCAL_ERROR
FAILING_EXAMPLES += [
# Raises multiple errors in previous versions.
'async def foo():\n def nofoo():[x async for x in []]',
]
if sys.version_info >= (3, 5):
FAILING_EXAMPLES += [
# Raises different errors so just ignore them for now.
'[*[] for a in [1]]',
# Raises multiple errors in previous versions.
'async def bla():\n def x(): await bla()',
]
if sys.version_info >= (3, 4):
# Before that del None works like del list, it gives a NameError.
FAILING_EXAMPLES.append('del None')
if sys.version_info >= (3,):
FAILING_EXAMPLES += [
# Unfortunately assigning to False and True do not raise an error in
# 2.x.
'(True,) = x',
'([False], a) = x',
# A symtable error that raises only a SyntaxWarning in Python 2.
'def x(): from math import *',
# unicode chars in bytes are allowed in python 2
'b"ä"',
# combining strings and unicode is allowed in Python 2.
'"s" b""',
]
if sys.version_info >= (2, 7):
# This is something that raises a different error in 2.6 than in the other
# versions. Just skip it for 2.6.
FAILING_EXAMPLES.append('[a, 1] += 3')
if sys.version_info[:2] == (3, 5):
# yields are not allowed in 3.5 async functions. Therefore test them
# separately, here.
FAILING_EXAMPLES += [
'async def foo():\n yield x',
'async def foo():\n yield x',
]
else:
FAILING_EXAMPLES += [
'async def foo():\n yield x\n return 1',
'async def foo():\n yield x\n return 1',
]
def _get_error_list(code, version=None): def _get_error_list(code, version=None):
@@ -508,8 +225,8 @@ def test_escape_decode_literals(each_version):
def test_too_many_levels_of_indentation(): def test_too_many_levels_of_indentation():
assert not _get_error_list(_build_nested('pass', 99)) assert not _get_error_list(build_nested('pass', 99))
assert _get_error_list(_build_nested('pass', 100)) assert _get_error_list(build_nested('pass', 100))
base = 'def x():\n if x:\n' base = 'def x():\n if x:\n'
assert not _get_error_list(_build_nested('pass', 49, base=base)) assert not _get_error_list(build_nested('pass', 49, base=base))
assert _get_error_list(_build_nested('pass', 50, base=base)) assert _get_error_list(build_nested('pass', 50, base=base))