How to Escape Curly Braces in Python Format Strings

To escape curly braces in Python format strings, double them: {{ prints { and }} prints }. The rule is the same for f-strings and str.format(), and single braces stay placeholders:

print(f"{{city}} is literal, {city} is the value")   # {city} is literal, Austin is the value

Every snippet here was run on Python 3.12.5, plus Python 3.14 for the new template strings near the end.

We’ll cover doubled braces, putting braces around a value, the errors a lone brace causes, and when it’s easier to avoid format strings entirely, such as for JSON.

Escape curly braces in f-strings and str.format()

Python reads { as the start of a replacement field. Writing it twice tells the parser you want the character itself:

city, total = "Austin", 249.5

print(f"{{city}} is a placeholder; the real value is {city}")
print("Order total: {{ ${:.2f} }}".format(total))
print("{{}} prints {}".format("empty braces"))

Output:

{city} is a placeholder; the real value is Austin
Order total: { $249.50 }
{} prints empty braces
Command Prompt output of Python f-string and str.format printing literal curly braces with doubled braces
Doubled braces come out as single literal braces, while single braces are still filled in.

{{}} on its own prints {}, which trips people up when they expect an empty placeholder. If you’re new to f-strings, start with creating a string with variables in Python.

Put curly braces around a value (triple braces)

To print a value wrapped in braces, like {TX}, you need three on each side: two for the literal brace and one for the placeholder. Format specs still work inside:

state, price = "TX", 19.99

print(f"{{{state}}}")                 # outer pair = literal braces, inner = the value
print(f"{{price: {price:.2f}}}")      # braces around a formatted number
print("{{{0}}}".format("Denver"))    # same rule in str.format

Output:

{TX}
{price: 19.99}
{Denver}
Command Prompt output of Python f-strings using triple curly braces to wrap a variable and a formatted price in braces
Triple braces wrap the value in literal braces; :.2f still formats the price.

Read it from the inside out: {state} is the value, and the extra pair on each side is the escaped brace. Number formatting like .2f is covered in printing 2 decimal places in Python.

Errors from a single curly brace

Forget to double a brace and you’ll get one of three errors, depending on the method. Here they are, caught so the script keeps going:

code = 'f"Total: {price}}"'
try:
    compile(code, "<order>", "eval")
except SyntaxError as err:
    print("SyntaxError:", err.msg)

try:
    print("Discount }: {}".format(10))
except ValueError as err:
    print("ValueError:", err)

template = '{"customer": "{name}", "state": "TX"}'
try:
    print(template.format(name="Emily"))
except KeyError as err:
    print("KeyError:", err)

Output:

SyntaxError: f-string: single '}' is not allowed
ValueError: Single '}' encountered in format string
KeyError: '"customer"'
Command Prompt output of Python errors for a single curly brace: f-string SyntaxError, str.format ValueError and KeyError from a JSON template
An f-string fails before running; str.format() raises ValueError for a stray } and KeyError when JSON braces look like placeholders.

That last KeyError is the sneaky one. Python sees {"customer"...} as a field named "customer" and goes looking for it.

Reading tracebacks like these is easier once you know how escape sequences work in Python, since quotes and backslashes cause similar surprises.

Avoid brace escaping with json.dumps and string.Template

When the text is full of braces, like JSON, CSS or JavaScript, escaping every one gets unreadable. Use a tool that doesn’t treat braces as special:

import json
from string import Template

customer = {"name": "Emily Clark", "state": "TX", "balance": 249.5}

print(json.dumps(customer))                                   # no brace escaping needed

css = Template(".banner { color: $color; font-size: ${size}px; }")
print(css.substitute(color="navy", size=18))                  # $ placeholders, braces stay literal

print("%s owes $%.2f {due Friday}" % (customer["name"], customer["balance"]))

Output:

{"name": "Emily Clark", "state": "TX", "balance": 249.5}
.banner { color: navy; font-size: 18px; }
Emily Clark owes $249.50 {due Friday}
Command Prompt output of Python json.dumps, string.Template with dollar placeholders, and percent formatting leaving curly braces untouched
json.dumps() handles quoting, Template uses $ placeholders, and % formatting ignores braces.

I always build JSON with json.dumps(); it also escapes quotes inside values, which hand-written f-strings often get wrong. For writing the result to disk, see writing a string to a file in Python.

Curly braces in Python 3.14 template strings

Python 3.14 adds template strings, written t"...". They follow the same rule, so {{ is still a literal brace:

import sys
from string.templatelib import Template

name = "Emily"
t = t"{{literal}} and {name}"          # template string (Python 3.14+)
print(type(t).__name__, t.strings, [i.value for i in t.interpolations])
print(sys.version.split()[0])

Output:

Template ('{literal} and ', '') ['Emily']
3.14.8

A t-string returns a Template object instead of a finished string, so libraries can process the values safely before joining them. For printing values next to text in older versions, see printing a string and a variable in Python.

Curly brace rules at a glance

You wantWrite
A literal { or }{{ or }}
A value inside bracesf"{{{value}}}"
Literal {}{{}}
JSON textjson.dumps(data)
Text full of braces with a few valuesstring.Template with $name

These string guides go well with this one:

Frequently asked questions

How do I escape curly braces in a Python f-string?

Double them: {{ prints { and }} prints }, for example f"{{name}}".

How do I escape braces in str.format()?

The same way, with doubled braces: "{{}} {}".format(x) prints {} followed by x.

How do I print a variable inside curly braces?

Use three braces on each side: f"{{{state}}}" prints {TX}.

Why do I get KeyError when formatting a JSON string?

str.format() treats the JSON braces as placeholders. Double them, or build the JSON with json.dumps().

Does % formatting need curly braces escaped?

No. Only % is special there; braces print as normal characters.

Where is the format string syntax documented?

See Format String Syntax in the Python docs.