From 338f77fa81c19a7f6f2396496ac8ed645efd47c1 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 15 Oct 2025 16:59:08 -0400 Subject: [PATCH 1/4] [mypyc] feat: use `get_expr_length_value` in `translate_len` Currently, `translate_len` can determine the length of an RTuple at compile time This PR extends this capability to all expressions supported by `get_expr_length_value` --- mypyc/irbuild/specialize.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index e810f11bd079..a7b067b98549 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -69,6 +69,7 @@ is_int64_rprimitive, is_int_rprimitive, is_list_rprimitive, + is_sequence_rprimitive, is_uint8_rprimitive, list_rprimitive, object_rprimitive, @@ -221,17 +222,11 @@ def translate_len(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value if len(expr.args) == 1 and expr.arg_kinds == [ARG_POS]: arg = expr.args[0] expr_rtype = builder.node_type(arg) - if isinstance(expr_rtype, RTuple): - # len() of fixed-length tuple can be trivially determined - # statically, though we still need to evaluate it. - builder.accept(arg) - return Integer(len(expr_rtype.types)) + # NOTE (?) I'm not sure if my handling of can_borrow is correct here + obj = builder.accept(arg, can_borrow=is_list_rprimitive(expr_rtype)) + if is_sequence_rprimitive(expr_rtype) or isinstance(expr_rtype, RTuple): + return get_expr_length_value(builder, arg, obj, expr.line, use_pyssize_t=False) else: - if is_list_rprimitive(builder.node_type(arg)): - borrow = True - else: - borrow = False - obj = builder.accept(arg, can_borrow=borrow) return builder.builtin_len(obj, expr.line) return None From 0c7974823566057575fa2edd5e389b8cd31fbf5d Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 15 Oct 2025 17:00:06 -0400 Subject: [PATCH 2/4] Update specialize.py --- mypyc/irbuild/specialize.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index a7b067b98549..39bcbc708e3e 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -81,6 +81,7 @@ from mypyc.irbuild.constant_fold import constant_fold_expr from mypyc.irbuild.for_helpers import ( comprehension_helper, + get_expr_length_value, sequence_from_generator_preallocate_helper, translate_list_comprehension, translate_set_comprehension, From f78c7542a770a09d842a46974cdbbf5d2b2a923f Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 15 Oct 2025 18:52:19 -0400 Subject: [PATCH 3/4] Update irbuild-basic.test --- mypyc/test-data/irbuild-basic.test | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index 612f3266fd79..fd5f1411c3a7 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -3799,3 +3799,11 @@ L0: r2.__mypyc_env__ = r0; r3 = is_error wrapper = r2 return wrapper + +[case testStaticLength] +def get_length() -> int: + return len("https://w3id.org/cwl/salad#") +[out] +def get_length(): +L0: + return 27 From 7f7934637108d61f80b9604426a669535d2d94de Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 15 Oct 2025 19:23:29 -0400 Subject: [PATCH 4/4] Update irbuild-basic.test --- mypyc/test-data/irbuild-basic.test | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index fd5f1411c3a7..e7074b13fe13 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -3805,5 +3805,7 @@ def get_length() -> int: return len("https://w3id.org/cwl/salad#") [out] def get_length(): + r0 :: str L0: - return 27 + r0 = 'https://w3id.org/cwl/salad#' + return 54