You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-02 16:44:46 +08:00
More fstring bugs -- nested fstring grammar rules
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -69,17 +69,8 @@ fields = ['a', 'b', 'c']
|
||||
assert _repr_fn(fields) == ['return xx + f"(a={self.a!r}, b={self.b!r}, c={self.c!r})"']
|
||||
|
||||
|
||||
# From Python 3.7 test_fstring. Why this kind of thing matter seems a bit
|
||||
# academic, but decompile an equivalent thing. For compatiblity with older
|
||||
# Python we'll use "%" instead of a format string
|
||||
def f():
|
||||
f'''Not a docstring'''
|
||||
def g():
|
||||
'''Not a docstring''' \
|
||||
f''
|
||||
|
||||
assert f.__doc__ is None
|
||||
assert g.__doc__ is None
|
||||
#################################
|
||||
# From Python 3.7 test_fstring.py
|
||||
|
||||
x = 5
|
||||
assert f'{(lambda y:x*y)("8")!r}' == "'88888'"
|
||||
@@ -92,3 +83,19 @@ except SyntaxError:
|
||||
pass
|
||||
else:
|
||||
assert False, "f'{lambda x:x}' should be a syntax error"
|
||||
|
||||
(x, y, width) = ("foo", 2, 10)
|
||||
assert f'x={x*y:{width}}' == 'x=foofoo '
|
||||
|
||||
# Why the fact that the distinction of docstring versus stmt is a
|
||||
# string expression is important academic, but we will decompile an
|
||||
# equivalent thing. For compatiblity with older Python we'll use "%"
|
||||
# instead of a format string
|
||||
def f():
|
||||
f'''Not a docstring'''
|
||||
def g():
|
||||
'''Not a docstring''' \
|
||||
f''
|
||||
|
||||
assert f.__doc__ is None
|
||||
assert g.__doc__ is None
|
||||
|
@@ -450,11 +450,18 @@ def customize_for_version36(self, version):
|
||||
def n_formatted_value1(node):
|
||||
expr = node[0]
|
||||
assert expr == "expr"
|
||||
self.in_format_string = True
|
||||
value = self.traverse(expr, indent="")
|
||||
self.in_format_string = False
|
||||
conversion = f_conversion(node)
|
||||
f_str = "f%s" % escape_string("{%s%s}" % (value, conversion))
|
||||
if (self.in_format_string):
|
||||
value = self.traverse(expr, indent="")
|
||||
es = escape_string("{%s%s}" % (value, conversion))
|
||||
f_str = "%s" % es
|
||||
else:
|
||||
self.in_format_string = True
|
||||
value = self.traverse(expr, indent="")
|
||||
self.in_format_string = False
|
||||
es = escape_string("{%s%s}" % (value, conversion))
|
||||
f_str = "f%s" % es
|
||||
|
||||
self.write(f_str)
|
||||
self.prune()
|
||||
|
||||
@@ -468,7 +475,6 @@ def customize_for_version36(self, version):
|
||||
assert expr == "expr"
|
||||
self.in_format_string = True
|
||||
value = self.traverse(expr, indent="")
|
||||
self.in_format_string = False
|
||||
format_value_attr = node[-1]
|
||||
assert format_value_attr == "FORMAT_VALUE_ATTR"
|
||||
attr = format_value_attr.attr
|
||||
@@ -483,6 +489,7 @@ def customize_for_version36(self, version):
|
||||
else:
|
||||
conversion = FSTRING_CONVERSION_MAP.get(attr, "")
|
||||
|
||||
self.in_format_string = False
|
||||
f_str = "f%s" % escape_string("{%s%s}" % (value, conversion))
|
||||
self.write(f_str)
|
||||
|
||||
@@ -495,14 +502,14 @@ def customize_for_version36(self, version):
|
||||
p = self.prec
|
||||
self.prec = 100
|
||||
|
||||
result = ''
|
||||
result = ""
|
||||
for expr in node[:-1]:
|
||||
assert expr == 'expr'
|
||||
value = self.traverse(expr, indent='')
|
||||
assert expr == "expr"
|
||||
value = self.traverse(expr, indent="")
|
||||
if expr[0].kind.startswith('formatted_value'):
|
||||
# remove leading 'f'
|
||||
assert value.startswith('f')
|
||||
value = value[1:]
|
||||
if value.startswith("f"):
|
||||
value = value[1:]
|
||||
pass
|
||||
else:
|
||||
# {{ and }} in Python source-code format strings mean
|
||||
|
Reference in New Issue
Block a user