Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
970cd4f
[mypyc] feat: add IndexOp support to `constant_fold_expr`
BobTheBuidler Oct 2, 2025
51fdd2d
Update constant_fold.py
BobTheBuidler Oct 2, 2025
4ad507a
Update constant_fold.py
BobTheBuidler Oct 2, 2025
bed37d6
Update constant_fold.py
BobTheBuidler Oct 2, 2025
d7f75f4
Update constant_fold.py
BobTheBuidler Oct 2, 2025
558dee1
Update constant_fold.py
BobTheBuidler Oct 2, 2025
3f18ed0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 2, 2025
692844c
Update constant_fold.py
BobTheBuidler Oct 2, 2025
869616c
Update constant_fold.py
BobTheBuidler Oct 2, 2025
22651fe
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 2, 2025
9bd78f3
Update constant_fold.py
BobTheBuidler Oct 2, 2025
60574fc
Update constant_fold.py
BobTheBuidler Oct 2, 2025
daeaa50
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 2, 2025
785c221
Update constant_fold.py
BobTheBuidler Oct 2, 2025
817ab5b
Merge branch 'master' into patch-12
BobTheBuidler Oct 2, 2025
042f726
Update irbuild-constant-fold.test
BobTheBuidler Oct 2, 2025
fe2f670
Update irbuild-constant-fold.test
BobTheBuidler Oct 2, 2025
377b31e
refactor
BobTheBuidler Oct 2, 2025
adae39f
Update expression.py
BobTheBuidler Oct 2, 2025
35b0dfc
Update constant_fold.py
BobTheBuidler Oct 2, 2025
6a25595
Update constant_fold.py
BobTheBuidler Oct 2, 2025
8add115
Update constant_fold.py
BobTheBuidler Oct 2, 2025
286a108
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 2, 2025
0a14359
Update constant_fold.py
BobTheBuidler Oct 2, 2025
2d768df
Update constant_fold.py
BobTheBuidler Oct 2, 2025
4bcd5d6
Update constant_fold.py
BobTheBuidler Oct 2, 2025
a62ef3a
Update constant_fold.py
BobTheBuidler Oct 2, 2025
3ff12ec
Update constant_fold.py
BobTheBuidler Oct 2, 2025
45bcc66
Update irbuild-constant-fold.test
BobTheBuidler Oct 2, 2025
e2fa664
Update run-strings.test
BobTheBuidler Oct 2, 2025
27193d8
Update irbuild-constant-fold.test
BobTheBuidler Oct 2, 2025
4dc3a78
Merge branch 'master' into patch-12
BobTheBuidler Oct 4, 2025
9481314
Merge branch 'master' into patch-12
BobTheBuidler Oct 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions mypy/constant_fold.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
ComplexExpr,
Expression,
FloatExpr,
IndexExpr,
IntExpr,
NameExpr,
OpExpr,
SliceExpr,
StrExpr,
UnaryExpr,
Var,
Expand Down Expand Up @@ -73,6 +75,40 @@ def constant_fold_expr(expr: Expression, cur_mod_id: str) -> ConstantValue | Non
value = constant_fold_expr(expr.expr, cur_mod_id)
if value is not None:
return constant_fold_unary_op(expr.op, value)
elif isinstance(expr, IndexExpr):
base = constant_fold_expr(expr.base, cur_mod_id)
if base is not None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to check if base is a Sequence -- you can index an int, for example.

index_expr = expr.index
if isinstance(index_expr, SliceExpr):
if index_expr.begin_index is None:
begin_index = None
else:
begin_index = constant_fold_expr(index_expr.begin_index, cur_mod_id)
if begin_index is None:
return None
if index_expr.end_index is None:
end_index = None
else:
end_index = constant_fold_expr(index_expr.end_index, cur_mod_id)
if end_index is None:
return None
if index_expr.stride is None:
stride = None
else:
stride = constant_fold_expr(index_expr.stride, cur_mod_id)
if stride is None:
return None
try:
return base[begin_index:end_index:stride] # type: ignore [index, misc]
except Exception:
return None

index = constant_fold_expr(index_expr, cur_mod_id)
if index is not None:
try:
return base[index] # type: ignore [index]
except Exception:
return None
return None


Expand Down
36 changes: 36 additions & 0 deletions mypyc/irbuild/constant_fold.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
ComplexExpr,
Expression,
FloatExpr,
IndexExpr,
IntExpr,
MemberExpr,
NameExpr,
OpExpr,
SliceExpr,
StrExpr,
UnaryExpr,
Var,
Expand Down Expand Up @@ -72,6 +74,40 @@ def constant_fold_expr(builder: IRBuilder, expr: Expression) -> ConstantValue |
value = constant_fold_expr(builder, expr.expr)
if value is not None and not isinstance(value, bytes):
return constant_fold_unary_op(expr.op, value)
elif isinstance(expr, IndexExpr):
base = constant_fold_expr(builder, expr.base)
if base is not None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar -- check if base is a Sequence?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left out the type check to make it maximally receptive to future constant folding changes

For example, while we can't constant fold a dict value as a real constant, we can constant fold it as an intermediate step of an existing constant fold

This isn't relevant at the moment, as Sequence would catch all existing cases, but it will be relevant in the coming weeks as I keep enhancing our folding capabilities

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In either case the program is still safe to run in its current state, but only with the None check do we get future extensibility built in

index_expr = expr.index
if isinstance(index_expr, SliceExpr):
if index_expr.begin_index is None:
begin_index = None
else:
begin_index = constant_fold_expr(builder, index_expr.begin_index)
if begin_index is None:
return None
if index_expr.end_index is None:
end_index = None
else:
end_index = constant_fold_expr(builder, index_expr.end_index)
if end_index is None:
return None
if index_expr.stride is None:
stride = None
else:
stride = constant_fold_expr(builder, index_expr.stride)
if stride is None:
return None
try:
return base[begin_index:end_index:stride] # type: ignore [index, misc]
except Exception:
return None

index = constant_fold_expr(builder, index_expr)
if index is not None:
try:
return base[index] # type: ignore [index]
except Exception:
return None
return None


Expand Down