Commit 3b1277a7 authored by Stefan Behnel's avatar Stefan Behnel

set FormattedValueNode.format_spec field to None for empty format specs to...

set FormattedValueNode.format_spec field to None for empty format specs to simplify later "empty" tests
parent eea27293
......@@ -3025,23 +3025,28 @@ class FormattedValueNode(ExprNode):
def analyse_types(self, env):
self.value = self.value.analyse_types(env).coerce_to_pyobject(env)
if self.format_spec:
self.format_spec = self.format_spec.analyse_types(env).coerce_to_pyobject(env)
return self
def generate_result_code(self, code):
value_result = self.value.py_result()
# common case: expect Unicode pass-through if no format spec
no_format_spec = isinstance(self.format_spec, UnicodeNode) and not self.format_spec.value.strip()
if self.format_spec:
format_func = '__Pyx_PyObject_Format'
format_spec = self.format_spec.py_result()
else:
# common case: expect simple Unicode pass-through if no format spec
format_func = '__Pyx_PyObject_FormatSimple'
format_spec = Naming.empty_unicode
if self.conversion_char:
fn = self.find_conversion_func(self.conversion_char)
assert fn is not None, "invalid conversion character found: '%s'" % self.conversion_char
value_result = '%s(%s)' % (fn, value_result)
code.globalstate.use_utility_code(UtilityCode.load_cached("PyObjectFormatAndDecref", "StringTools.c"))
format_func = '__Pyx_PyObject_FormatSimpleAndDecref' if no_format_spec else '__Pyx_PyObject_FormatAndDecref'
elif no_format_spec:
format_func += 'AndDecref'
elif not self.format_spec:
code.globalstate.use_utility_code(UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c"))
format_func = '__Pyx_PyObject_FormatSimple'
else:
format_func = 'PyObject_Format'
......@@ -3049,7 +3054,7 @@ class FormattedValueNode(ExprNode):
self.result(),
format_func,
value_result,
self.format_spec.py_result(),
format_spec,
code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result())
......
......@@ -3960,18 +3960,24 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
"""
self.visitchildren(node)
unicode_node = ExprNodes.UnicodeNode
format_node = ExprNodes.FormattedValueNode
values = []
for is_unode_group, substrings in itertools.groupby(node.values, lambda v: isinstance(v, unicode_node)):
if is_unode_group:
substrings = list(substrings)
unode = substrings[0]
if len(substrings) > 1:
unode.value = EncodedString(u''.join(node.value for node in substrings))
unode.value = EncodedString(u''.join(value.value for value in substrings))
# ignore empty Unicode strings
if unode.value:
values.append(unode)
else:
values.extend(substrings)
for value in substrings:
if isinstance(value, format_node):
if isinstance(value.format_spec, unicode_node) and not value.format_spec.value:
value.format_spec = None
values.append(value)
if not values:
node = ExprNodes.UnicodeNode(node.pos, value=EncodedString(''))
......
......@@ -1031,7 +1031,7 @@ def p_f_string_expr(s, unicode_value, pos, starting_index):
i = starting_index
size = len(unicode_value)
conversion_char = terminal_char = format_spec = None
format_spec_str = u''
format_spec_str = None
NO_CHAR = 2**30
nested_depth = 0
......@@ -1133,7 +1133,7 @@ def p_f_string_expr(s, unicode_value, pos, starting_index):
s.error("invalid conversion character '%s'" % conversion_char)
# the format spec is itself treated like an f-string
if format_spec_str is not None:
if format_spec_str:
format_spec = ExprNodes.JoinedStrNode(pos, values=p_f_string(s, format_spec_str, pos))
return i + 1, ExprNodes.FormattedValueNode(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment