@@ -126,7 +126,7 @@ public Object doForeignObjectSlice(Object object, PSlice idxSlice,
126
126
try {
127
127
mslice = materializeSlice (idxSlice , object , lib );
128
128
} catch (UnsupportedMessageException e ) {
129
- throw raise ( AttributeError , "%s instance has no attribute '__getitem__'" , object );
129
+ throw raiseAttributeError ( object );
130
130
}
131
131
Object [] values = new Object [mslice .length ];
132
132
for (int i = mslice .start , j = 0 ; i < mslice .stop ; i += mslice .step , j ++) {
@@ -138,17 +138,19 @@ public Object doForeignObjectSlice(Object object, PSlice idxSlice,
138
138
@ Specialization
139
139
public Object doForeignKey (Object object , String key ,
140
140
@ CachedLibrary (limit = "3" ) InteropLibrary lib ) {
141
- try {
142
- return lib .readMember (object , key );
143
- } catch (UnsupportedMessageException e ) {
144
- if (lib .hasArrayElements (object )) {
145
- throw raise (TypeError , "'%p' object cannot be interpreted as an integer" , key );
146
- } else {
147
- throw raise (AttributeError , "%s instance has no attribute '__getitem__'" , object );
141
+ if (lib .hasMembers (object )) {
142
+ if (lib .isMemberReadable (object , key )) {
143
+ try {
144
+ return lib .readMember (object , key );
145
+ } catch (UnsupportedMessageException e ) {
146
+ throw raiseAttributeErrorDisambiguated (object , key , lib );
147
+ } catch (UnknownIdentifierException e ) {
148
+ // fall through
149
+ }
148
150
}
149
- } catch (UnknownIdentifierException e ) {
150
151
throw raise (KeyError , key );
151
152
}
153
+ throw raiseAttributeErrorDisambiguated (object , key , lib );
152
154
}
153
155
154
156
@ Specialization (guards = {"!isSlice(idx)" , "!isString(idx)" })
@@ -158,14 +160,36 @@ public Object doForeignObject(Object object, Object idx,
158
160
return readForeignValue (object , castIndex .execute (idx ), lib );
159
161
}
160
162
163
+ private PException raiseAttributeErrorDisambiguated (Object object , String key , InteropLibrary lib ) {
164
+ if (lib .hasArrayElements (object )) {
165
+ throw raise (TypeError , "'%p' object cannot be interpreted as an integer" , key );
166
+ } else {
167
+ throw raiseAttributeError (object );
168
+ }
169
+ }
170
+
161
171
private Object readForeignValue (Object object , long index , InteropLibrary lib ) {
162
- try {
163
- return getToPythonNode ().executeConvert (lib .readArrayElement (object , index ));
164
- } catch (UnsupportedMessageException ex ) {
165
- throw raise (AttributeError , "%s instance has no attribute '__getitem__'" , object );
166
- } catch (InvalidArrayIndexException ex ) {
167
- throw raise (IndexError , "invalid index %s" , index );
172
+ if (lib .hasArrayElements (object )) {
173
+ if (lib .isArrayElementReadable (object , index )) {
174
+ try {
175
+ return getToPythonNode ().executeConvert (lib .readArrayElement (object , index ));
176
+ } catch (UnsupportedMessageException ex ) {
177
+ throw raiseAttributeError (object );
178
+ } catch (InvalidArrayIndexException ex ) {
179
+ throw raiseIndexError (index );
180
+ }
181
+ }
182
+ throw raiseIndexError (index );
168
183
}
184
+ throw raiseAttributeError (object );
185
+ }
186
+
187
+ private PException raiseIndexError (long index ) {
188
+ return raise (IndexError , "invalid index %s" , index );
189
+ }
190
+
191
+ private PException raiseAttributeError (Object object ) {
192
+ return raise (AttributeError , "%s instance has no attribute '__getitem__'" , object );
169
193
}
170
194
171
195
private PForeignToPTypeNode getToPythonNode () {
@@ -207,22 +231,40 @@ public Object doForeignObjectSlice(VirtualFrame frame, Object object, PSlice idx
207
231
@ Specialization
208
232
public Object doForeignKey (Object object , String key , Object value ,
209
233
@ CachedLibrary (limit = "3" ) InteropLibrary lib ) {
210
- try {
211
- lib .writeMember (object , key , value );
212
- return PNone .NONE ;
213
- } catch (UnsupportedMessageException e ) {
214
- if (lib .hasArrayElements (object )) {
215
- throw raise (TypeError , "'%p' object cannot be interpreted as an integer" , key );
216
- } else {
217
- throw raise (AttributeError , "attribute %s is read-only" , key );
234
+ if (lib .hasMembers (object )) {
235
+ if (lib .isMemberWritable (object , key )) {
236
+ try {
237
+ lib .writeMember (object , key , value );
238
+ return PNone .NONE ;
239
+ } catch (UnsupportedMessageException e ) {
240
+ throw raiseAttributeReadOnlyDisambiguated (object , key , lib );
241
+ } catch (UnknownIdentifierException e ) {
242
+ throw raiseAttributeError (key );
243
+ } catch (UnsupportedTypeException e ) {
244
+ throw raiseAttributeReadOnly (key );
245
+ }
218
246
}
219
- } catch (UnknownIdentifierException e ) {
220
- throw raise (AttributeError , "foreign object has no attribute '%s'" , key );
221
- } catch (UnsupportedTypeException e ) {
222
- throw raise (AttributeError , "attribute %s is read-only" , key );
247
+ throw raiseAttributeReadOnlyDisambiguated (object , key , lib );
248
+ }
249
+ throw raiseAttributeError (key );
250
+ }
251
+
252
+ private PException raiseAttributeReadOnlyDisambiguated (Object object , String key , InteropLibrary lib ) {
253
+ if (lib .hasArrayElements (object )) {
254
+ throw raise (TypeError , "'%p' object cannot be interpreted as an integer" , key );
255
+ } else {
256
+ throw raiseAttributeReadOnly (key );
223
257
}
224
258
}
225
259
260
+ private PException raiseAttributeReadOnly (String key ) {
261
+ return raise (AttributeError , "attribute %s is read-only" , key );
262
+ }
263
+
264
+ private PException raiseAttributeError (String key ) {
265
+ return raise (AttributeError , "foreign object has no attribute '%s'" , key );
266
+ }
267
+
226
268
@ Specialization (guards = {"!isSlice(idx)" , "!isString(idx)" })
227
269
public Object doForeignObject (Object object , Object idx , Object value ,
228
270
@ CachedLibrary (limit = "3" ) InteropLibrary lib ,
@@ -239,13 +281,16 @@ public Object doForeignObject(Object object, Object idx, Object value,
239
281
}
240
282
241
283
private void writeForeignValue (Object object , int idx , Object value , InteropLibrary lib ) throws UnsupportedMessageException , UnsupportedTypeException {
242
- if (lib .isArrayElementModifiable (object , idx )) {
243
- try {
244
- lib .writeArrayElement (object , idx , value );
245
- return ;
246
- } catch (InvalidArrayIndexException ex ) {
247
- throw raise (IndexError , "invalid index %s" , idx );
284
+ if (lib .hasArrayElements (object )) {
285
+ if (lib .isArrayElementWritable (object , idx )) {
286
+ try {
287
+ lib .writeArrayElement (object , idx , value );
288
+ return ;
289
+ } catch (InvalidArrayIndexException ex ) {
290
+ // fall through
291
+ }
248
292
}
293
+ throw raise (IndexError , "invalid index %s" , idx );
249
294
}
250
295
throw raise (AttributeError , "%s instance has no attribute '__setitem__'" , object );
251
296
}
@@ -270,37 +315,58 @@ public Object doForeignObjectSlice(Object object, PSlice idxSlice,
270
315
}
271
316
return PNone .NONE ;
272
317
} catch (UnsupportedMessageException e ) {
273
- throw raise ( AttributeError , "%s instance has no attribute '__delitem__'" , object );
318
+ throw raiseAttributeError ( object );
274
319
}
275
320
}
276
321
277
322
@ Specialization
278
323
public Object doForeignKey (Object object , String key ,
279
324
@ CachedLibrary (limit = "3" ) InteropLibrary lib ) {
280
- try {
281
- lib .removeMember (object , key );
282
- return PNone .NONE ;
283
- } catch (UnsupportedMessageException e ) {
284
- if (lib .hasArrayElements (object )) {
285
- throw raise (TypeError , "'%p' object cannot be interpreted as an integer" , key );
286
- } else {
287
- throw raise (AttributeError , "attribute %s is read-only" , key );
325
+ if (lib .hasMembers (object )) {
326
+ if (lib .isMemberRemovable (object , key )) {
327
+ try {
328
+ lib .removeMember (object , key );
329
+ return PNone .NONE ;
330
+ } catch (UnsupportedMessageException e ) {
331
+ throw raiseAttributeReadOnlyDisambiguated (object , key , lib );
332
+ } catch (UnknownIdentifierException e ) {
333
+ throw raiseAttributeError (key );
334
+ }
288
335
}
289
- } catch (UnknownIdentifierException e ) {
290
- throw raise (AttributeError , "foreign object has no attribute '%s'" , key );
336
+ throw raiseAttributeReadOnlyDisambiguated (object , key , lib );
337
+ }
338
+ throw raiseAttributeError (key );
339
+ }
340
+
341
+ private PException raiseAttributeError (String key ) {
342
+ return raise (AttributeError , "foreign object has no attribute '%s'" , key );
343
+ }
344
+
345
+ private PException raiseAttributeReadOnlyDisambiguated (Object object , String key , InteropLibrary lib ) {
346
+ if (lib .hasArrayElements (object )) {
347
+ throw raise (TypeError , "'%p' object cannot be interpreted as an integer" , key );
348
+ } else {
349
+ throw raise (AttributeError , "attribute %s is read-only" , key );
291
350
}
292
351
}
293
352
294
353
@ Specialization (guards = "!isSlice(idx)" )
295
354
public Object doForeignObject (Object object , Object idx ,
296
355
@ Cached CastToIndexNode castIndex ,
297
356
@ CachedLibrary (limit = "3" ) InteropLibrary lib ) {
298
- try {
299
- int convertedIdx = castIndex .execute (idx );
300
- return removeForeignValue (object , convertedIdx , lib );
301
- } catch (UnsupportedMessageException e ) {
302
- throw raise (AttributeError , "%s instance has no attribute '__delitem__'" , object );
357
+ if (lib .hasArrayElements (object )) {
358
+ try {
359
+ int convertedIdx = castIndex .execute (idx );
360
+ return removeForeignValue (object , convertedIdx , lib );
361
+ } catch (UnsupportedMessageException e ) {
362
+ // fall through
363
+ }
303
364
}
365
+ throw raiseAttributeError (object );
366
+ }
367
+
368
+ private PException raiseAttributeError (Object object ) {
369
+ return raise (AttributeError , "%s instance has no attribute '__delitem__'" , object );
304
370
}
305
371
306
372
private Object removeForeignValue (Object object , int idx , InteropLibrary lib ) throws UnsupportedMessageException {
@@ -311,7 +377,7 @@ private Object removeForeignValue(Object object, int idx, InteropLibrary lib) th
311
377
throw raise (IndexError , "invalid index %s" , idx );
312
378
}
313
379
}
314
- throw raise ( AttributeError , "%s instance has no attribute '__delitem__'" , object );
380
+ throw raiseAttributeError ( object );
315
381
}
316
382
317
383
public static RemoveForeignItemNode create () {
0 commit comments