def n_joined_str(node): result = '' for fstr_node in node: assert fstr_node == 'fstr' assert fstr_node[0] == 'expr' subnode = fstr_node[0][0] if subnode.kind == 'fstring_expr': # Don't include outer f'...' f_conversion(subnode) data = strip_quotes(self.traverse(subnode, indent='')) result += data elif subnode == 'LOAD_CONST': result += strip_quotes(escape_string(subnode.attr)) elif subnode == 'fstring_single': f_conversion(subnode) data = self.traverse(subnode, indent='') if data[0:1] == 'f': data = strip_quotes(data[1:]) result += data pass else: result += strip_quotes(self.traverse(subnode, indent='')) pass pass self.write('f%s' % escape_string(result)) self.prune()
def n_joined_str(node): p = self.prec self.prec = 100 result = '' for expr in node[:-1]: 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:] 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_STR # 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_STR' value = value.replace("{", "{{").replace("}", "}}") # Remove leading quotes result += strip_quotes(value) pass self.write('f%s' % escape_string(result)) self.prec = p self.prune()
def n_formatted_value2(node): p = self.prec self.prec = 100 expr = node[0] assert expr == "expr" old_in_format_string = self.in_format_string self.in_format_string = "formatted_value2" value = self.traverse(expr, indent="") format_value_attr = node[-1] assert format_value_attr == "FORMAT_VALUE_ATTR" attr = format_value_attr.attr if attr & 4: assert node[1] == "expr" fmt = strip_quotes(self.traverse(node[1], indent="")) attr_flags = attr & 3 if attr_flags: conversion = "%s:%s" % (FSTRING_CONVERSION_MAP.get( attr_flags, ""), fmt) else: conversion = ":%s" % fmt else: conversion = FSTRING_CONVERSION_MAP.get(attr, "") self.in_format_string = old_in_format_string f_str = "f%s" % escape_string("{%s%s}" % (value, conversion)) self.write(f_str) self.prec = p self.prune()
def n_fstr(node): if node[0] == 'expr' and node[0][0] == 'fstring_expr': f_conversion(node[0][0]) self.default(node[0][0]) else: value = strip_quotes(self.traverse(node[0], indent='')) pass self.write(value) self.prune()
def n_formatted_value2(node): p = self.prec self.prec = 100 expr = node[0] assert expr == 'expr' value = self.traverse(expr, indent='') format_value_attr = node[-1] assert format_value_attr == 'FORMAT_VALUE_ATTR' attr = format_value_attr.attr if attr == 4: assert node[1] == 'expr' fmt = strip_quotes(self.traverse(node[1], indent='')) conversion = ":%s" % fmt else: conversion = FSTRING_CONVERSION_MAP.get(attr, '') f_str = "f%s" % escape_string("{%s%s}" % (value, conversion)) self.write(f_str) self.prec = p self.prune()
def n_joined_str(node): p = self.prec self.prec = 100 old_in_format_string = self.in_format_string self.in_format_string = "joined_str" result = "" for expr in node[:-1]: assert expr == "expr" value = self.traverse(expr, indent="") if expr[0].kind.startswith("formatted_value"): # remove leading 'f' if value.startswith("f"): value = value[1:] 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_STR # 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_STR" or expr[0] == "LOAD_CONST" and isinstance(expr[0].attr, unicode)) value = value.replace("{", "{{").replace("}", "}}") # Remove leading quotes result += strip_quotes(value) pass self.in_format_string = old_in_format_string if self.in_format_string: self.write(result) else: self.write("f%s" % escape_string(result)) self.prec = p self.prune()