How to PERMANENTLY escape curly braces in Python format string?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


How to PERMANENTLY escape curly braces in Python format string?



Related: How can I print literal curly-brace characters in python string and also use .format on it?



You need to put double braces ({{, }}) to put literal curly brace characters in a string and use .format() on it.


{{


}}


.format()



Problem is, I have JavaScript in my strings which contain nested curly braces. I use .format() on these strings an undefined number of times in a chain. Like, if some condition is true, format this. If some other condition is true, format this too.


.format()



I can't do this:


'''
<script type="application/javascript" src="//code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script type="application/javascript">
$(document).ready(() => {{{{{
window.top.location.replace('https://www.youtube.com/watch?v=hSlb1ezRqfA');
}}}}});
</script>
'''



Because I don't know how many curly braces I need. The number of .formats() in the chain depends on several conditions that depend on stuff outputed by an external source.


.formats()



I want a way to PERMANENTLY escape curly braces in a Python string. No matter how many times I use .format() on it, the literal braces should never be formatted.


.format()



How to PERMANENTLY escape curly braces in Python format string?



Simplified example (still quite long):



Simple example of problems with complex formatting chains


footerHTML = '''
<footer>
<p>
<strong>&copy;</strong> Copyright 2018, powered by the Stack Exchange API v2.2
</p>
</footer>
'''

def format1(string):
scriptInjection = '''
<script type="application/javascript" src="//code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script type="application/javascript">
$(document).ready(() => {{{
window.top.location.replace('https://www.youtube.com/watch?v=hSlb1ezRqfA');
}}});
</script>
''' if random.randint(0, 10) == random.randint(0, 10) else "{{CONTENT}}"
return content.format(PRANK=scriptInjection)

def format2(string):

# Do something complicated here
# Irrelavent to the question
# Now I have some extra variables now

HTMLcontent = '''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>StackPromo Q&A Stack Exchange Community Content Showcase</title>
<link rel="stylesheet" type="text/css" href="assets/style.css">
<style type="text/css">
* {{
cursor: pointer !important;
}}
#click-overlay {{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
}}
</style>
</head>
<body>
<div id="click-overlay" onclick="window.parent.location.assign('{{postURL}}');"></div>
<h1>{{postTitle}}</h1>
</body>
</html>
'''.format(postURL=post, postTitle=title)

return string.format(CONTENT=HTMLcontent)

class Submit(webapp2.RequestHandler):
def get(self):
self.response.write(format1('''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Enter a post into the StackPromo advertisement service database</title>
<link rel="stylesheet" type="text/css" href="assets/style.css">
{PRANK}
<script type="application/javascript">
$(document).ready(() => {{{
if (window.location.search.includes("error=YES")) {{{
$("body").prepend("<p class='error'><strong>AN ERROR OCCURED!</strong></p><div class='spacer'></div>");
}}}
}}});
</script>
</head>
<body>
<header>
<h1>StackPromo&trade;</h1>
<div class="spacer"></div>
<p>
<em>StackPromo&trade;</em> is a free-to-use advertising platform for Stack Exchange posts!
</p>
</header>
<div class="spacer"></div>
<main>
<form action="/submit" method="POST">
<strong>Post ID:</strong>
<input type="number" name="id">
<div class="spacer"></div>
<strong>Site:</strong>
<select name="site">
<option value="stackoverflow">Stack Overflow</option>
<option value="superuser">Super User</option>
<option value="serverfault">Server Fault</option>
<option value="stackapps">Stack Apps</option>
<option value="ux">User Experience</option>
</select>
<div class="spacer"></div>
<input type="submit" value="Advertise">
</form>
</main>
<div class="spacer"></div>
{{FOOTER}}
</body>
</html>
''').format(FOOTER=footerHTML).format(CONTENT=""))

def post(self):
ID = self.request.get('id', 'garbage')
site = self.request.get('site', 'garbage')
SE_API_AJAX = urlfetch.fetch('https://api.stackexchange.com/2.2/{}?site={}'.format(ID, site), validate_certificate=True)

if SE_API_AJAX.status_code == 200:
newPost = Post()
newPost.postID = ID
newPost.site = site
newPost.initialJSON = SE_API_AJAX.content
newPost.put()

self.response.write(format1('''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Success!</title>
<link rel="stylesheet" type="text/css" href="assets/style.css">
{PRANK}
</head>
<body>
<header>
<h1>Post Successfully Submitted into the StackPromo System</h1>
</header>
<div class="spacer"></div>
<main>
<a href="https://www.youtube.com/watch?v=hSlb1ezRqfA">Click here to go to Stack Apps Post</a>
</main>
<div class="spacer"></div>
{{FOOTER}}
</body>
</html>
''').format(FOOTER=footerHTML).format(CONTENT=""))

else:
self.redirect("/submit?error=YES", code=303)

class Advert(webapp2.RequestHandler):
def get(self):
self.response.write(format2(format1('''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>StackPromo Q&A Stack Exchange Community Content Showcase</title>
<link rel="stylesheet" type="text/css" href="assets/style.css">
{PRANK}
<style type="text/css">
* {{{
cursor: pointer !important;
}}}
#click-overlay {{{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
}}}
</style>
</head>
<body>
<div id="click-overlay" onclick="window.parent.location.assign('{{postURL}}');"></div>
<h1>{{postTitle}}</h1>
</body>
</html>
''')))



What I want is that the curly braces in JavaScript and CSS stay as curly braces and never get formatted no matter how many times I format the string. My current method of using a ton of braces is bad code, non-scalable, and very error-prone (I have errors now).





How does this .format() chain work exactly?
– Ry-
28 mins ago


.format()





As far as I'm aware, you can't. Perhaps you need to think of another way to handle the task than repeated string formating.
– jonrsharpe
27 mins ago


format





You PERMANENTLY shouldn't be using string formatting to generate code. Use a proper templating language.
– Daniel Roseman
27 mins ago





You could PERMANENTLY provide your relevant code in your question.
– scharette
26 mins ago







What is your input and what is expected output? How do you use the format() on the string? We cannot help if we don't know the details.
– Andrej Kesely
21 mins ago


format()









By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

How to scale/resize CVPixelBufferRef in objective C, iOS

Stripe::AuthenticationError No API key provided. Set your API key using “Stripe.api_key = ”

SVG with two text elements. When one resizes due to textLength - how to resize the other one to the same character size