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): ...@@ -3025,23 +3025,28 @@ class FormattedValueNode(ExprNode):
def analyse_types(self, env): def analyse_types(self, env):
self.value = self.value.analyse_types(env).coerce_to_pyobject(env) self.value = self.value.analyse_types(env).coerce_to_pyobject(env)
self.format_spec = self.format_spec.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 return self
def generate_result_code(self, code): def generate_result_code(self, code):
value_result = self.value.py_result() value_result = self.value.py_result()
# common case: expect Unicode pass-through if no format spec if self.format_spec:
no_format_spec = isinstance(self.format_spec, UnicodeNode) and not self.format_spec.value.strip() 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: if self.conversion_char:
fn = self.find_conversion_func(self.conversion_char) fn = self.find_conversion_func(self.conversion_char)
assert fn is not None, "invalid conversion character found: '%s'" % self.conversion_char assert fn is not None, "invalid conversion character found: '%s'" % self.conversion_char
value_result = '%s(%s)' % (fn, value_result) value_result = '%s(%s)' % (fn, value_result)
code.globalstate.use_utility_code(UtilityCode.load_cached("PyObjectFormatAndDecref", "StringTools.c")) code.globalstate.use_utility_code(UtilityCode.load_cached("PyObjectFormatAndDecref", "StringTools.c"))
format_func = '__Pyx_PyObject_FormatSimpleAndDecref' if no_format_spec else '__Pyx_PyObject_FormatAndDecref' format_func += 'AndDecref'
elif no_format_spec: elif not self.format_spec:
code.globalstate.use_utility_code(UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c")) code.globalstate.use_utility_code(UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c"))
format_func = '__Pyx_PyObject_FormatSimple'
else: else:
format_func = 'PyObject_Format' format_func = 'PyObject_Format'
...@@ -3049,7 +3054,7 @@ class FormattedValueNode(ExprNode): ...@@ -3049,7 +3054,7 @@ class FormattedValueNode(ExprNode):
self.result(), self.result(),
format_func, format_func,
value_result, value_result,
self.format_spec.py_result(), format_spec,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
......
...@@ -3960,18 +3960,24 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations): ...@@ -3960,18 +3960,24 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
""" """
self.visitchildren(node) self.visitchildren(node)
unicode_node = ExprNodes.UnicodeNode unicode_node = ExprNodes.UnicodeNode
format_node = ExprNodes.FormattedValueNode
values = [] values = []
for is_unode_group, substrings in itertools.groupby(node.values, lambda v: isinstance(v, unicode_node)): for is_unode_group, substrings in itertools.groupby(node.values, lambda v: isinstance(v, unicode_node)):
if is_unode_group: if is_unode_group:
substrings = list(substrings) substrings = list(substrings)
unode = substrings[0] unode = substrings[0]
if len(substrings) > 1: 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 # ignore empty Unicode strings
if unode.value: if unode.value:
values.append(unode) values.append(unode)
else: 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: if not values:
node = ExprNodes.UnicodeNode(node.pos, value=EncodedString('')) node = ExprNodes.UnicodeNode(node.pos, value=EncodedString(''))
......
...@@ -1031,7 +1031,7 @@ def p_f_string_expr(s, unicode_value, pos, starting_index): ...@@ -1031,7 +1031,7 @@ def p_f_string_expr(s, unicode_value, pos, starting_index):
i = starting_index i = starting_index
size = len(unicode_value) size = len(unicode_value)
conversion_char = terminal_char = format_spec = None conversion_char = terminal_char = format_spec = None
format_spec_str = u'' format_spec_str = None
NO_CHAR = 2**30 NO_CHAR = 2**30
nested_depth = 0 nested_depth = 0
...@@ -1133,7 +1133,7 @@ def p_f_string_expr(s, unicode_value, pos, starting_index): ...@@ -1133,7 +1133,7 @@ def p_f_string_expr(s, unicode_value, pos, starting_index):
s.error("invalid conversion character '%s'" % conversion_char) s.error("invalid conversion character '%s'" % conversion_char)
# the format spec is itself treated like an f-string # 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)) format_spec = ExprNodes.JoinedStrNode(pos, values=p_f_string(s, format_spec_str, pos))
return i + 1, ExprNodes.FormattedValueNode( 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