mirror of
https://github.com/davidhalter/parso.git
synced 2026-01-10 13:32:46 +08:00
Remove support for parsing Python 2
This commit is contained in:
@@ -44,3 +44,75 @@ a = 3
|
||||
|
||||
def x(b=a):
|
||||
global a
|
||||
|
||||
|
||||
*foo, a = (1,)
|
||||
*foo[0], a = (1,)
|
||||
*[], a = (1,)
|
||||
|
||||
|
||||
async def foo():
|
||||
await bar()
|
||||
#: E901
|
||||
yield from []
|
||||
return
|
||||
#: E901
|
||||
return ''
|
||||
|
||||
|
||||
# With decorator it's a different statement.
|
||||
@bla
|
||||
async def foo():
|
||||
await bar()
|
||||
#: E901
|
||||
yield from []
|
||||
return
|
||||
#: E901
|
||||
return ''
|
||||
|
||||
|
||||
foo: int = 4
|
||||
(foo): int = 3
|
||||
((foo)): int = 3
|
||||
foo.bar: int
|
||||
foo[3]: int
|
||||
|
||||
|
||||
def glob():
|
||||
global x
|
||||
y: foo = x
|
||||
|
||||
|
||||
def c():
|
||||
a = 3
|
||||
|
||||
def d():
|
||||
class X():
|
||||
nonlocal a
|
||||
|
||||
|
||||
def x():
|
||||
a = 3
|
||||
|
||||
def y():
|
||||
nonlocal a
|
||||
|
||||
|
||||
def x():
|
||||
def y():
|
||||
nonlocal a
|
||||
|
||||
a = 3
|
||||
|
||||
|
||||
def x():
|
||||
a = 3
|
||||
|
||||
def y():
|
||||
class z():
|
||||
nonlocal a
|
||||
|
||||
|
||||
a = *args, *args
|
||||
error[(*args, *args)] = 3
|
||||
*args, *args
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
's' b''
|
||||
u's' b'ä'
|
||||
@@ -1,3 +0,0 @@
|
||||
*foo, a = (1,)
|
||||
*foo[0], a = (1,)
|
||||
*[], a = (1,)
|
||||
@@ -1,23 +0,0 @@
|
||||
"""
|
||||
Mostly allowed syntax in Python 3.5.
|
||||
"""
|
||||
|
||||
|
||||
async def foo():
|
||||
await bar()
|
||||
#: E901
|
||||
yield from []
|
||||
return
|
||||
#: E901
|
||||
return ''
|
||||
|
||||
|
||||
# With decorator it's a different statement.
|
||||
@bla
|
||||
async def foo():
|
||||
await bar()
|
||||
#: E901
|
||||
yield from []
|
||||
return
|
||||
#: E901
|
||||
return ''
|
||||
@@ -1,45 +0,0 @@
|
||||
foo: int = 4
|
||||
(foo): int = 3
|
||||
((foo)): int = 3
|
||||
foo.bar: int
|
||||
foo[3]: int
|
||||
|
||||
|
||||
def glob():
|
||||
global x
|
||||
y: foo = x
|
||||
|
||||
|
||||
def c():
|
||||
a = 3
|
||||
|
||||
def d():
|
||||
class X():
|
||||
nonlocal a
|
||||
|
||||
|
||||
def x():
|
||||
a = 3
|
||||
|
||||
def y():
|
||||
nonlocal a
|
||||
|
||||
|
||||
def x():
|
||||
def y():
|
||||
nonlocal a
|
||||
|
||||
a = 3
|
||||
|
||||
|
||||
def x():
|
||||
a = 3
|
||||
|
||||
def y():
|
||||
class z():
|
||||
nonlocal a
|
||||
|
||||
|
||||
a = *args, *args
|
||||
error[(*args, *args)] = 3
|
||||
*args, *args
|
||||
@@ -1,14 +0,0 @@
|
||||
import sys
|
||||
|
||||
print 1, 2 >> sys.stdout
|
||||
|
||||
|
||||
foo = ur'This is not possible in Python 3.'
|
||||
|
||||
# This is actually printing a tuple.
|
||||
#: E275:5
|
||||
print(1, 2)
|
||||
|
||||
# True and False are not keywords in Python 2 and therefore there's no need for
|
||||
# a space.
|
||||
norman = True+False
|
||||
@@ -10,12 +10,12 @@ def get_python_files(path):
|
||||
yield os.path.join(dir_path, file_name)
|
||||
|
||||
|
||||
def test_on_itself(each_py3_version):
|
||||
def test_on_itself(each_version):
|
||||
"""
|
||||
There are obviously no syntax erros in the Python code of parso. However
|
||||
parso should output the same for all versions.
|
||||
"""
|
||||
grammar = parso.load_grammar(version=each_py3_version)
|
||||
grammar = parso.load_grammar(version=each_version)
|
||||
path = os.path.dirname(os.path.dirname(__file__)) + '/parso'
|
||||
for file in get_python_files(path):
|
||||
tree = grammar.parse(path=file)
|
||||
|
||||
@@ -8,13 +8,13 @@ from textwrap import dedent
|
||||
from parso import parse
|
||||
|
||||
|
||||
def assert_params(param_string, version=None, **wanted_dct):
|
||||
def assert_params(param_string, **wanted_dct):
|
||||
source = dedent('''
|
||||
def x(%s):
|
||||
pass
|
||||
''') % param_string
|
||||
|
||||
module = parse(source, version=version)
|
||||
module = parse(source)
|
||||
funcdef = next(module.iter_funcdefs())
|
||||
dct = dict((p.name.value, p.default and p.default.get_code())
|
||||
for p in funcdef.get_params())
|
||||
@@ -23,9 +23,9 @@ def assert_params(param_string, version=None, **wanted_dct):
|
||||
|
||||
|
||||
def test_split_params_with_separation_star():
|
||||
assert_params('x, y=1, *, z=3', x=None, y='1', z='3', version='3.5')
|
||||
assert_params('*, x', x=None, version='3.5')
|
||||
assert_params('*', version='3.5')
|
||||
assert_params('x, y=1, *, z=3', x=None, y='1', z='3')
|
||||
assert_params('*, x', x=None)
|
||||
assert_params('*')
|
||||
|
||||
|
||||
def test_split_params_with_stars():
|
||||
@@ -34,12 +34,12 @@ def test_split_params_with_stars():
|
||||
assert_params('*args, **kwargs', args=None, kwargs=None)
|
||||
|
||||
|
||||
def test_kw_only_no_kw(works_ge_py3):
|
||||
def test_kw_only_no_kw(works_in_py):
|
||||
"""
|
||||
Parsing this should be working. In CPython the parser also parses this and
|
||||
in a later step the AST complains.
|
||||
"""
|
||||
module = works_ge_py3.parse('def test(arg, *):\n pass')
|
||||
module = works_in_py.parse('def test(arg, *):\n pass')
|
||||
if module is not None:
|
||||
func = module.children[0]
|
||||
open_, p1, asterisk, close = func._get_param_nodes()
|
||||
|
||||
@@ -26,7 +26,7 @@ class TestsFunctionAndLambdaParsing(object):
|
||||
|
||||
@pytest.fixture(params=FIXTURES)
|
||||
def node(self, request):
|
||||
parsed = parse(dedent(request.param[0]), version='3.5')
|
||||
parsed = parse(dedent(request.param[0]), version='3.10')
|
||||
request.keywords['expected'] = request.param[1]
|
||||
child = parsed.children[0]
|
||||
if child.type == 'simple_stmt':
|
||||
@@ -79,16 +79,16 @@ def test_default_param(each_version):
|
||||
assert not param.star_count
|
||||
|
||||
|
||||
def test_annotation_param(each_py3_version):
|
||||
func = parse('def x(foo: 3): pass', version=each_py3_version).children[0]
|
||||
def test_annotation_param(each_version):
|
||||
func = parse('def x(foo: 3): pass', version=each_version).children[0]
|
||||
param, = func.get_params()
|
||||
assert param.default is None
|
||||
assert param.annotation.value == '3'
|
||||
assert not param.star_count
|
||||
|
||||
|
||||
def test_annotation_params(each_py3_version):
|
||||
func = parse('def x(foo: 3, bar: 4): pass', version=each_py3_version).children[0]
|
||||
def test_annotation_params(each_version):
|
||||
func = parse('def x(foo: 3, bar: 4): pass', version=each_version).children[0]
|
||||
param1, param2 = func.get_params()
|
||||
|
||||
assert param1.default is None
|
||||
@@ -100,23 +100,14 @@ def test_annotation_params(each_py3_version):
|
||||
assert not param2.star_count
|
||||
|
||||
|
||||
def test_default_and_annotation_param(each_py3_version):
|
||||
func = parse('def x(foo:3=42): pass', version=each_py3_version).children[0]
|
||||
def test_default_and_annotation_param(each_version):
|
||||
func = parse('def x(foo:3=42): pass', version=each_version).children[0]
|
||||
param, = func.get_params()
|
||||
assert param.default.value == '42'
|
||||
assert param.annotation.value == '3'
|
||||
assert not param.star_count
|
||||
|
||||
|
||||
def test_ellipsis_py2(each_py2_version):
|
||||
module = parse('[0][...]', version=each_py2_version, error_recovery=False)
|
||||
expr = module.children[0]
|
||||
trailer = expr.children[-1]
|
||||
subscript = trailer.children[1]
|
||||
assert subscript.type == 'subscript'
|
||||
assert [leaf.value for leaf in subscript.children] == ['.', '.', '.']
|
||||
|
||||
|
||||
def get_yield_exprs(code, version):
|
||||
return list(parse(code, version=version).children[0].iter_yield_exprs())
|
||||
|
||||
|
||||
@@ -42,23 +42,23 @@ def test_formfeed(each_version):
|
||||
_parse(s, each_version)
|
||||
|
||||
|
||||
def test_matrix_multiplication_operator(works_ge_py35):
|
||||
works_ge_py35.parse("a @ b")
|
||||
works_ge_py35.parse("a @= b")
|
||||
def test_matrix_multiplication_operator(works_in_py):
|
||||
works_in_py.parse("a @ b")
|
||||
works_in_py.parse("a @= b")
|
||||
|
||||
|
||||
def test_yield_from(works_ge_py3, each_version):
|
||||
works_ge_py3.parse("yield from x")
|
||||
works_ge_py3.parse("(yield from x) + y")
|
||||
def test_yield_from(works_in_py, each_version):
|
||||
works_in_py.parse("yield from x")
|
||||
works_in_py.parse("(yield from x) + y")
|
||||
_invalid_syntax("yield from", each_version)
|
||||
|
||||
|
||||
def test_await_expr(works_ge_py35):
|
||||
works_ge_py35.parse("""async def foo():
|
||||
def test_await_expr(works_in_py):
|
||||
works_in_py.parse("""async def foo():
|
||||
await x
|
||||
""")
|
||||
|
||||
works_ge_py35.parse("""async def foo():
|
||||
works_in_py.parse("""async def foo():
|
||||
|
||||
def foo(): pass
|
||||
|
||||
@@ -67,24 +67,23 @@ def test_await_expr(works_ge_py35):
|
||||
await x
|
||||
""")
|
||||
|
||||
works_ge_py35.parse("""async def foo(): return await a""")
|
||||
works_in_py.parse("""async def foo(): return await a""")
|
||||
|
||||
works_ge_py35.parse("""def foo():
|
||||
works_in_py.parse("""def foo():
|
||||
def foo(): pass
|
||||
async def foo(): await x
|
||||
""")
|
||||
|
||||
|
||||
@pytest.mark.skipif('sys.version_info[:2] < (3, 5)')
|
||||
@pytest.mark.xfail(reason="acting like python 3.7")
|
||||
def test_async_var():
|
||||
_parse("""async = 1""", "3.5")
|
||||
_parse("""await = 1""", "3.5")
|
||||
_parse("""def async(): pass""", "3.5")
|
||||
_parse("""async = 1""", "3.6")
|
||||
_parse("""await = 1""", "3.6")
|
||||
_parse("""def async(): pass""", "3.6")
|
||||
|
||||
|
||||
def test_async_for(works_ge_py35):
|
||||
works_ge_py35.parse("async def foo():\n async for a in b: pass")
|
||||
def test_async_for(works_in_py):
|
||||
works_in_py.parse("async def foo():\n async for a in b: pass")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("body", [
|
||||
@@ -114,77 +113,82 @@ def test_async_for(works_ge_py35):
|
||||
1 async for a in b
|
||||
]""",
|
||||
])
|
||||
def test_async_for_comprehension_newline(works_ge_py36, body):
|
||||
def test_async_for_comprehension_newline(works_in_py, body):
|
||||
# Issue #139
|
||||
works_ge_py36.parse("""async def foo():
|
||||
works_in_py.parse("""async def foo():
|
||||
{}""".format(body))
|
||||
|
||||
|
||||
def test_async_with(works_ge_py35):
|
||||
works_ge_py35.parse("async def foo():\n async with a: pass")
|
||||
def test_async_with(works_in_py):
|
||||
works_in_py.parse("async def foo():\n async with a: pass")
|
||||
|
||||
@pytest.mark.skipif('sys.version_info[:2] < (3, 5)')
|
||||
@pytest.mark.xfail(reason="acting like python 3.7")
|
||||
def test_async_with_invalid():
|
||||
_invalid_syntax("""def foo():
|
||||
async with a: pass""", version="3.5")
|
||||
|
||||
def test_async_with_invalid(works_in_py):
|
||||
works_in_py.parse("""def foo():\n async with a: pass""")
|
||||
|
||||
|
||||
def test_raise_3x_style_1(each_version):
|
||||
_parse("raise", each_version)
|
||||
|
||||
|
||||
def test_raise_2x_style_2(works_in_py2):
|
||||
works_in_py2.parse("raise E, V")
|
||||
def test_raise_2x_style_2(works_not_in_py):
|
||||
works_not_in_py.parse("raise E, V")
|
||||
|
||||
|
||||
def test_raise_2x_style_3(works_not_in_py):
|
||||
works_not_in_py.parse("raise E, V, T")
|
||||
|
||||
def test_raise_2x_style_3(works_in_py2):
|
||||
works_in_py2.parse("raise E, V, T")
|
||||
|
||||
def test_raise_2x_style_invalid_1(each_version):
|
||||
_invalid_syntax("raise E, V, T, Z", version=each_version)
|
||||
|
||||
def test_raise_3x_style(works_ge_py3):
|
||||
works_ge_py3.parse("raise E1 from E2")
|
||||
|
||||
def test_raise_3x_style(works_in_py):
|
||||
works_in_py.parse("raise E1 from E2")
|
||||
|
||||
|
||||
def test_raise_3x_style_invalid_1(each_version):
|
||||
_invalid_syntax("raise E, V from E1", each_version)
|
||||
|
||||
|
||||
def test_raise_3x_style_invalid_2(each_version):
|
||||
_invalid_syntax("raise E from E1, E2", each_version)
|
||||
|
||||
|
||||
def test_raise_3x_style_invalid_3(each_version):
|
||||
_invalid_syntax("raise from E1, E2", each_version)
|
||||
|
||||
|
||||
def test_raise_3x_style_invalid_4(each_version):
|
||||
_invalid_syntax("raise E from", each_version)
|
||||
|
||||
|
||||
# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef
|
||||
def test_annotation_1(works_ge_py3):
|
||||
works_ge_py3.parse("""def f(x) -> list: pass""")
|
||||
def test_annotation_1(works_in_py):
|
||||
works_in_py.parse("""def f(x) -> list: pass""")
|
||||
|
||||
def test_annotation_2(works_ge_py3):
|
||||
works_ge_py3.parse("""def f(x:int): pass""")
|
||||
def test_annotation_2(works_in_py):
|
||||
works_in_py.parse("""def f(x:int): pass""")
|
||||
|
||||
def test_annotation_3(works_ge_py3):
|
||||
works_ge_py3.parse("""def f(*x:str): pass""")
|
||||
def test_annotation_3(works_in_py):
|
||||
works_in_py.parse("""def f(*x:str): pass""")
|
||||
|
||||
def test_annotation_4(works_ge_py3):
|
||||
works_ge_py3.parse("""def f(**x:float): pass""")
|
||||
def test_annotation_4(works_in_py):
|
||||
works_in_py.parse("""def f(**x:float): pass""")
|
||||
|
||||
def test_annotation_5(works_ge_py3):
|
||||
works_ge_py3.parse("""def f(x, y:1+2): pass""")
|
||||
def test_annotation_5(works_in_py):
|
||||
works_in_py.parse("""def f(x, y:1+2): pass""")
|
||||
|
||||
def test_annotation_6(each_py3_version):
|
||||
_invalid_syntax("""def f(a, (b:1, c:2, d)): pass""", each_py3_version)
|
||||
def test_annotation_6(each_version):
|
||||
_invalid_syntax("""def f(a, (b:1, c:2, d)): pass""", each_version)
|
||||
|
||||
def test_annotation_7(each_py3_version):
|
||||
_invalid_syntax("""def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass""", each_py3_version)
|
||||
def test_annotation_7(each_version):
|
||||
_invalid_syntax("""def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass""", each_version)
|
||||
|
||||
def test_annotation_8(each_py3_version):
|
||||
def test_annotation_8(each_version):
|
||||
s = """def f(a, (b:1, c:2, d), e:3=4, f=5,
|
||||
*g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass"""
|
||||
_invalid_syntax(s, each_py3_version)
|
||||
_invalid_syntax(s, each_version)
|
||||
|
||||
|
||||
def test_except_new(each_version):
|
||||
@@ -195,27 +199,27 @@ def test_except_new(each_version):
|
||||
y""")
|
||||
_parse(s, each_version)
|
||||
|
||||
def test_except_old(works_in_py2):
|
||||
def test_except_old(works_not_in_py):
|
||||
s = dedent("""
|
||||
try:
|
||||
x
|
||||
except E, N:
|
||||
y""")
|
||||
works_in_py2.parse(s)
|
||||
works_not_in_py.parse(s)
|
||||
|
||||
|
||||
# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testAtoms
|
||||
def test_set_literal_1(works_ge_py27):
|
||||
works_ge_py27.parse("""x = {'one'}""")
|
||||
def test_set_literal_1(works_in_py):
|
||||
works_in_py.parse("""x = {'one'}""")
|
||||
|
||||
def test_set_literal_2(works_ge_py27):
|
||||
works_ge_py27.parse("""x = {'one', 1,}""")
|
||||
def test_set_literal_2(works_in_py):
|
||||
works_in_py.parse("""x = {'one', 1,}""")
|
||||
|
||||
def test_set_literal_3(works_ge_py27):
|
||||
works_ge_py27.parse("""x = {'one', 'two', 'three'}""")
|
||||
def test_set_literal_3(works_in_py):
|
||||
works_in_py.parse("""x = {'one', 'two', 'three'}""")
|
||||
|
||||
def test_set_literal_4(works_ge_py27):
|
||||
works_ge_py27.parse("""x = {2, 3, 4,}""")
|
||||
def test_set_literal_4(works_in_py):
|
||||
works_in_py.parse("""x = {2, 3, 4,}""")
|
||||
|
||||
|
||||
def test_new_octal_notation(each_version):
|
||||
@@ -223,21 +227,21 @@ def test_new_octal_notation(each_version):
|
||||
_invalid_syntax("""0o7324528887""", each_version)
|
||||
|
||||
|
||||
def test_old_octal_notation(works_in_py2):
|
||||
works_in_py2.parse("07")
|
||||
def test_old_octal_notation(works_not_in_py):
|
||||
works_not_in_py.parse("07")
|
||||
|
||||
|
||||
def test_long_notation(works_in_py2):
|
||||
works_in_py2.parse("0xFl")
|
||||
works_in_py2.parse("0xFL")
|
||||
works_in_py2.parse("0b1l")
|
||||
works_in_py2.parse("0B1L")
|
||||
works_in_py2.parse("0o7l")
|
||||
works_in_py2.parse("0O7L")
|
||||
works_in_py2.parse("0l")
|
||||
works_in_py2.parse("0L")
|
||||
works_in_py2.parse("10l")
|
||||
works_in_py2.parse("10L")
|
||||
def test_long_notation(works_not_in_py):
|
||||
works_not_in_py.parse("0xFl")
|
||||
works_not_in_py.parse("0xFL")
|
||||
works_not_in_py.parse("0b1l")
|
||||
works_not_in_py.parse("0B1L")
|
||||
works_not_in_py.parse("0o7l")
|
||||
works_not_in_py.parse("0O7L")
|
||||
works_not_in_py.parse("0l")
|
||||
works_not_in_py.parse("0L")
|
||||
works_not_in_py.parse("10l")
|
||||
works_not_in_py.parse("10L")
|
||||
|
||||
|
||||
def test_new_binary_notation(each_version):
|
||||
@@ -245,20 +249,20 @@ def test_new_binary_notation(each_version):
|
||||
_invalid_syntax("""0b0101021""", each_version)
|
||||
|
||||
|
||||
def test_class_new_syntax(works_ge_py3):
|
||||
works_ge_py3.parse("class B(t=7): pass")
|
||||
works_ge_py3.parse("class B(t, *args): pass")
|
||||
works_ge_py3.parse("class B(t, **kwargs): pass")
|
||||
works_ge_py3.parse("class B(t, *args, **kwargs): pass")
|
||||
works_ge_py3.parse("class B(t, y=9, *args, **kwargs): pass")
|
||||
def test_class_new_syntax(works_in_py):
|
||||
works_in_py.parse("class B(t=7): pass")
|
||||
works_in_py.parse("class B(t, *args): pass")
|
||||
works_in_py.parse("class B(t, **kwargs): pass")
|
||||
works_in_py.parse("class B(t, *args, **kwargs): pass")
|
||||
works_in_py.parse("class B(t, y=9, *args, **kwargs): pass")
|
||||
|
||||
|
||||
def test_parser_idempotency_extended_unpacking(works_ge_py3):
|
||||
def test_parser_idempotency_extended_unpacking(works_in_py):
|
||||
"""A cut-down version of pytree_idempotency.py."""
|
||||
works_ge_py3.parse("a, *b, c = x\n")
|
||||
works_ge_py3.parse("[*a, b] = x\n")
|
||||
works_ge_py3.parse("(z, *y, w) = m\n")
|
||||
works_ge_py3.parse("for *z, m in d: pass\n")
|
||||
works_in_py.parse("a, *b, c = x\n")
|
||||
works_in_py.parse("[*a, b] = x\n")
|
||||
works_in_py.parse("(z, *y, w) = m\n")
|
||||
works_in_py.parse("for *z, m in d: pass\n")
|
||||
|
||||
|
||||
def test_multiline_bytes_literals(each_version):
|
||||
@@ -285,13 +289,13 @@ def test_multiline_bytes_tripquote_literals(each_version):
|
||||
_parse(s, each_version)
|
||||
|
||||
|
||||
def test_ellipsis(works_ge_py3, each_version):
|
||||
works_ge_py3.parse("...")
|
||||
def test_ellipsis(works_in_py, each_version):
|
||||
works_in_py.parse("...")
|
||||
_parse("[0][...]", version=each_version)
|
||||
|
||||
|
||||
def test_dict_unpacking(works_ge_py35):
|
||||
works_ge_py35.parse("{**dict(a=3), foo:2}")
|
||||
def test_dict_unpacking(works_in_py):
|
||||
works_in_py.parse("{**dict(a=3), foo:2}")
|
||||
|
||||
|
||||
def test_multiline_str_literals(each_version):
|
||||
@@ -304,24 +308,24 @@ def test_multiline_str_literals(each_version):
|
||||
_parse(s, each_version)
|
||||
|
||||
|
||||
def test_py2_backticks(works_in_py2):
|
||||
works_in_py2.parse("`1`")
|
||||
def test_py2_backticks(works_not_in_py):
|
||||
works_not_in_py.parse("`1`")
|
||||
|
||||
|
||||
def test_py2_string_prefixes(works_in_py2):
|
||||
works_in_py2.parse("ur'1'")
|
||||
works_in_py2.parse("Ur'1'")
|
||||
works_in_py2.parse("UR'1'")
|
||||
_invalid_syntax("ru'1'", works_in_py2.version)
|
||||
def test_py2_string_prefixes(works_not_in_py):
|
||||
works_not_in_py.parse("ur'1'")
|
||||
works_not_in_py.parse("Ur'1'")
|
||||
works_not_in_py.parse("UR'1'")
|
||||
_invalid_syntax("ru'1'", works_not_in_py.version)
|
||||
|
||||
|
||||
def py_br(each_version):
|
||||
_parse('br""', each_version)
|
||||
|
||||
|
||||
def test_py3_rb(works_ge_py3):
|
||||
works_ge_py3.parse("rb'1'")
|
||||
works_ge_py3.parse("RB'1'")
|
||||
def test_py3_rb(works_in_py):
|
||||
works_in_py.parse("rb'1'")
|
||||
works_in_py.parse("RB'1'")
|
||||
|
||||
|
||||
def test_left_recursion():
|
||||
|
||||
@@ -411,8 +411,8 @@ def test_backslash():
|
||||
]),
|
||||
]
|
||||
)
|
||||
def test_fstring_token_types(code, types, version_ge_py36):
|
||||
actual_types = [t.type for t in _get_token_list(code, version_ge_py36)]
|
||||
def test_fstring_token_types(code, types, each_version):
|
||||
actual_types = [t.type for t in _get_token_list(code, each_version)]
|
||||
assert types + [ENDMARKER] == actual_types
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user