Skip to content

Unexpected whitespace handling in f-string !r #93283

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

Closed
dimaqq opened this issue May 27, 2022 · 8 comments · Fixed by #93349
Closed

Unexpected whitespace handling in f-string !r #93283

dimaqq opened this issue May 27, 2022 · 8 comments · Fixed by #93349
Labels
3.10 only security fixes 3.11 only security fixes 3.12 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement

Comments

@dimaqq
Copy link
Contributor

dimaqq commented May 27, 2022

Bug report

The handling of whitespace around the argument in literal string interpolation (f-string) is unexpected when a conversion specifier (e.g. !r) is applied.

Consider

f"{None}"  # OK
f"{ None }"  # OK
f"{None!r}"  # OK
f"{ None!r }"  # SyntaxError

# details
f"{ None!r}  # OK
f"{None !r}  # OK
f"{None!r }  # SyntaxError

PEP-498 states:

Leading and trailing whitespace in expressions is ignored
For ease of readability, leading and trailing whitespace in expressions is ignored. This is a by-product of enclosing the expression in parentheses before evaluation.

I suppose that the text above may be technically accurate, but is misleading to common folk:
In the example above, None is enclosed in parentheses (None) but not None!r.

There are no mentions of whitespace in the rest of the PEP.

Formal reproducer:

> python3.11 -c 'print(f"{ None!r }")'
  File "<string>", line 1
    print(f"{ None!r }")
                       ^
SyntaxError: f-string: expecting '}'

Your environment

  • CPython versions tested on: 3.8, 3.9, 3.10, 3.11a2, 3.11a7
  • Operating system and architecture: Linux, MacOS
@dimaqq dimaqq added the type-bug An unexpected behavior, bug, or error label May 27, 2022
@dimaqq
Copy link
Contributor Author

dimaqq commented May 27, 2022

cc @pablogsal b/c 2022 PSL f-string grammar

@dimaqq
Copy link
Contributor Author

dimaqq commented May 27, 2022

cc @ericvsmith who continues to gather feefback

@ericvsmith
Copy link
Member

The space in the statements with a syntax error above is not part of the expression, it's part of the conversion specifier. I do not want to weaken the parsing here, and I do not consider this a bug. I suppose we could improve the error message, and a quick search doesn't show a test for this. There is a test for a space in f'{3! s}', which could be expanded to also raise an error for a trailing space.

@AA-Turner AA-Turner added type-feature A feature request or enhancement interpreter-core (Objects, Python, Grammar, and Parser dirs) 3.11 only security fixes 3.10 only security fixes 3.12 only security fixes and removed type-bug An unexpected behavior, bug, or error labels May 27, 2022
@AA-Turner
Copy link
Member

Marking as a feature request for a better error message or better documentation, given a core developer has noted this is not a bug.

A

@dimaqq
Copy link
Contributor Author

dimaqq commented May 28, 2022

A side note on multi-line f-strings.
Current rules only allow these:

f"""{
  None
}"""
c = f"""{
  None
!r}"""

but not this:

d = f"""{
  None!r
}"""

I feel that the developer experience is subpar here.
At the same time, I feel that conversion specifiers are a bit of an afterthought anyway 🤷🏿

@ericvsmith
Copy link
Member

I can assure you that conversion specifiers were not an afterthought. They come from PEP 3101 (16 years ago), and were present from the beginning.

If the error message were "Unknown conversion specifier 'r\n'", would that not make it clear enough what the problem is?

@dimaqq
Copy link
Contributor Author

dimaqq commented Jun 1, 2022

I apologize, I must have misread the spec and I was under the impression that {repr(a)} was preferred over {a!r} and {str(a)} over {a!s}.

@ericvsmith
Copy link
Member

The spec has no preference: either way works. It’s just a style thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.10 only security fixes 3.11 only security fixes 3.12 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-feature A feature request or enhancement
Projects
None yet
3 participants