-
-
Notifications
You must be signed in to change notification settings - Fork 3k
[mypyc] Refactor: reuse format string parser #10894
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! This reduces duplicated functionality and thus reduces the code that needs to be maintained, and it will be easier to support new format string features in mypyc as the parsing is already implemented.
Left a few minor comments, otherwise looks good.
mypyc/irbuild/specialize.py
Outdated
# The empty Context and MessageBuilder for parse_format_value(). | ||
# They wouldn't be used since the code has passed the type-checking. | ||
EMPTY_CONTEXT = Context() | ||
EMPTY_MSG = MessageBuilder(Errors(), {'': MypyFile([], [])}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is mutable, it would be better to create this on each translate_str_format
call. We don't want to risk accumulating state here.
Why do we need the '': MypyFile(...)
entry in the dictionary? What happens if we leave it out? If we actually need it, please add a comment explaining why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I mark EMPTY_MSG
as Final
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't help -- see my other comment.
mypyc/irbuild/specialize.py
Outdated
if not can_optimize_format(format_str): | ||
return None | ||
specifiers = parse_format_value(format_str, EMPTY_CONTEXT, EMPTY_MSG) | ||
assert specifiers is not None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may not be safe to do. For example, what if there is a malformed format string and the error has been # type: ignore
d? I think that it would be better to fall back to the default slow path but still generate IR if we can't parse the format string. What do you think?
mypyc/irbuild/specialize.py
Outdated
# The empty Context and MessageBuilder for parse_format_value(). | ||
# They wouldn't be used since the code has passed the type-checking. | ||
EMPTY_CONTEXT: Final = Context() | ||
EMPTY_MSG: Final = MessageBuilder(Errors(), {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making EMPTY_MSG
final doesn't help with the issue I mentioned earlier. Errors()
is mutable, so it's now shared mutable state, which we want to usually avoid. Please create MessageBuilder
and Errors
within translate_str_format
to avoid the global state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good now!
[mypyc] Refactor: reuse format string parser (python#10894)
Description
parse_conversion_specifiers
andparse_format_value
frommypy.checkstrformat
can be reused when compiling string formatting.can_optimize_format
andsplit_braces
are useless now.Adding a
start_pos
as an attribute ofConversionSpecifier
can not only help parse literals but also help generate useful error messages in the future.Test Plan