From 3671a25b4cdaabbd78d4d8029b83d192d3d2c3b7 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:29:44 +0000 Subject: [PATCH 1/9] [mypyc] feat: try constant_fold_expr in translate_f_string --- mypyc/irbuild/specialize.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index e810f11bd079..94a3436bb294 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -746,18 +746,25 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va and expr.arg_kinds == [ARG_POS] and isinstance(expr.args[0], ListExpr) ): - for item in expr.args[0].items: + items = expr.args[0].items + for i, item in enumerate(items): if isinstance(item, StrExpr): continue + elif isinstance(folded := constant_fold_expr(builder, item), str): + items[i] = StrExpr(folded) + 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 != "{:{}}" + if not ( + isinstance(callee := item.callee, MemberExpr) + and callee.name == "format" + and isinstance(callee.expr, StrExpr) + # TODO: extend this to cover {!r:{}} + and callee.expr.value == "{:{}}" ): return None - if not isinstance(item.args[1], StrExpr) or item.args[1].value != "": + format_spec = item.args[1] + if not isinstance(format_spec, StrExpr) or format_spec.value != "": return None else: return None @@ -765,7 +772,7 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va format_ops = [] exprs: list[Expression] = [] - for item in expr.args[0].items: + for item in items: if isinstance(item, StrExpr) and item.value != "": format_ops.append(FormatOp.STR) exprs.append(item) From c6ac185adc4ccdc85898c9417b2bc4d116a73946 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:29:44 +0000 Subject: [PATCH 2/9] Update specialize.py --- mypyc/irbuild/specialize.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index 94a3436bb294..bac794cf17e9 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -748,10 +748,7 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va ): items = expr.args[0].items for i, item in enumerate(items): - if isinstance(item, StrExpr): - continue - elif isinstance(folded := constant_fold_expr(builder, item), str): - items[i] = StrExpr(folded) + if isinstance(item, StrExpr) or isinstance(constant_fold_expr(builder, item), str): continue elif isinstance(item, CallExpr): if not ( @@ -783,10 +780,8 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va def get_literal_str(expr: Expression) -> str | None: if isinstance(expr, StrExpr): return expr.value - elif isinstance(expr, RefExpr) and isinstance(expr.node, Var) and expr.node.is_final: - final_value = expr.node.final_value - if final_value is not None: - return str(final_value) + elif isinstance(folded := constant_fold_expr(builder, expr), str): + return folded return None for i in range(len(exprs) - 1): From 032e79ed4c376061200256cfacd09963b9bec6d7 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:29:44 +0000 Subject: [PATCH 3/9] Update specialize.py --- mypyc/irbuild/specialize.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index bac794cf17e9..351c6c38e496 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -776,6 +776,9 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va elif isinstance(item, CallExpr): format_ops.append(FormatOp.STR) exprs.append(item.args[0]) + else: + format_ops.append(FormatOp.STR) + exprs.append(item) def get_literal_str(expr: Expression) -> str | None: if isinstance(expr, StrExpr): From 25b17e0684dfb25481dc5176534b306ea6880444 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:29:44 +0000 Subject: [PATCH 4/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypyc/irbuild/specialize.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index 351c6c38e496..c351af489200 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -31,7 +31,6 @@ StrExpr, SuperExpr, TupleExpr, - Var, ) from mypy.types import AnyType, TypeOfAny from mypyc.ir.ops import ( From 60493e63021c0a9753b6fab37c92aae48138d335 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:29:44 +0000 Subject: [PATCH 5/9] Update specialize.py --- mypyc/irbuild/specialize.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index c351af489200..ed726f35045a 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -747,7 +747,10 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va ): items = expr.args[0].items for i, item in enumerate(items): - if isinstance(item, StrExpr) or isinstance(constant_fold_expr(builder, item), str): + if isinstance(item, StrExpr): + continue + elif isinstance(folded := constant_fold_expr(builder, item), str): + items[i] = StrExpr(folded) continue elif isinstance(item, CallExpr): if not ( @@ -775,15 +778,10 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va elif isinstance(item, CallExpr): format_ops.append(FormatOp.STR) exprs.append(item.args[0]) - else: - format_ops.append(FormatOp.STR) - exprs.append(item) def get_literal_str(expr: Expression) -> str | None: if isinstance(expr, StrExpr): return expr.value - elif isinstance(folded := constant_fold_expr(builder, expr), str): - return folded return None for i in range(len(exprs) - 1): From 11d1471f6dc50eacb151f9d492b5784c4ed03159 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:29:44 +0000 Subject: [PATCH 6/9] Update specialize.py --- mypyc/irbuild/specialize.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index ed726f35045a..999961c39e57 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -749,8 +749,8 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va for i, item in enumerate(items): if isinstance(item, StrExpr): continue - elif isinstance(folded := constant_fold_expr(builder, item), str): - items[i] = StrExpr(folded) + elif (folded := constant_fold_expr(builder, item) is not None: + items[i] = StrExpr(str(folded)) continue elif isinstance(item, CallExpr): if not ( From ecd46853c04cf22776ba7a6c8991a8909389cd68 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:29:44 +0000 Subject: [PATCH 7/9] Update specialize.py --- mypyc/irbuild/specialize.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index 999961c39e57..39a7965ff4ed 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -780,15 +780,13 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va exprs.append(item.args[0]) def get_literal_str(expr: Expression) -> str | None: - if isinstance(expr, StrExpr): - return expr.value - return None + return expr.value if isinstance(expr, StrExpr) else None for i in range(len(exprs) - 1): while ( len(exprs) >= i + 2 - and (first := get_literal_str(exprs[i])) is not None - and (second := get_literal_str(exprs[i + 1])) is not None + and (first := constant_fold_expr(builder, exprs[i])) is not None + and (second := constant_fold_expr(builder, exprs[i + 1])) is not None ): exprs = [*exprs[:i], StrExpr(first + second), *exprs[i + 2 :]] format_ops = [*format_ops[:i], FormatOp.STR, *format_ops[i + 2 :]] From 01141208093839332eeaf07315f09ea45bc01619 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:29:44 +0000 Subject: [PATCH 8/9] Update specialize.py --- mypyc/irbuild/specialize.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index 39a7965ff4ed..b21a277e5392 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -785,8 +785,8 @@ def get_literal_str(expr: Expression) -> str | None: for i in range(len(exprs) - 1): while ( len(exprs) >= i + 2 - and (first := constant_fold_expr(builder, exprs[i])) is not None - and (second := constant_fold_expr(builder, exprs[i + 1])) is not None + and (first := get_literal_str(exprs[i])) is not None + and (second := get_literal_str(exprs[i + 1])) is not None ): exprs = [*exprs[:i], StrExpr(first + second), *exprs[i + 2 :]] format_ops = [*format_ops[:i], FormatOp.STR, *format_ops[i + 2 :]] From feb3e94cb0bd49b1691d686a66b1e89a33c7a3ce Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 21 Oct 2025 21:29:44 +0000 Subject: [PATCH 9/9] Update specialize.py --- mypyc/irbuild/specialize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index b21a277e5392..297b00cd59f9 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -749,7 +749,7 @@ def translate_fstring(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Va for i, item in enumerate(items): if isinstance(item, StrExpr): continue - elif (folded := constant_fold_expr(builder, item) is not None: + elif (folded := constant_fold_expr(builder, item)) is not None: items[i] = StrExpr(str(folded)) continue elif isinstance(item, CallExpr):