Skip to content

Avoid creating unused JoinedStr in FStringParser - #4116

Merged
youknowone merged 2 commits into
RustPython:mainfrom
astral-sh:charlie/f-string
Aug 23, 2022
Merged

youknowone merged 2 commits into
RustPython:mainfrom
astral-sh:charlie/f-string

Conversation

@charliermarsh

Copy link
Copy Markdown
Collaborator

Summary

Per discussion in #4097, we can now avoid creating a JoinedStr entirely when parsing f-strings, and instead return the vector of values.

Comment thread parser/src/fstring.rs
kind: None,
}));
constant_piece.clear();
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was another difference I noticed.

In CPython, you get:

>>> import ast
>>> print(ast.dump(ast.parse('f"{foo:{spec}}"')))
Module(body=[Expr(value=JoinedStr(values=[FormattedValue(value=Name(id='foo', ctx=Load()), conversion=-1, format_spec=JoinedStr(values=[FormattedValue(value=Name(id='spec', ctx=Load()), conversion=-1)]))]))], type_ignores=[])

Prior to this change, the RustPython AST was similar, except that the inner FormattedValue was padded by an empty Constant on both sides.

@youknowone

Copy link
Copy Markdown
Member

parser/src/fstring.rs conflicts to #4101
could you rebase it to see CI result?

Snapshots will make annoying conflicts. My suggestion is to remove them from the current working commit and rebase it only with fstring.rs
(git checkout upstream/main -- parser/src/snapshots/* && git add parser/src/snapshots/ && git commit --ame)

@charliermarsh

Copy link
Copy Markdown
Collaborator Author

Yup, on it.

@charliermarsh
charliermarsh force-pushed the charlie/f-string branch 2 times, most recently from a6479dc to e3f4531 Compare August 21, 2022 19:49
@charliermarsh

Copy link
Copy Markdown
Collaborator Author

Looking into a few of the test failures.

Comment thread parser/src/fstring.rs Resolved
Comment thread parser/src/fstring.rs Outdated
.parse()?,
),
.parse()?
})),

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This yields a slightly different AST than CPython, we're returning a FormattedValue(JoinedStr(FormattedValue( whereas CPython just returns a FormattedValue.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We thought the return type can be changed, but maybe actually not? I thought The returned JoinedStr is always a vector of strings, but it seems it had a nested structure.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, although the returned JoinedStr can either contain FormattedValue, Constant, or JoinedStr, right? I think the code as-written does work, it just includes some additional nesting (but still fewer levels than before IIUC).

@charliermarsh charliermarsh Aug 22, 2022 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As written, this does now return format_spec: Some(JoinedStr(FormattedValue(, just like CPython. (The exactly_one enforcement / unwrapping was necessary, AFAICT.)

@youknowone

Copy link
Copy Markdown
Member

I am really sorry but I just finished massive relocation from #4119. parser directory is moved under compiler/parser.
Could you please rebase once again like before without snapshots?
These kinds of big changes will not happen again for a while - I promise.

@charliermarsh

Copy link
Copy Markdown
Collaborator Author

Yeah no worries!

@charliermarsh
charliermarsh force-pushed the charlie/f-string branch 4 times, most recently from 6d3b320 to f37bb55 Compare August 21, 2022 22:34

@youknowone youknowone left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok with ast incompatibility if its behavior is the same.

@coolreader18 how do you think about it?

.parse()?;
spec_constructor.push(values
.into_iter()
.exactly_one()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worried if this is possible to be broken, but ExpressionNestedTooDeeply seems to prevent it successfully.

@fanninpm

Copy link
Copy Markdown
Contributor

As an aside, how far does RustPython get through https://github.com/python/cpython/blob/3.10/Lib/test/test_fstring.py without raising a SyntaxError and bailing out?

@youknowone youknowone left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great. I misunderstood the changed test. So the ast seems fully compatible now.

@youknowone
youknowone merged commit 6b31ed3 into RustPython:main Aug 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants