8000 Implement partial PEP-498 (f-string) support by jepler · Pull Request #2690 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content

Implement partial PEP-498 (f-string) support #2690

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

Merged
merged 6 commits into from
Mar 10, 2020

Conversation

jepler
Copy link
@jepler jepler commented Mar 9, 2020

I've taken a shot at updating #2054:

  • rebased on master
  • make the code optional so we can disable it on small targets (code may still grow ~20 bytes?)
  • Fix the edge case concatenation so it's a parse-time error
  • update locales
  • update some tests
  • remove unintended updates of some submodules

klardotsh and others added 5 commits March 9, 2020 08:16
This implements (most of) the PEP-498 spec for f-strings, with two
exceptions:

- raw f-strings (`fr` or `rf` prefixes) raise `NotImplementedError`
- one special corner case does not function as specified in the PEP
(more on that in a moment)

This is implemented in the core as a syntax translation, brute-forcing
all f-strings to run through `String.format`. For example, the statement
`x='world'; print(f'hello {x}')` gets translated *at a syntax level*
(injected into the lexer) to `x='world'; print('hello {}'.format(x))`.
While this may lead to weird column results in tracebacks, it seemed
like the fastest, most efficient, and *likely* most RAM-friendly option,
despite being implemented under the hood with a completely separate
`vstr_t`.

Since [string concatenation of adjacent literals is implemented in the
lexer](micropython@534b7c3),
two side effects emerge:

- All strings with at least one f-string portion are concatenated into a
single literal which *must* be run through `String.format()` wholesale,
and:
- Concatenation of a raw string with interpolation characters with an
f-string will cause `IndexError`/`KeyError`, which is both different
from CPython *and* different from the corner case mentioned in the PEP
(which gave an example of the following:)

```python
x = 10
y = 'hi'
assert ('a' 'b' f'{x}' '{c}' f'str<{y:^4}>' 'd' 'e') == 'ab10{c}str< hi >de'
```

The above-linked commit detailed a pretty solid case for leaving string
concatenation in the lexer rather than putting it in the parser, and
undoing that decision would likely be disproportionately costly on
resources for the sake of a probably-low-impact corner case. An
alternative to become complaint with this corner case of the PEP would
be to revert to string concatenation in the parser *only when an
f-string is part of concatenation*, though I've done no investigation on
the difficulty or costs of doing this.

A decent set of tests is included. I've manually tested this on the
`unix` port on Linux and on a Feather M4 Express (`atmel-samd`) and
things seem sane.
This turns the "edge case" into a parse-time error.
This should reclaim *most* code space added to handle f-strings.
However, there may be some small code growth as parse_string_literal
takes a new parameter (which will always be 0, so hopefully the optimizer
eliminates it)
 * string_pep498_fstring.py: Not compatible with python3.5
 * cmd_parsetree.py: enumerated constants changed
@jepler jepler force-pushed the topic-pep-498-fstrings branch from 21bee01 to ef195d6 Compare March 10, 2020 02:13
@jepler jepler requested a review from tannewt March 10, 2020 03:56
@jepler jepler changed the title Topic pep 498 fstrings Implement partial PEP-498 (f-string) support Mar 10, 2020
Copy link
Member
@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

Thanks for dusting this off! Thanks to @klardotsh for the original PR. I know everyone will be excited for the f-string future! @brettcannon asked me about this at PyCon last year.

@tannewt tannewt merged commit d988af0 into adafruit:master Mar 10, 2020
@jepler jepler deleted the topic-pep-498-fstrings branch November 3, 2021 21:10
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
0