MCPcopy Index your code
hub / github.com/python/mypy / translate_fstring

Function translate_fstring

mypyc/irbuild/specialize.py:872–936  ·  view source on GitHub ↗

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.

(builder: IRBuilder, expr: CallExpr, callee: RefExpr)

Source from the content-addressed store, hash-verified

870
871@specialize_function("join", str_rprimitive)
872def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value | None:
873 """Special case for f-string, which is translated into str.join()
874 in mypy AST.
875
876 This specializer optimizes simplest f-strings which don't contain
877 any format operation.
878 """
879 if (
880 isinstance(callee, MemberExpr)
881 and isinstance(callee.expr, StrExpr)
882 and callee.expr.value == ""
883 and expr.arg_kinds == [ARG_POS]
884 and isinstance(expr.args[0], ListExpr)
885 ):
886 for item in expr.args[0].items:
887 if isinstance(item, StrExpr):
888 continue
889 elif isinstance(item, CallExpr):
890 if not isinstance(item.callee, MemberExpr) or item.callee.name != "format":
891 return None
892 elif (
893 not isinstance(item.callee.expr, StrExpr) or item.callee.expr.value != "{:{}}"
894 ):
895 return None
896
897 if not isinstance(item.args[1], StrExpr) or item.args[1].value != "":
898 return None
899 else:
900 return None
901
902 format_ops = []
903 exprs: list[Expression] = []
904
905 for item in expr.args[0].items:
906 if isinstance(item, StrExpr) and item.value != "":
907 format_ops.append(FormatOp.STR)
908 exprs.append(item)
909 elif isinstance(item, CallExpr):
910 format_ops.append(FormatOp.STR)
911 exprs.append(item.args[0])
912
913 def get_literal_str(expr: Expression) -> str | None:
914 if isinstance(expr, StrExpr):
915 return expr.value
916 elif isinstance(expr, RefExpr) and isinstance(expr.node, Var) and expr.node.is_final:
917 final_value = expr.node.final_value
918 if final_value is not None:
919 return str(final_value)
920 return None
921
922 for i in range(len(exprs) - 1):
923 while (
924 len(exprs) >= i + 2
925 and (first := get_literal_str(exprs[i])) is not None
926 and (second := get_literal_str(exprs[i + 1])) is not None
927 ):
928 exprs = [*exprs[:i], StrExpr(first + second), *exprs[i + 2 :]]
929 format_ops = [*format_ops[:i], FormatOp.STR, *format_ops[i + 2 :]]

Callers

nothing calls this directly

Calls 8

StrExprClass · 0.90
join_formatted_stringsFunction · 0.90
isinstanceFunction · 0.85
rangeClass · 0.85
lenFunction · 0.85
get_literal_strFunction · 0.85
appendMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…