def translate_printf_style_formatting(builder: IRBuilder, format_expr: Union[StrExpr, BytesExpr], rhs: Expression) -> Optional[Value]: tokens = tokenizer_printf_style(format_expr.value) if tokens is not None: literals, format_ops = tokens exprs = [] if isinstance(rhs, TupleExpr): exprs = rhs.items elif isinstance(rhs, Expression): exprs.append(rhs) if isinstance(format_expr, BytesExpr): substitutions = convert_format_expr_to_bytes(builder, format_ops, exprs, format_expr.line) if substitutions is not None: return join_formatted_bytes(builder, literals, substitutions, format_expr.line) else: substitutions = convert_format_expr_to_str(builder, format_ops, exprs, format_expr.line) if substitutions is not None: return join_formatted_strings(builder, literals, substitutions, format_expr.line) return None
def translate_str_format_percent_sign(builder: IRBuilder, format_expr: StrExpr, rhs: Expression) -> Value: tokens = tokenizer_printf_style(format_expr.value) if tokens is not None: literals, format_ops = tokens exprs = [] if isinstance(rhs, TupleExpr): exprs = rhs.items elif isinstance(rhs, Expression): exprs.append(rhs) substitutions = convert_expr(builder, format_ops, exprs, format_expr.line) if substitutions is not None: return join_formatted_strings(builder, literals, substitutions, format_expr.line) call_c_ops_candidates = binary_ops.get('%', []) ret = builder.builder.matching_call_c( call_c_ops_candidates, [builder.accept(format_expr), builder.accept(rhs)], format_expr.line) assert ret is not None, 'Cannot use binary op % at line {}'.format( format_expr.line) return ret
def translate_str_format( builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Optional[Value]: if (isinstance(callee, MemberExpr) and isinstance(callee.expr, StrExpr) and expr.arg_kinds.count(ARG_POS) == len(expr.arg_kinds)): format_str = callee.expr.value tokens = tokenizer_format_call(format_str) if tokens is None: return None literals, format_ops = tokens # Convert variables to strings substitutions = convert_format_expr_to_str(builder, format_ops, expr.args, expr.line) if substitutions is None: return None return join_formatted_strings(builder, literals, substitutions, expr.line) return None
def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Optional[Value]: """Special case for f-string, which is translated into str.join() in mypy AST. This specializer optimizes simplest f-strings which don't contain any format operation. """ if (isinstance(callee, MemberExpr) and isinstance(callee.expr, StrExpr) and callee.expr.value == '' and expr.arg_kinds == [ARG_POS] and isinstance(expr.args[0], ListExpr)): for item in expr.args[0].items: if isinstance(item, StrExpr): continue elif isinstance(item, CallExpr): if (not isinstance(item.callee, MemberExpr) or item.callee.name != 'format'): return None elif (not isinstance(item.callee.expr, StrExpr) or item.callee.expr.value != '{:{}}'): return None if not isinstance(item.args[1], StrExpr) or item.args[1].value != '': return None else: return None format_ops = [] exprs: List[Expression] = [] for item in expr.args[0].items: if isinstance(item, StrExpr) and item.value != '': format_ops.append(FormatOp.STR) exprs.append(item) elif isinstance(item, CallExpr): format_ops.append(FormatOp.STR) exprs.append(item.args[0]) substitutions = convert_format_expr_to_str(builder, format_ops, exprs, expr.line) if substitutions is None: return None return join_formatted_strings(builder, None, substitutions, expr.line) return None