Skip to content

Commit 9e91466

Browse files
committed
Set AttributeError attributes when appropriate
1 parent 16a4dc6 commit 9e91466

File tree

12 files changed

+92
-30
lines changed

12 files changed

+92
-30
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TimeModuleBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ Object tzset() {
328328
}
329329
TimeZone.setDefault(TimeZone.getTimeZone(tzEnv));
330330
} else {
331-
PRaiseNode.raiseStatic(this, PythonBuiltinClassType.AttributeError, SET_TIMEZONE_ERROR);
331+
throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.AttributeError, SET_TIMEZONE_ERROR);
332332
}
333333
return PNone.NONE;
334334
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@
105105
import com.oracle.graal.python.lib.PyDictSetDefault;
106106
import com.oracle.graal.python.lib.PyObjectGetAttr;
107107
import com.oracle.graal.python.lib.PyObjectHashNode;
108-
import com.oracle.graal.python.lib.PyObjectLookupAttr;
109108
import com.oracle.graal.python.nodes.PRaiseNode;
110109
import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode;
111110
import com.oracle.graal.python.nodes.call.CallNode;
@@ -521,15 +520,15 @@ abstract static class PyDict_Merge extends CApiTernaryBuiltinNode {
521520
@Specialization(guards = {"override != 0"})
522521
static int merge(PDict a, Object b, @SuppressWarnings("unused") int override,
523522
@Bind("this") Node inliningTarget,
524-
@Cached PyObjectLookupAttr lookupKeys,
525-
@Cached PyObjectLookupAttr lookupAttr,
523+
@Shared @Cached PyObjectGetAttr getKeys,
524+
@Cached PyObjectGetAttr getUpdate,
526525
@Shared @Cached CallNode callNode,
527526
@Cached PRaiseNode raiseNode) {
528527
// lookup "keys" to raise the right error:
529-
if (lookupKeys.execute(null, inliningTarget, b, T_KEYS) == PNone.NO_VALUE) {
528+
if (getKeys.execute(null, inliningTarget, b, T_KEYS) == PNone.NO_VALUE) {
530529
throw raiseNode.raise(inliningTarget, AttributeError, OBJ_P_HAS_NO_ATTR_S, b, T_KEYS);
531530
}
532-
Object updateCallable = lookupAttr.execute(null, inliningTarget, a, T_UPDATE);
531+
Object updateCallable = getUpdate.execute(null, inliningTarget, a, T_UPDATE);
533532
callNode.executeWithoutFrame(updateCallable, new Object[]{b});
534533
return 0;
535534
}
@@ -561,7 +560,7 @@ static int merge(PDict a, PDict b, @SuppressWarnings("unused") int override,
561560
@Specialization(guards = {"override == 0", "!isDict(b)"})
562561
static int merge(PDict a, Object b, @SuppressWarnings("unused") int override,
563562
@Bind("this") Node inliningTarget,
564-
@Cached PyObjectGetAttr getAttrNode,
563+
@Shared @Cached PyObjectGetAttr getKeys,
565564
@Shared @Cached CallNode callNode,
566565
@Cached ConstructListNode listNode,
567566
@Cached GetItemNode getKeyNode,
@@ -570,7 +569,7 @@ static int merge(PDict a, Object b, @SuppressWarnings("unused") int override,
570569
@Cached HashingStorageSetItem setItemA,
571570
@Exclusive @Cached InlinedLoopConditionProfile loopProfile,
572571
@Cached InlinedBranchProfile noKeyProfile) {
573-
Object attr = getAttrNode.execute(null, inliningTarget, a, T_KEYS);
572+
Object attr = getKeys.execute(null, inliningTarget, a, T_KEYS);
574573
PList keys = listNode.execute(null, callNode.execute(null, attr));
575574

576575
SequenceStorage keysStorage = keys.getSequenceStorage();

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,22 @@
6868
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
6969
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
7070
import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
71+
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles;
7172
import com.oracle.graal.python.nodes.object.GetClassNode;
7273
import com.oracle.graal.python.nodes.object.GetDictIfExistsNode;
74+
import com.oracle.graal.python.runtime.exception.PException;
7375
import com.oracle.graal.python.runtime.object.PFactory;
7476
import com.oracle.truffle.api.dsl.Bind;
7577
import com.oracle.truffle.api.dsl.Cached;
78+
import com.oracle.truffle.api.dsl.GenerateCached;
79+
import com.oracle.truffle.api.dsl.GenerateInline;
7680
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
81+
import com.oracle.truffle.api.dsl.GenerateUncached;
7782
import com.oracle.truffle.api.dsl.NodeFactory;
7883
import com.oracle.truffle.api.dsl.Specialization;
7984
import com.oracle.truffle.api.frame.VirtualFrame;
8085
import com.oracle.truffle.api.nodes.Node;
86+
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
8187
import com.oracle.truffle.api.profiles.InlinedLoopConditionProfile;
8288
import com.oracle.truffle.api.strings.TruffleString;
8389

@@ -100,6 +106,10 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
100106

101107
private static final BaseExceptionAttrNode.StorageFactory ATTR_FACTORY = (args) -> new Object[NUM_ATTRS];
102108

109+
public static Object[] dataForObjKey(Object obj, Object key) {
110+
return new Object[]{key, obj};
111+
}
112+
103113
@Slot(value = SlotKind.tp_init, isComplex = true)
104114
@SlotSignature(minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
105115
@GenerateNodeFactory
@@ -199,4 +209,27 @@ static Object reduce(VirtualFrame frame, PBaseException self,
199209
return PFactory.createTuple(language, new Object[]{clazz, args, state});
200210
}
201211
}
212+
213+
@GenerateInline
214+
@GenerateCached(false)
215+
@GenerateUncached
216+
public abstract static class SetAttributeErrorContext extends Node {
217+
public abstract PException execute(Node inliningTarget, PException e, Object obj, Object name);
218+
219+
@Specialization
220+
static PException set(Node inliningTarget, PException e, Object obj, Object name,
221+
@Cached BuiltinClassProfiles.IsBuiltinObjectProfile errorProfile,
222+
@Cached BaseExceptionAttrNode attrNode,
223+
@Cached InlinedConditionProfile writeAttrsProfile) {
224+
e.expectAttributeError(inliningTarget, errorProfile);
225+
if (writeAttrsProfile.profile(inliningTarget, e.getUnreifiedException() instanceof PBaseException exception &&
226+
exception.getExceptionAttributes() != null &&
227+
exception.getExceptionAttributes()[IDX_NAME] == null && exception.getExceptionAttributes()[IDX_OBJ] == null)) {
228+
PBaseException exception = (PBaseException) e.getUnreifiedException();
229+
attrNode.set(exception, name, IDX_NAME, ATTR_FACTORY);
230+
attrNode.set(exception, obj, IDX_OBJ, ATTR_FACTORY);
231+
}
232+
throw e;
233+
}
234+
}
202235
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ private static PDict createDict(Node inliningTarget, PythonModule self, SetDictN
251251

252252
@Slot(value = SlotKind.tp_getattro, isComplex = true)
253253
@GenerateNodeFactory
254-
public abstract static class ModuleGetattritbuteNode extends GetAttrBuiltinNode {
254+
public abstract static class ModuleGetattributeNode extends GetAttrBuiltinNode {
255255
@Specialization
256256
static Object getattributeStr(VirtualFrame frame, PythonModule self, TruffleString key,
257257
@Shared @Cached ObjectBuiltins.GetAttributeNode objectGetattrNode,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ private Object fullLookup(VirtualFrame frame, Node inliningTarget, Object object
583583
return dispatch(frame, object, type, descr, descrGetSlot);
584584
}
585585
}
586-
throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key);
586+
throw raiseNode.raiseAttributeError(inliningTarget, object, key);
587587
}
588588

589589
private Object readAttribute(Object object, TruffleString key) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalBuiltins.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
package com.oracle.graal.python.builtins.objects.thread;
4242

4343
import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DICT__;
44-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError;
4544

4645
import java.util.List;
4746

@@ -185,7 +184,7 @@ Object doIt(VirtualFrame frame, PThreadLocal object, Object keyObj,
185184
return dispatch(frame, object, type, descr, descrGetSlot);
186185
}
187186
}
188-
throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key);
187+
throw raiseNode.raiseAttributeError(inliningTarget, object, key);
189188
}
190189

191190
private Object dispatch(VirtualFrame frame, Object object, Object type, Object descr, TpSlot get) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode;
9494
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToArrayNode;
9595
import com.oracle.graal.python.builtins.objects.dict.PDict;
96+
import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins;
9697
import com.oracle.graal.python.builtins.objects.function.AbstractFunctionBuiltins;
9798
import com.oracle.graal.python.builtins.objects.function.PKeyword;
9899
import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorDeleteMarker;
@@ -574,7 +575,7 @@ protected Object doIt(VirtualFrame frame, Object object, Object keyObj,
574575
}
575576
}
576577
errorProfile.enter(inliningTarget);
577-
throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.OBJ_N_HAS_NO_ATTR_S, object, key);
578+
throw raiseNode.raiseWithData(inliningTarget, AttributeError, AttributeErrorBuiltins.dataForObjKey(object, key), ErrorMessages.OBJ_N_HAS_NO_ATTR_S, object, key);
578579
}
579580

