Handle set/dictionary comprehensions in format strings

This commit is contained in:
rocky
2020-01-13 23:49:17 -05:00
parent a918055a31
commit 73937ffeb4
6 changed files with 17 additions and 2 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -102,7 +102,17 @@ assert g.__doc__ is None
import decimal import decimal
width, precision, value = (10, 4, decimal.Decimal('12.34567')) width, precision, value = (10, 4, decimal.Decimal('12.34567'))
# Make sure we don't have additional f'..' inside the format strings below.
assert f'result: {value:{width}.{precision}}' == 'result: 12.35' assert f'result: {value:{width}.{precision}}' == 'result: 12.35'
assert f'result: {value:{width:0}.{precision:1}}' == 'result: 12.35' assert f'result: {value:{width:0}.{precision:1}}' == 'result: 12.35'
assert f'{2}\t' == '2\t' assert f'{2}\t' == '2\t'
# But below we *do* need the additional f".."
assert f'{f"{0}"*3}' == "000" assert f'{f"{0}"*3}' == "000"
# We need to make sure we have { {x:... not {{x: ...
# ^
# The former, {{ confuses the format strings so dictionary/set comprehensions
# don't work.
assert f'expr={ {x: y for x, y in [(1, 2), ]}}' == 'expr={1: 2}'

View File

@@ -69,7 +69,6 @@ SKIP_TESTS=(
[test_fractions.py]=1 # doesn't terminate [test_fractions.py]=1 # doesn't terminate
[test_float.py]=1 # it fails on its own [test_float.py]=1 # it fails on its own
[test_frame.py]=1 # doesn't terminate [test_frame.py]=1 # doesn't terminate
[test_fstring.py]=1 # syntax error: Investigate
[test_functools.py]=1 # it fails on its own [test_functools.py]=1 # it fails on its own
[test___future__.py]=1 # syntax error: Investigate [test___future__.py]=1 # syntax error: Investigate

View File

@@ -453,7 +453,13 @@ def customize_for_version36(self, version):
conversion = f_conversion(node) conversion = f_conversion(node)
if (self.in_format_string and self.in_format_string != "formatted_value1"): if (self.in_format_string and self.in_format_string != "formatted_value1"):
value = self.traverse(expr, indent="") value = self.traverse(expr, indent="")
es = escape_string("{%s%s}" % (value, conversion)) if value[0] == "{":
# If we have a set or dictionary comprehension, then we need to add a space
# so as not to confuse the format string with {{.
fmt = "{ %s%s }"
else:
fmt = "{%s%s}"
es = escape_string( fmt % (value, conversion))
f_str = "%s" % es f_str = "%s" % es
else: else:
old_in_format_string = self.in_format_string old_in_format_string = self.in_format_string