diff -Nru parso-0.8.0/CHANGELOG.rst parso-0.8.1/CHANGELOG.rst --- parso-0.8.0/CHANGELOG.rst 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/CHANGELOG.rst 2020-12-10 15:09:15.000000000 +0000 @@ -6,6 +6,11 @@ Unreleased ++++++++++ +0.8.1 (2020-12-10) +++++++++++++++++++ + +- Various small bugfixes + 0.8.0 (2020-08-05) ++++++++++++++++++ diff -Nru parso-0.8.0/debian/changelog parso-0.8.1/debian/changelog --- parso-0.8.0/debian/changelog 2020-11-13 09:56:26.000000000 +0000 +++ parso-0.8.1/debian/changelog 2020-12-20 21:50:50.000000000 +0000 @@ -1,8 +1,9 @@ -parso (0.8.0-0ubuntu1) hirsute; urgency=medium +parso (0.8.1-1) unstable; urgency=medium * New upstream release. + - works with Python 3.9 (closes: 973193) - -- Matthias Klose Fri, 13 Nov 2020 10:56:26 +0100 + -- Piotr Ożarowski Sun, 20 Dec 2020 22:50:50 +0100 parso (0.7.0-1) unstable; urgency=medium diff -Nru parso-0.8.0/parso/__init__.py parso-0.8.1/parso/__init__.py --- parso-0.8.0/parso/__init__.py 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/parso/__init__.py 2020-12-10 15:09:15.000000000 +0000 @@ -43,7 +43,7 @@ from parso.utils import split_lines, python_bytes_to_unicode -__version__ = '0.8.0' +__version__ = '0.8.1' def parse(code=None, **kwargs): diff -Nru parso-0.8.0/parso/python/errors.py parso-0.8.1/parso/python/errors.py --- parso-0.8.0/parso/python/errors.py 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/parso/python/errors.py 2020-12-10 15:09:15.000000000 +0000 @@ -957,7 +957,11 @@ if '\\' in expr.get_code(): self.add_issue(expr, message=self.message_expr) - conversion = fstring_expr.children[2] + children_2 = fstring_expr.children[2] + if children_2.type == 'operator' and children_2.value == '=': + conversion = fstring_expr.children[3] + else: + conversion = children_2 if conversion.type == 'fstring_conversion': name = conversion.children[1] if name.value not in ('s', 'r', 'a'): diff -Nru parso-0.8.0/parso/python/grammar310.txt parso-0.8.1/parso/python/grammar310.txt --- parso-0.8.0/parso/python/grammar310.txt 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/parso/python/grammar310.txt 2020-12-10 15:09:15.000000000 +0000 @@ -124,14 +124,14 @@ testlist_comp: (namedexpr_test|star_expr) ( comp_for | (',' (namedexpr_test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] -subscript: test | [test] ':' [test] [sliceop] +subscript: test [':=' test] | [test] ':' [test] [sliceop] sliceop: ':' [test] exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] dictorsetmaker: ( ((test ':' test | '**' expr) (comp_for | (',' (test ':' test | '**' expr))* [','])) | - ((test | star_expr) - (comp_for | (',' (test | star_expr))* [','])) ) + ((test [':=' test] | star_expr) + (comp_for | (',' (test [':=' test] | star_expr))* [','])) ) classdef: 'class' NAME ['(' [arglist] ')'] ':' suite @@ -167,5 +167,5 @@ fstring: FSTRING_START fstring_content* FSTRING_END fstring_content: FSTRING_STRING | fstring_expr fstring_conversion: '!' NAME -fstring_expr: '{' testlist ['='] [ fstring_conversion ] [ fstring_format_spec ] '}' +fstring_expr: '{' (testlist_comp | yield_expr) ['='] [ fstring_conversion ] [ fstring_format_spec ] '}' fstring_format_spec: ':' fstring_content* diff -Nru parso-0.8.0/parso/python/grammar36.txt parso-0.8.1/parso/python/grammar36.txt --- parso-0.8.0/parso/python/grammar36.txt 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/parso/python/grammar36.txt 2020-12-10 15:09:15.000000000 +0000 @@ -154,5 +154,5 @@ fstring: FSTRING_START fstring_content* FSTRING_END fstring_content: FSTRING_STRING | fstring_expr fstring_conversion: '!' NAME -fstring_expr: '{' testlist_comp [ fstring_conversion ] [ fstring_format_spec ] '}' +fstring_expr: '{' (testlist_comp | yield_expr) [ fstring_conversion ] [ fstring_format_spec ] '}' fstring_format_spec: ':' fstring_content* diff -Nru parso-0.8.0/parso/python/grammar37.txt parso-0.8.1/parso/python/grammar37.txt --- parso-0.8.0/parso/python/grammar37.txt 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/parso/python/grammar37.txt 2020-12-10 15:09:15.000000000 +0000 @@ -152,5 +152,5 @@ fstring: FSTRING_START fstring_content* FSTRING_END fstring_content: FSTRING_STRING | fstring_expr fstring_conversion: '!' NAME -fstring_expr: '{' testlist [ fstring_conversion ] [ fstring_format_spec ] '}' +fstring_expr: '{' (testlist_comp | yield_expr) [ fstring_conversion ] [ fstring_format_spec ] '}' fstring_format_spec: ':' fstring_content* diff -Nru parso-0.8.0/parso/python/grammar38.txt parso-0.8.1/parso/python/grammar38.txt --- parso-0.8.0/parso/python/grammar38.txt 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/parso/python/grammar38.txt 2020-12-10 15:09:15.000000000 +0000 @@ -167,5 +167,5 @@ fstring: FSTRING_START fstring_content* FSTRING_END fstring_content: FSTRING_STRING | fstring_expr fstring_conversion: '!' NAME -fstring_expr: '{' testlist ['='] [ fstring_conversion ] [ fstring_format_spec ] '}' +fstring_expr: '{' (testlist_comp | yield_expr) ['='] [ fstring_conversion ] [ fstring_format_spec ] '}' fstring_format_spec: ':' fstring_content* diff -Nru parso-0.8.0/parso/python/grammar39.txt parso-0.8.1/parso/python/grammar39.txt --- parso-0.8.0/parso/python/grammar39.txt 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/parso/python/grammar39.txt 2020-12-10 15:09:15.000000000 +0000 @@ -130,8 +130,8 @@ testlist: test (',' test)* [','] dictorsetmaker: ( ((test ':' test | '**' expr) (comp_for | (',' (test ':' test | '**' expr))* [','])) | - ((test | star_expr) - (comp_for | (',' (test | star_expr))* [','])) ) + ((test [':=' test] | star_expr) + (comp_for | (',' (test [':=' test] | star_expr))* [','])) ) classdef: 'class' NAME ['(' [arglist] ')'] ':' suite @@ -167,5 +167,5 @@ fstring: FSTRING_START fstring_content* FSTRING_END fstring_content: FSTRING_STRING | fstring_expr fstring_conversion: '!' NAME -fstring_expr: '{' testlist ['='] [ fstring_conversion ] [ fstring_format_spec ] '}' +fstring_expr: '{' (testlist_comp | yield_expr) ['='] [ fstring_conversion ] [ fstring_format_spec ] '}' fstring_format_spec: ':' fstring_content* diff -Nru parso-0.8.0/parso/python/tokenize.py parso-0.8.1/parso/python/tokenize.py --- parso-0.8.0/parso/python/tokenize.py 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/parso/python/tokenize.py 2020-12-10 15:09:15.000000000 +0000 @@ -110,9 +110,14 @@ _create_token_collection(version_info) return result - -fstring_string_single_line = _compile(r'(?:\{\{|\}\}|\\(?:\r\n?|\n)|[^{}\r\n])+') -fstring_string_multi_line = _compile(r'(?:[^{}]+|\{\{|\}\})+') +unicode_character_name = r'[A-Za-z0-9\-]+(?: [A-Za-z0-9\-]+)*' +fstring_string_single_line = _compile( + r'(?:\{\{|\}\}|\\N\{' + unicode_character_name + + r'\}|\\(?:\r\n?|\n)|\\[^\r\nN]|[^{}\r\n\\])+' +) +fstring_string_multi_line = _compile( + r'(?:\{\{|\}\}|\\N\{' + unicode_character_name + r'\}|\\[^N]|[^{}\\])+' +) fstring_format_spec_single_line = _compile(r'(?:\\(?:\r\n?|\n)|[^{}\r\n])+') fstring_format_spec_multi_line = _compile(r'[^{}]+') diff -Nru parso-0.8.0/parso/python/tree.py parso-0.8.1/parso/python/tree.py --- parso-0.8.0/parso/python/tree.py 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/parso/python/tree.py 2020-12-10 15:09:15.000000000 +0000 @@ -775,8 +775,8 @@ return names def get_test_node_from_name(self, name): - node = name.parent - if node.type != 'with_item': + node = search_ancestor(name, "with_item") + if node is None: raise ValueError('The name is not actually part of a with statement.') return node.children[0] diff -Nru parso-0.8.0/parso.egg-info/PKG-INFO parso-0.8.1/parso.egg-info/PKG-INFO --- parso-0.8.0/parso.egg-info/PKG-INFO 2020-08-04 22:52:03.000000000 +0000 +++ parso-0.8.1/parso.egg-info/PKG-INFO 2020-12-10 15:10:12.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: parso -Version: 0.8.0 +Version: 0.8.1 Summary: A Python Parser Home-page: https://github.com/davidhalter/parso Author: David Halter @@ -113,6 +113,11 @@ Unreleased ++++++++++ + 0.8.1 (2020-12-10) + ++++++++++++++++++ + + - Various small bugfixes + 0.8.0 (2020-08-05) ++++++++++++++++++ diff -Nru parso-0.8.0/PKG-INFO parso-0.8.1/PKG-INFO --- parso-0.8.0/PKG-INFO 2020-08-04 22:52:04.107161800 +0000 +++ parso-0.8.1/PKG-INFO 2020-12-10 15:10:12.660451400 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: parso -Version: 0.8.0 +Version: 0.8.1 Summary: A Python Parser Home-page: https://github.com/davidhalter/parso Author: David Halter @@ -113,6 +113,11 @@ Unreleased ++++++++++ + 0.8.1 (2020-12-10) + ++++++++++++++++++ + + - Various small bugfixes + 0.8.0 (2020-08-05) ++++++++++++++++++ diff -Nru parso-0.8.0/test/failing_examples.py parso-0.8.1/test/failing_examples.py --- parso-0.8.0/test/failing_examples.py 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/test/failing_examples.py 2020-12-10 15:09:15.000000000 +0000 @@ -356,4 +356,12 @@ '(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}'", ] diff -Nru parso-0.8.0/test/test_fstring.py parso-0.8.1/test/test_fstring.py --- parso-0.8.0/test/test_fstring.py 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/test/test_fstring.py 2020-12-10 15:09:15.000000000 +0000 @@ -60,6 +60,24 @@ # a line continuation inside of an format spec 'f"{123:.2\\\nf}"', + + # some unparenthesized syntactic structures + 'f"{*x,}"', + 'f"{*x, *y}"', + 'f"{x, *y}"', + 'f"{*x, y}"', + 'f"{x for x in [1]}"', + + # named unicode characters + 'f"\\N{BULLET}"', + 'f"\\N{FLEUR-DE-LIS}"', + 'f"\\N{NO ENTRY}"', + 'f"Combo {expr} and \\N{NO ENTRY}"', + 'f"\\N{NO ENTRY} and {expr}"', + 'f"\\N{no entry}"', + 'f"\\N{SOYOMBO LETTER -A}"', + 'f"\\N{DOMINO TILE HORIZONTAL-00-00}"', + 'f"""\\N{NO ENTRY}"""', ] ) def test_valid(code, grammar): @@ -79,6 +97,7 @@ # invalid conversion characters 'f"{1!{a}}"', + 'f"{1=!{a}}"', 'f"{!{a}}"', # The curly braces must contain an expression @@ -96,6 +115,11 @@ # a newline without a line continuation inside a single-line string 'f"abc\ndef"', + + # various named unicode escapes that aren't name-shaped + 'f"\\N{ BULLET }"', + 'f"\\N{NO ENTRY}"', + 'f"""\\N{NO\nENTRY}"""', ] ) def test_invalid(code, grammar): @@ -114,6 +138,8 @@ (1, 10), (1, 11), (1, 12), (1, 13)]), ('f"""\n {\nfoo\n }"""', [(1, 0), (1, 4), (2, 1), (3, 0), (4, 1), (4, 2), (4, 5)]), + ('f"\\N{NO ENTRY} and {expr}"', [(1, 0), (1, 2), (1, 19), (1, 20), + (1, 24), (1, 25), (1, 26)]), ] ) def test_tokenize_start_pos(code, positions): diff -Nru parso-0.8.0/test/test_parser_tree.py parso-0.8.1/test/test_parser_tree.py --- parso-0.8.0/test/test_parser_tree.py 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/test/test_parser_tree.py 2020-12-10 15:09:15.000000000 +0000 @@ -229,3 +229,13 @@ module = parse(code, version='3.8') func_names = [f.name.value for f in module.iter_funcdefs()] assert func_names == ['normal', 'asyn', 'dec_normal', 'dec_async'] + + +def test_with_stmt_get_test_node_from_name(): + code = "with A as X.Y, B as (Z), C as Q[0], D as Q['foo']: pass" + with_stmt = parse(code, version='3').children[0] + tests = [ + with_stmt.get_test_node_from_name(name).value + for name in with_stmt.get_defined_names(include_setitem=True) + ] + assert tests == ["A", "B", "C", "D"] diff -Nru parso-0.8.0/test/test_python_errors.py parso-0.8.1/test/test_python_errors.py --- parso-0.8.0/test/test_python_errors.py 2020-08-04 22:51:23.000000000 +0000 +++ parso-0.8.1/test/test_python_errors.py 2020-12-10 15:09:15.000000000 +0000 @@ -274,6 +274,8 @@ r'fr"\""', r'fr"\\\""', r"print(f'Some {x:.2f} and some {y}')", + # Unparenthesized yield expression + 'def foo(): return f"{yield 1}"', ] ) def test_valid_fstrings(code): @@ -287,6 +289,11 @@ '[total := total + v for v in range(10)]', 'while chunk := file.read(2):\n pass', 'numbers = [y := math.factorial(x), y**2, y**3]', + '{(a:="a"): (b:=1)}', + '{(y:=1): 2 for x in range(5)}', + 'a[(b:=0)]', + 'a[(b:=0, c:=0)]', + 'a[(b:=0):1:2]', ] ) def test_valid_namedexpr(code): @@ -294,6 +301,26 @@ @pytest.mark.parametrize( + 'code', [ + '{x := 1, 2, 3}', + '{x4 := x ** 5 for x in range(7)}', + ] +) +def test_valid_namedexpr_set(code): + assert not _get_error_list(code, version='3.9') + + +@pytest.mark.parametrize( + 'code', [ + 'a[b:=0]', + 'a[b:=0, c:=0]', + ] +) +def test_valid_namedexpr_index(code): + assert not _get_error_list(code, version='3.10') + + +@pytest.mark.parametrize( ('code', 'message'), [ ("f'{1+}'", ('invalid syntax')), (r'f"\"', ('invalid syntax')),