580581
private Object readAttribute(Object object, TruffleString key) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@
4040
*/
4141
package com.oracle.graal.python.lib;
4242

43-
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4443
import com.oracle.graal.python.builtins.objects.PNone;
44+
import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins;
4545
import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode;
4646
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.CallSlotGetAttrNode;
47-
import com.oracle.graal.python.nodes.ErrorMessages;
4847
import com.oracle.graal.python.nodes.PRaiseNode;
4948
import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode;
5049
import com.oracle.graal.python.nodes.object.GetClassNode;
50+
import com.oracle.graal.python.runtime.exception.PException;
5151
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
5252
import com.oracle.truffle.api.dsl.Cached;
5353
import com.oracle.truffle.api.dsl.GenerateCached;
@@ -96,6 +96,7 @@ static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver,
9696
@Cached GetClassNode getClass,
9797
@Cached GetObjectSlotsNode getSlotsNode,
9898
@Cached CallSlotGetAttrNode callGetAttrNode,
99+
@Cached AttributeErrorBuiltins.SetAttributeErrorContext setContext,
99100
@Cached(inline = false) TruffleString.CodePointLengthNode codePointLengthNode,
100101
@Cached(inline = false) TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
101102
Object type = getClass.execute(inliningTarget, receiver);
@@ -105,12 +106,16 @@ static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver,
105106
Object result = PyObjectLookupAttr.readAttributeQuickly(type, slots, receiver, name, codePointLengthNode, codePointAtIndexNode);
106107
if (result != null) {
107108
if (result == PNone.NO_VALUE) {
108-
throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name);
109+
throw PRaiseNode.raiseAttributeErrorStatic(inliningTarget, receiver, name);
109110
}
110111
return result;
111112
}
112113
}
113-
return callGetAttrNode.execute((VirtualFrame) frame, inliningTarget, slots, receiver, name);
114+
try {
115+
return callGetAttrNode.execute((VirtualFrame) frame, inliningTarget, slots, receiver, name);
116+
} catch (PException e) {
117+
throw setContext.execute(inliningTarget, e, receiver, name);
118+
}
114119
}
115120

