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

Function get_expr_length

mypyc/irbuild/for_helpers.py:1282–1344  ·  view source on GitHub ↗
(builder: IRBuilder, expr: Expression)

Source from the content-addressed store, hash-verified

1280
1281
1282def get_expr_length(builder: IRBuilder, expr: Expression) -> int | None:
1283 folded = constant_fold_expr(builder, expr)
1284 if isinstance(folded, (str, bytes)):
1285 return len(folded)
1286 elif isinstance(expr, (ListExpr, TupleExpr)):
1287 # if there are no star expressions, or we know the length of them,
1288 # we know the length of the expression
1289 stars = [get_expr_length(builder, i) for i in expr.items if isinstance(i, StarExpr)]
1290 if None not in stars:
1291 other = sum(not isinstance(i, StarExpr) for i in expr.items)
1292 return other + sum(stars) # type: ignore [arg-type]
1293 elif isinstance(expr, StarExpr):
1294 return get_expr_length(builder, expr.expr)
1295 elif (
1296 isinstance(expr, RefExpr)
1297 and isinstance(expr.node, Var)
1298 and expr.node.is_final
1299 and isinstance(expr.node.final_value, str)
1300 and expr.node.has_explicit_value
1301 ):
1302 return len(expr.node.final_value)
1303 elif (
1304 isinstance(expr, CallExpr)
1305 and isinstance(callee := expr.callee, NameExpr)
1306 and all(kind == ARG_POS for kind in expr.arg_kinds)
1307 ):
1308 fullname = callee.fullname
1309 if (
1310 fullname
1311 in (
1312 "builtins.list",
1313 "builtins.tuple",
1314 "builtins.enumerate",
1315 "builtins.sorted",
1316 "builtins.reversed",
1317 )
1318 and len(expr.args) == 1
1319 ):
1320 return get_expr_length(builder, expr.args[0])
1321 elif fullname == "builtins.map" and len(expr.args) == 2:
1322 return get_expr_length(builder, expr.args[1])
1323 elif fullname == "builtins.zip" and expr.args:
1324 arg_lengths = [get_expr_length(builder, arg) for arg in expr.args]
1325 if all(arg is not None for arg in arg_lengths):
1326 return min(arg_lengths) # type: ignore [type-var]
1327 elif fullname == "builtins.range" and len(expr.args) <= 3:
1328 folded_args = [constant_fold_expr(builder, arg) for arg in expr.args]
1329 if all(isinstance(arg, int) for arg in folded_args):
1330 try:
1331 return len(range(*cast(list[int], folded_args)))
1332 except ValueError: # prevent crash if invalid args
1333 pass
1334
1335 # TODO: extend this, passing length of listcomp and genexp should have worthwhile
1336 # performance boost and can be (sometimes) figured out pretty easily. set and dict
1337 # comps *can* be done as well but will need special logic to consider the possibility
1338 # of key conflicts.
1339

Callers 1

get_expr_length_valueFunction · 0.85

Calls 8

constant_fold_exprFunction · 0.90
isinstanceFunction · 0.85
lenFunction · 0.85
sumFunction · 0.85
allFunction · 0.85
minFunction · 0.85
rangeClass · 0.85
node_typeMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…