Search code examples
pythonf-string

Why can't I call dict.get() in f-string? (Python 3.8.1)


Question

Does anybody have a beginner-friendly explanation as to why I get a SyntaxError when I call .get() from within an f-string in Python >3.8?

Problem

When I call dict.get() directly within the f-string I get a SyntaxError. If I store the dict.get() call in a variable and reference the variable in the f-string it works without error.

This works

def new_item():
    desc = request.form.get('description', 'No description found')
    return f'Your new item to insert\nDescription:{desc}'

http://127.0.0.1:5000/new_item displays:

 Website returning form['description']

This doesn't work

def new_item():
    return f'Your new item to insert\nDescription:{request.form.get('description', 'No description found')}'

SyntaxError: invalid syntax

File ".\server.py", line 39
    return f'Your new item to insert\nDescription:{request.form.get('description', 'No description found')}'
                                                             ^

My Research

StackOverflow is littered with questions (here, here, here, here) and/or problems that were solved simply by calling an adequate Python version. I do have such a Python version installed and am calling also the appropriate command (in fact, the f-string works in an example above). Anyways, here's the powershell:

> python
Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64 bit (AMD64)] on win32

Solution

  • After some additional research (see here), the solution to my problem is the following:

    I'm calling the dictionary property with a single quoted string. The f-string literal interprets the single-quote as the end of the string and subsequently throws a SyntaxError.

    Solution

    1) Instead of calling the dictionary property with a single quote, call it with a double-quote, like so:

    def new_item():
        return f'Your new item to insert\nDescription:{request.form.get("description", "No description found")}'
    

    As @Todd pointed out in the comment there are more solutions. For the sake of completeness:

    2) Invert 1) -- Use a double-quote for the f-string and single one for any strings inside it.

    3) Use backslashes \ to escape the quote char

    4) Use triple double quotes on the string and then anything inside it

    5) Store the dictionary values separately (just like in the working solution in the question). As @chepner points out this has the advantage of respecting max line length limit and improving readability.

    --

    Thank you all for contributing via comments. I've upvoted.