Handle {{ }} escape, but when appropriate

This commit is contained in:
rocky
2019-05-13 09:35:47 -04:00
parent 1cc08d9598
commit 8b5e0f49f8
4 changed files with 36 additions and 1 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -39,6 +39,30 @@ source = 'foo'
source = (f"__file__ = r'''{os.path.abspath(filename)}'''\n" source = (f"__file__ = r'''{os.path.abspath(filename)}'''\n"
+ source + "\ndel __file__") + source + "\ndel __file__")
# From 3.7.3 datalasses.py # Note how { and } are *not* escaped here
f = 'one'
name = 'two'
assert(f"{f}{'{{name}}'} {f}{'{name}'}") == 'one{{name}} one{name}'
# From 3.7.3 dataclasses.py
log_rounds = 5 log_rounds = 5
assert "05$" == f'{log_rounds:02d}$' assert "05$" == f'{log_rounds:02d}$'
def testit(a, b, l):
# print(l)
return l
# The call below shows the need for BUILD_STRING to count expr arguments.
# Also note that we use {{ }} to escape braces in contrast to the example
# above.
def _repr_fn(fields):
return testit('__repr__',
('self',),
['return xx + f"(' +
', '.join([f"{f}={{self.{f}!r}}"
for f in fields]) +
')"'])
fields = ['a', 'b', 'c']
assert _repr_fn(fields) == ['return xx + f"(a={self.a!r}, b={self.b!r}, c={self.c!r})"']

View File

@@ -476,8 +476,19 @@ def customize_for_version36(self, version):
value = self.traverse(expr, indent='') value = self.traverse(expr, indent='')
if expr[0].kind.startswith('formatted_value'): if expr[0].kind.startswith('formatted_value'):
# remove leading 'f' # remove leading 'f'
assert value.startswith('f')
value = value[1:] value = value[1:]
pass pass
else:
# {{ and }} in Python source-code format strings mean
# { and } respectively. But only when *not* part of a
# formatted value. However in the LOAD_CONST
# bytecode, the escaping of the braces has been
# removed. So we need to put back the braces escaping in
# reconstructing the source.
assert expr[0] == 'LOAD_CONST'
value = value.replace("{", "{{").replace("}", "}}")
# Remove leading quotes # Remove leading quotes
result += strip_quotes(value) result += strip_quotes(value)
pass pass