Skip to content

Commit edb1975

Browse files
author
Michal Medvecky
committed
[GR-52133] Implement except* in Bytecode DSL.
PullRequest: graalpython/4033
2 parents aa64ab2 + 732be90 commit edb1975

File tree

16 files changed

+1193
-36
lines changed

16 files changed

+1193
-36
lines changed

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags_bytecode_dsl/test_compile.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,4 @@ test.test_compile.TestStackSizeStability.test_async_for @ linux-x86_64
4747
test.test_compile.TestStackSizeStability.test_async_for_else @ linux-x86_64
4848
test.test_compile.TestStackSizeStability.test_if @ linux-x86_64
4949
test.test_compile.TestStackSizeStability.test_if_else @ linux-x86_64
50-
test.test_compile.TestStackSizeStability.test_try_except_star_as @ linux-x86_64
51-
test.test_compile.TestStackSizeStability.test_try_except_star_finally @ linux-x86_64
52-
test.test_compile.TestStackSizeStability.test_try_except_star_qualified @ linux-x86_64
5350
test.test_compile.TestStackSizeStability.test_while_else @ linux-x86_64
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,58 @@
11
test.test_except_star.TestInvalidExceptStar.test_mixed_except_and_except_star_is_syntax_error @ linux-x86_64
2+
test.test_except_star.TestInvalidExceptStar.test_except_star_ExceptionGroup_is_runtime_error_single @ linux-x86_64
3+
test.test_except_star.TestInvalidExceptStar.test_except_star_ExceptionGroup_is_runtime_error_tuple @ linux-x86_64
4+
test.test_except_star.TestInvalidExceptStar.test_except_star_invalid_exception_type @ linux-x86_64
5+
test.test_except_star.TestBreakContinueReturnInExceptStarBlock.test_break_in_except_star @ linux-x86_64
6+
test.test_except_star.TestBreakContinueReturnInExceptStarBlock.test_continue_in_except_star_block_invalid @ linux-x86_64
7+
test.test_except_star.TestBreakContinueReturnInExceptStarBlock.test_return_in_except_star_block_invalid @ linux-x86_64
8+
test.test_except_star.TestBreakContinueReturnInExceptStarBlock.test_break_continue_in_except_star_block_valid @ linux-x86_64
9+
test.test_except_star.TestBreakContinueReturnInExceptStarBlock.test_return_in_except_star_block_valid @ linux-x86_64
10+
test.test_except_star.TestExceptStarSplitSemantics.test_empty_groups_removed @ linux-x86_64
11+
test.test_except_star.TestExceptStarSplitSemantics.test_no_match_single_type @ linux-x86_64
12+
test.test_except_star.TestExceptStarSplitSemantics.test_match_single_type @ linux-x86_64
13+
test.test_except_star.TestExceptStarSplitSemantics.test_match_single_type_partial_match @ linux-x86_64
14+
test.test_except_star.TestExceptStarSplitSemantics.test_match_single_type_nested @ linux-x86_64
15+
test.test_except_star.TestExceptStarSplitSemantics.test_match_type_tuple_nested @ linux-x86_64
16+
test.test_except_star.TestExceptStarSplitSemantics.test_singleton_groups_are_kept @ linux-x86_64
17+
test.test_except_star.TestExceptStarSplitSemantics.test_naked_exception_matched_wrapped1 @ linux-x86_64
18+
test.test_except_star.TestExceptStarSplitSemantics.test_naked_exception_matched_wrapped2 @ linux-x86_64
19+
test.test_except_star.TestExceptStarSplitSemantics.test_exception_group_except_star_Exception_not_wrapped @ linux-x86_64
20+
test.test_except_star.TestExceptStarSplitSemantics.test_plain_exception_not_matched @ linux-x86_64
21+
test.test_except_star.TestExceptStarSplitSemantics.test_match__supertype @ linux-x86_64
22+
test.test_except_star.TestExceptStarSplitSemantics.test_multiple_matches_named @ linux-x86_64
23+
test.test_except_star.TestExceptStarSplitSemantics.test_multiple_matches_unnamed @ linux-x86_64
24+
test.test_except_star.TestExceptStarSplitSemantics.test_first_match_wins_named @ linux-x86_64
25+
test.test_except_star.TestExceptStarSplitSemantics.test_first_match_wins_unnamed @ linux-x86_64
26+
test.test_except_star.TestExceptStarSplitSemantics.test_nested_except_stars @ linux-x86_64
27+
test.test_except_star.TestExceptStarSplitSemantics.test_nested_in_loop @ linux-x86_64
28+
test.test_except_star.TestExceptStarReraise.test_reraise_all_named @ linux-x86_64
29+
test.test_except_star.TestExceptStarReraise.test_reraise_all_unnamed @ linux-x86_64
30+
test.test_except_star.TestExceptStarReraise.test_reraise_some_handle_all_named @ linux-x86_64
31+
test.test_except_star.TestExceptStarReraise.test_reraise_partial_handle_all_unnamed @ linux-x86_64
32+
test.test_except_star.TestExceptStarReraise.test_reraise_partial_handle_some_named @ linux-x86_64
33+
test.test_except_star.TestExceptStarReraise.test_reraise_partial_handle_some_unnamed @ linux-x86_64
34+
test.test_except_star.TestExceptStarReraise.test_reraise_plain_exception_named @ linux-x86_64
35+
test.test_except_star.TestExceptStarReraise.test_reraise_plain_exception_unnamed @ linux-x86_64
36+
test.test_except_star.TestExceptStarRaise.test_raise_named @ linux-x86_64
37+
test.test_except_star.TestExceptStarRaise.test_raise_unnamed @ linux-x86_64
38+
test.test_except_star.TestExceptStarRaise.test_raise_handle_all_raise_one_named @ linux-x86_64
39+
test.test_except_star.TestExceptStarRaise.test_raise_handle_all_raise_one_unnamed @ linux-x86_64
40+
test.test_except_star.TestExceptStarRaise.test_raise_handle_all_raise_two_named @ linux-x86_64
41+
test.test_except_star.TestExceptStarRaise.test_raise_handle_all_raise_two_unnamed @ linux-x86_64
42+
test.test_except_star.TestExceptStarRaiseFrom.test_raise_named @ linux-x86_64
43+
test.test_except_star.TestExceptStarRaiseFrom.test_raise_unnamed @ linux-x86_64
44+
test.test_except_star.TestExceptStarRaiseFrom.test_raise_handle_all_raise_one_named @ linux-x86_64
45+
test.test_except_star.TestExceptStarRaiseFrom.test_raise_handle_all_raise_one_unnamed @ linux-x86_64
46+
test.test_except_star.TestExceptStarRaiseFrom.test_raise_handle_all_raise_two_named @ linux-x86_64
47+
test.test_except_star.TestExceptStarRaiseFrom.test_raise_handle_all_raise_two_unnamed @ linux-x86_64
48+
test.test_except_star.TestExceptStarExceptionGroupSubclass.test_falsy_exception_group_subclass @ linux-x86_64
49+
test.test_except_star.TestExceptStarExceptionGroupSubclass.test_except_star_EG_subclass @ linux-x86_64
50+
test.test_except_star.TestExceptStarCleanup.test_sys_exception_restored @ linux-x86_64
51+
test.test_except_star.TestExceptStar_WeirdLeafExceptions.test_catch_unhashable_leaf_exception @ linux-x86_64
52+
test.test_except_star.TestExceptStar_WeirdLeafExceptions.test_propagate_unhashable_leaf @ linux-x86_64
53+
test.test_except_star.TestExceptStar_WeirdLeafExceptions.test_catch_nothing_unhashable_leaf @ linux-x86_64
54+
test.test_except_star.TestExceptStar_WeirdLeafExceptions.test_catch_everything_unhashable_leaf @ linux-x86_64
55+
test.test_except_star.TestExceptStar_WeirdLeafExceptions.test_reraise_unhashable_leaf @ linux-x86_64
56+
test.test_except_star.TestExceptStar_WeirdExceptionGroupSubclass.test_catch_some_unhashable_exception_group_subclass @ linux-x86_64
57+
test.test_except_star.TestExceptStar_WeirdExceptionGroupSubclass.test_catch_none_unhashable_exception_group_subclass @ linux-x86_64
58+
test.test_except_star.TestExceptStar_WeirdExceptionGroupSubclass.test_catch_all_unhashable_exception_group_subclass @ linux-x86_64

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionGroupBuiltins.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,11 @@ private static void createExceptionGroupType(Python3Core core) {
143143
@SlotSignature(name = "BaseExceptionGroup.__new__", minNumOfPositionalArgs = 3)
144144
@GenerateNodeFactory
145145
public abstract static class BaseExceptionGroupNode extends PythonTernaryBuiltinNode {
146+
@Override
147+
public abstract PBaseExceptionGroup execute(VirtualFrame frame, Object cls, Object messageObj, Object exceptionsObj);
146148

147149
@Specialization
148-
static Object doManaged(VirtualFrame frame, Object cls, Object messageObj, Object exceptionsObj,
150+
static PBaseExceptionGroup doManaged(VirtualFrame frame, Object cls, Object messageObj, Object exceptionsObj,
149151
@Bind Node inliningTarget,
150152
@Bind PythonLanguage language,
151153
@Cached TypeNodes.GetInstanceShape getInstanceShape,
@@ -233,6 +235,7 @@ static TruffleString str(PBaseExceptionGroup self,
233235
appendCodePointNode.execute(builder, 's');
234236
}
235237
appendCodePointNode.execute(builder, ')');
238+
// TODO: GR-70916 recursive printing of exception groups + indentation
236239
return toStringNode.execute(builder);
237240
}
238241
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/ChainExceptionsNode.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,44 @@
4848
import com.oracle.truffle.api.dsl.NeverDefault;
4949
import com.oracle.truffle.api.dsl.Specialization;
5050
import com.oracle.truffle.api.nodes.Node;
51+
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
5152
import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile;
5253

5354
@GenerateInline(false) // Used in BCI
5455
public abstract class ChainExceptionsNode extends Node {
5556
public abstract void execute(PException currentException, PException contextException);
5657

58+
private static boolean compare(PBaseExceptionGroup currentGroup, PBaseExceptionGroup contextGroup, Node inliningTarget, InlinedConditionProfile conditionProfile) {
59+
return conditionProfile.profile(
60+
inliningTarget,
61+
currentGroup != contextGroup && ((currentGroup.getParent() == null || contextGroup.getParent() == null) || currentGroup.getParent() != contextGroup.getParent()));
62+
}
63+
5764
@Specialization
5865
public static void chainExceptions(PException currentException, PException contextException,
5966
@Bind Node inliningTarget,
6067
@Cached ExceptionNodes.GetContextNode getContextNode,
6168
@Cached ExceptionNodes.SetContextNode setContextNode,
6269
@Cached InlinedLoopConditionProfile p1,
63-
@Cached InlinedLoopConditionProfile p2) {
70+
@Cached InlinedLoopConditionProfile p2,
71+
@Cached InlinedConditionProfile areExceptionGroups,
72+
@Cached InlinedConditionProfile compareCurrentAndContext) {
6473
Object current = currentException.getUnreifiedException();
6574
Object context = contextException.getUnreifiedException();
66-
if (current != context) {
75+
boolean shouldChain = false;
76+
boolean checkAreExceptionGroups = areExceptionGroups.profile(
77+
inliningTarget,
78+
current instanceof PBaseExceptionGroup && context instanceof PBaseExceptionGroup);
79+
if (checkAreExceptionGroups) {
80+
// for exception groups, the check needs to be done for parent, and not the original,
81+
// since some exceptions may be filtered out from `current` when evaluating the except*
82+
// match
83+
shouldChain = compare((PBaseExceptionGroup) current, (PBaseExceptionGroup) context, inliningTarget, compareCurrentAndContext);
84+
} else if (compareCurrentAndContext.profile(inliningTarget, current != context)) {
85+
shouldChain = true;
86+
}
87+
88+
if (shouldChain) {
6789
Object e = current;
6890
while (p1.profile(inliningTarget, e != PNone.NONE)) {
6991
Object eContext = getContextNode.execute(inliningTarget, e);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PBaseExceptionGroup.java

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -41,12 +41,32 @@
4141
package com.oracle.graal.python.builtins.objects.exception;
4242

4343
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
44+
import com.oracle.graal.python.runtime.exception.PException;
4445
import com.oracle.truffle.api.object.Shape;
4546
import com.oracle.truffle.api.strings.TruffleString;
4647

4748
public class PBaseExceptionGroup extends PBaseException {
4849
private final TruffleString message;
4950
private final Object[] exceptions;
51+
private PException parent;
52+
53+
/**
54+
* Flag to denote if the `exceptions` field contains only reraised and/or unmatched exceptions.
55+
*/
56+
private boolean containsReraises;
57+
58+
/**
59+
* This flag marks the outer/final exception group that encompasses all other exception groups
60+
* that are thrown at the end of the try-except* block. This is needed, since we can nest other
61+
* exception groups into exception groups themselves.
62+
*/
63+
private boolean isOuter;
64+
65+
/**
66+
* Context setting behaves somewhat differently when handling exception groups. This flag
67+
* assures, that context, after being once set, won't be set again/overwritten.
68+
*/
69+
private boolean contextWasExplicitlySet;
5070

5171
public PBaseExceptionGroup(Object cls, Shape instanceShape, TruffleString message, Object[] exceptions, PTuple args) {
5272
super(cls, instanceShape, null, args);
@@ -61,4 +81,59 @@ public Object[] getExceptions() {
6181
public TruffleString getMessage() {
6282
return message;
6383
}
84+
85+
public void setParent(PException parent) {
86+
this.parent = parent;
87+
}
88+
89+
public PException getParent() {
90+
return this.parent;
91+
}
92+
93+
/**
94+
* See {@link PBaseExceptionGroup#containsReraises}
95+
*/
96+
public void setContainsReraises(boolean value) {
97+
this.containsReraises = value;
98+
}
99+
100+
/**
101+
* See {@link PBaseExceptionGroup#containsReraises}
102+
*/
103+
public boolean getContainsReraises() {
104+
return this.containsReraises;
105+
}
106+
107+
/**
108+
* See {@link PBaseExceptionGroup#isOuter}
109+
*/
110+
public void setIsOuter(boolean value) {
111+
this.isOuter = value;
112+
}
113+
114+
/**
115+
* See {@link PBaseExceptionGroup#isOuter}
116+
*/
117+
public boolean getIsOuter() {
118+
return this.isOuter;
119+
}
120+
121+
/**
122+
* See {@link PBaseExceptionGroup#contextWasExplicitlySet}
123+
*/
124+
public void setContextExplicitly(Object context) {
125+
contextWasExplicitlySet = true;
126+
super.setContext(context);
127+
}
128+
129+
/**
130+
* See also {@link PBaseExceptionGroup#setContextExplicitly} and
131+
* {@link PBaseExceptionGroup#contextWasExplicitlySet}
132+
*/
133+
public void setContext(Object context) {
134+
if (contextWasExplicitlySet) {
135+
return;
136+
}
137+
super.setContext(context);
138+
}
64139
}

0 commit comments

Comments
 (0)