Skip to content
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

py: Implement partial PEP-498 (f-string) support #4998

Commits on May 16, 2020

  1. py: Implement partial PEP-498 (f-string) support

    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.
    klardotsh committed May 16, 2020
    Copy the full SHA
    600051d View commit details
    Browse the repository at this point in the history