diff --git a/parso/python/grammar26.txt b/parso/python/grammar26.txt index b972a41..d9cede2 100644 --- a/parso/python/grammar26.txt +++ b/parso/python/grammar26.txt @@ -119,7 +119,8 @@ atom: ('(' [yield_expr|testlist_comp] ')' | '[' [listmaker] ']' | '{' [dictorsetmaker] '}' | '`' testlist1 '`' | - NAME | NUMBER | STRING+) + NAME | NUMBER | strings) +strings: STRING+ listmaker: test ( list_for | (',' test)* [','] ) # Dave: Renamed testlist_gexpr to testlist_comp, because in 2.7+ this is the # default. It's more consistent like this. diff --git a/parso/python/grammar27.txt b/parso/python/grammar27.txt index 4c3f33d..359f12b 100644 --- a/parso/python/grammar27.txt +++ b/parso/python/grammar27.txt @@ -104,7 +104,8 @@ atom: ('(' [yield_expr|testlist_comp] ')' | '[' [listmaker] ']' | '{' [dictorsetmaker] '}' | '`' testlist1 '`' | - NAME | NUMBER | STRING+) + NAME | NUMBER | strings) +strings: STRING+ listmaker: test ( list_for | (',' test)* [','] ) testlist_comp: test ( comp_for | (',' test)* [','] ) lambdef: 'lambda' [varargslist] ':' test diff --git a/parso/python/grammar33.txt b/parso/python/grammar33.txt index d7aaffd..3a55809 100644 --- a/parso/python/grammar33.txt +++ b/parso/python/grammar33.txt @@ -103,7 +103,8 @@ power: atom trailer* ['**' factor] atom: ('(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | - NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False') + NAME | NUMBER | strings | '...' | 'None' | 'True' | 'False') +strings: STRING+ testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] diff --git a/parso/python/grammar34.txt b/parso/python/grammar34.txt index 05c3181..324bba1 100644 --- a/parso/python/grammar34.txt +++ b/parso/python/grammar34.txt @@ -103,7 +103,8 @@ power: atom trailer* ['**' factor] atom: ('(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | - NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False') + NAME | NUMBER | strings | '...' | 'None' | 'True' | 'False') +strings: STRING+ testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] diff --git a/parso/python/grammar35.txt b/parso/python/grammar35.txt index c38217f..5868b8f 100644 --- a/parso/python/grammar35.txt +++ b/parso/python/grammar35.txt @@ -110,7 +110,8 @@ atom_expr: ['await'] atom trailer* atom: ('(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | - NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False') + NAME | NUMBER | strings | '...' | 'None' | 'True' | 'False') +strings: STRING+ testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] diff --git a/parso/python/parser.py b/parso/python/parser.py index 1897f53..4eb9241 100644 --- a/parso/python/parser.py +++ b/parso/python/parser.py @@ -1,6 +1,6 @@ from parso.python import tree from parso.python.token import (DEDENT, INDENT, ENDMARKER, NEWLINE, NUMBER, - STRING, tok_name, NAME) + STRING, tok_name, NAME, FSTRING_STRING) from parso.parser import BaseParser from parso.pgen2.parse import token_to_ilabel @@ -129,6 +129,8 @@ class Parser(BaseParser): return tree.Newline(value, start_pos, prefix) elif type == ENDMARKER: return tree.EndMarker(value, start_pos, prefix) + elif type == FSTRING_STRING: + return tree.FStringString(value, start_pos, prefix) else: return tree.Operator(value, start_pos, prefix) diff --git a/parso/python/tree.py b/parso/python/tree.py index eb97780..075505f 100644 --- a/parso/python/tree.py +++ b/parso/python/tree.py @@ -262,6 +262,15 @@ class String(Literal): return match.group(2)[:-len(match.group(1))] +class FStringString(Leaf): + """ + f-strings contain f-string expressions and normal python strings. These are + the string parts of f-strings. + """ + type = 'fstring_string' + __slots__ = () + + class _StringComparisonMixin(object): def __eq__(self, other): """