116121
@NeverDefault

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
*/
4141
package com.oracle.graal.python.lib;
4242

43-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError;
44-
4543
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4644
import com.oracle.graal.python.builtins.objects.PNone;
4745
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
@@ -52,7 +50,6 @@
5250
import com.oracle.graal.python.builtins.objects.type.slots.TpSlot;
5351
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet;
5452
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet;
55-
import com.oracle.graal.python.nodes.ErrorMessages;
5653
import com.oracle.graal.python.nodes.PRaiseNode;
5754
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
5855
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
@@ -160,7 +157,7 @@ static Object getFixedAttr(VirtualFrame frame, Node inliningTarget, Object recei
160157
if (descr != PNone.NO_VALUE) {
161158
return new BoundDescriptor(descr);
162159
}
163-
throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name);
160+
throw raiseNode.raiseAttributeError(inliningTarget, receiver, name);
164161
}
165162

166163
// No explicit branch profiling when we're looking up multiple things
@@ -205,7 +202,7 @@ static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver,
205202
if (descr != PNone.NO_VALUE) {
206203
return new BoundDescriptor(descr);
207204
}
208-
throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name);
205+
throw raiseNode.raiseAttributeError(inliningTarget, receiver, name);
209206
}
210207

211208
@Specialization(guards = "isForeignObject(inliningTarget, isForeignObjectNode, receiver)", limit = "1")

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.oracle.graal.python.PythonLanguage;
4747
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4848
import com.oracle.graal.python.builtins.objects.PNone;
49+
import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins;
4950
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
5051
import com.oracle.graal.python.lib.PyExceptionInstanceCheckNode;
5152
import com.oracle.graal.python.runtime.PythonOptions;
@@ -129,6 +130,26 @@ public static PException raiseWithDataStatic(Node node, PythonBuiltinClassType t
129130
throw raiseExceptionObject(node, pythonException, language);
130131
}
131132

133+
public final PException raiseAttributeError(Node inliningTarget, Object obj, Object key) {
134+
executeEnterProfile(inliningTarget);
135+
throw raiseAttributeErrorStatic(inliningTarget, obj, key);
136+
}
137+
138+
public static PException raiseAttributeErrorStatic(Node inliningTarget, Object obj, Object key) {
139+
throw raiseWithDataStatic(inliningTarget, PythonBuiltinClassType.AttributeError, AttributeErrorBuiltins.dataForObjKey(obj, key), ErrorMessages.OBJ_P_HAS_NO_ATTR_S, obj, key);
140+
}
141+
142+
public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassType type, Object[] data, TruffleString format, Object... formatArgs) {
143+
executeEnterProfile(inliningTarget);
144+
throw raiseWithDataStatic(inliningTarget, type, data, format, formatArgs);
145+
}
146+
147+
public static PException raiseWithDataStatic(Node node, PythonBuiltinClassType type, Object[] data, TruffleString format, Object... formatArgs) {
148+
PythonLanguage language = PythonLanguage.get(node);
149+
PBaseException pythonException = PFactory.createBaseException(language, type, data, format, formatArgs);
150+
throw raiseExceptionObject(node, pythonException, language);
151+
}
152+
132153
public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassType type, Object[] data, Object... arguments) {
133154
executeEnterProfile(inliningTarget);
134155
throw raiseWithDataStatic(inliningTarget, type, data, arguments);

0 commit comments

Comments
 (0)