Repository navigation
Closed
Labels
A-compilerArea: compilerArea: compilerC-compatA discrepancy between RustPython and CPythonA discrepancy between RustPython and CPython
Description
The AST produced by RustPython differs from CPython when parsing implicitly concatenated strings.
For example, given this source:
import ast
expr = """(
'Hello, '
'world!'
)"""
print(ast.dump(ast.parse(expr), include_attributes=True))CPython produces a single Constant, with a value equal to the concatenated strings:
Expr(value=Constant(value='Hello, world!', kind=None, lineno=2, col_offset=4, end_lineno=3, end_col_offset=12), lineno=1, col_offset=0, end_lineno=4, end_col_offset=1)
Whereas RustPython produces a JoinedStr consisting of two Constant sub-expressions:
Expr { value: Located { location: Location { row: 2, column: 6 }, custom: (), node: JoinedStr { values: [Located { location: Location { row: 2, column: 6 }, custom: (), node: Constant { value: Str("Hello, "), kind: None } }, Located { location: Location { row: 3, column: 6 }, custom: (), node: Constant { value: Str("world!"), kind: None } }] } } }
There are some other differences too, e.g.:
- CPython seems to propagate the string kind of the first substring. So if the first substring is
u'Hello, ', then the whole thing will be treated as Unicode. If the second substring isu'world!', CPython drops theuentirely. (I found this surprising.) - If any of the substrings are f-strings, CPython returns a
JoinedStr, but exhibits the same constant-collapsing as in the provided example.
As far as I can tell, the rules are (roughly):
- If every substring is a
Constant, return a singleConstantwith the substrings concatened. - If any substring is an f-string, return a
JoinedStr, then flatten out the values into that top-levelJoinedStr, collapsing any adjacentConstantexpressions, so that you're left withConstantexpressions interspersed withFormattedValueexpressions. - If the first substring has a "kind", apply that "kind" to any
Constantexpressions.
(I haven't been able to find this in any documentation, only from testing out CPython 3.8.12 itself.)
Happy to attempt a PR, unless this behavior is intentional.
(By the way: very impressive project!)
Reacted by Jeong, YunWon
Metadata
Metadata
Assignees
Labels
A-compilerArea: compilerArea: compilerC-compatA discrepancy between RustPython and CPythonA discrepancy between RustPython and CPython
Activity
charliermarsh commentedon Aug 17, 2022
I think this can be fixed by modifying the
<location:@L> <s:(@L string)+> =>?case in the LALRPOP file.charliermarsh commentedon Aug 18, 2022
Made an attempt with #4097.