Commit 5c65e33
[mypyc] Fix AttributeError in async try/finally with mixed return paths (#19361)
Async functions with try/finally blocks were raising AttributeError
when:
* Some paths in the try block return while others don't
* The non-return path is executed at runtime
* No further await calls are needed
This occurred because mypyc's IR requires all control flow paths to
assign
to spill targets. The non-return path assigns NULL to maintain this
invariant, but reading NULL attributes raises AttributeError in Python.
Modified the GetAttr IR operation to support reading NULL attributes
without raising AttributeError through a new allow_null parameter. This
parameter is used specifically in try/finally resolution when reading
spill targets.
* Added allow_null: bool = False parameter to GetAttr.init in
mypyc/ir/ops.py
* When allow_null=True, sets error_kind=ERR_NEVER to prevent
AttributeError
* Modified read_nullable_attr in IRBuilder to create GetAttr with
allow_null=True
* Modified try_finally_resolve_control in statement.py to use
read_nullable_attr
only for spill targets (attributes starting with 'mypyc_temp')
* Updated C code generation in emitfunc.py:
* visit_get_attr checks for allow_null and delegates to
get_attr_with_allow_null
* get_attr_with_allow_null reads attributes without NULL checks and only
increments reference count if not NULL
Design decisions:
* Targeted fix: Only applied to spill targets in try/finally resolution,
not a general replacement for GetAttr. This minimizes risk and maintains
existing behavior for all other attribute access.
* No initialization changes: Initially tried initializing spill targets
to Py_None instead of NULL, but this would incorrectly make try/finally
blocks return None instead of falling through to subsequent code.
Added two test cases to mypyc/test-data/run-async.test:
* testAsyncTryFinallyMixedReturn: Tests the basic issue with async
try/finally blocks containing mixed return/non-return paths.
* testAsyncWithMixedReturn: Tests async with statements (which use
try/finally under the hood) to ensure the fix works for this common
pattern as well.
Both tests verify that the AttributeError no longer occurs when taking
the non-return path through the try block.
See mypyc/mypyc#11151 parent 934ec50 commit 5c65e33
File tree
5 files changed
+348
-4
lines changed- mypyc
- codegen
- irbuild
- ir
- test-data
5 files changed
+348
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
358 | 358 | | |
359 | 359 | | |
360 | 360 | | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
361 | 364 | | |
362 | 365 | | |
363 | 366 | | |
| |||
426 | 429 | | |
427 | 430 | | |
428 | 431 | | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
429 | 450 | | |
430 | 451 | | |
431 | 452 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
777 | 777 | | |
778 | 778 | | |
779 | 779 | | |
780 | | - | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
781 | 783 | | |
782 | 784 | | |
783 | 785 | | |
| 786 | + | |
784 | 787 | | |
785 | 788 | | |
786 | 789 | | |
787 | 790 | | |
788 | | - | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
789 | 794 | | |
790 | 795 | | |
791 | 796 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
708 | 708 | | |
709 | 709 | | |
710 | 710 | | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
711 | 720 | | |
712 | 721 | | |
713 | 722 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| 49 | + | |
49 | 50 | | |
50 | 51 | | |
51 | 52 | | |
| |||
653 | 654 | | |
654 | 655 | | |
655 | 656 | | |
656 | | - | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
657 | 663 | | |
658 | 664 | | |
659 | | - | |
| 665 | + | |
660 | 666 | | |
661 | 667 | | |
662 | 668 | | |
| |||
0 commit comments