Skip to content

Commit a6d8e13

Browse files
committed
Fix exception handling in 'python_cext' module.
1 parent ec5be2f commit a6d8e13

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/control/TopLevelExceptionHandler.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public Object execute(VirtualFrame frame) {
103103
printExc(exception);
104104
return null;
105105
} else {
106+
assert context.getCurrentException() == null;
106107
try {
107108
return run(frame);
108109
} catch (PException e) {
@@ -116,6 +117,8 @@ public Object execute(VirtualFrame frame) {
116117
}
117118
}
118119
throw e;
120+
} finally {
121+
context.setCurrentException(null);
119122
}
120123
}
121124
}

graalpython/lib-graalpython/python_cext.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,12 @@ def may_raise(error_result=error_handler):
6161
else:
6262
def decorator(fun):
6363
def wrapper(*args):
64-
with error_handler:
64+
typ = val = tb = None
65+
try:
6566
return fun(*args)
67+
except BaseException as e:
68+
typ, val, tb = sys.exc_info()
69+
PyErr_Restore(typ, val, tb)
6670
return error_result
6771
wrapper.__name__ = fun.__name__
6872
return wrapper
@@ -141,7 +145,7 @@ def PyDict_Size(dictObj):
141145
@may_raise(None)
142146
def PyDict_Copy(dictObj):
143147
if not isinstance(dictObj, dict):
144-
_PyErr_BadInternalCall(None, None, dictObj)
148+
__bad_internal_call(None, None, dictObj)
145149
return dictObj.copy()
146150

147151

@@ -171,7 +175,7 @@ def PyDict_DelItem(dictObj, key):
171175
@may_raise(-1)
172176
def PyDict_Contains(dictObj, key):
173177
if not isinstance(dictObj, dict):
174-
_PyErr_BadInternalCall(None, None, dictObj)
178+
__bad_internal_call(None, None, dictObj)
175179
return key in dictObj
176180

177181

@@ -264,14 +268,14 @@ def PyBytes_FromFormat(fmt, args):
264268
@may_raise
265269
def PyList_New(size):
266270
if size < 0:
267-
_PyErr_BadInternalCall(None, None, None)
271+
__bad_internal_call(None, None, None)
268272
return [None] * size
269273

270274

271275
@may_raise
272276
def PyList_GetItem(listObj, pos):
273277
if not isinstance(listObj, list):
274-
_PyErr_BadInternalCall(None, None, listObj)
278+
__bad_internal_call(None, None, listObj)
275279
if pos < 0:
276280
raise IndexError("list index out of range")
277281
return listObj[pos]
@@ -280,7 +284,7 @@ def PyList_GetItem(listObj, pos):
280284
@may_raise(-1)
281285
def PyList_SetItem(listObj, pos, newitem):
282286
if not isinstance(listObj, list):
283-
_PyErr_BadInternalCall(None, None, listObj)
287+
__bad_internal_call(None, None, listObj)
284288
if pos < 0:
285289
raise IndexError("list assignment index out of range")
286290
listObj[pos] = newitem
@@ -290,7 +294,7 @@ def PyList_SetItem(listObj, pos, newitem):
290294
@may_raise(-1)
291295
def PyList_Append(listObj, newitem):
292296
if not isinstance(listObj, list):
293-
_PyErr_BadInternalCall(None, None, listObj)
297+
__bad_internal_call(None, None, listObj)
294298
listObj.append(newitem)
295299
return 0
296300

@@ -305,14 +309,14 @@ def PyList_AsTuple(listObj):
305309
@may_raise
306310
def PyList_GetSlice(listObj, ilow, ihigh):
307311
if not isinstance(listObj, list):
308-
_PyErr_BadInternalCall(None, None, listObj)
312+
__bad_internal_call(None, None, listObj)
309313
return listObj[ilow:ihigh]
310314

311315

312316
@may_raise(-1)
313317
def PyList_Size(listObj):
314318
if not isinstance(listObj, list):
315-
_PyErr_BadInternalCall(None, None, listObj)
319+
__bad_internal_call(None, None, listObj)
316320
return len(listObj)
317321

318322

@@ -792,21 +796,21 @@ def PyTuple_New(size):
792796
@may_raise
793797
def PyTuple_GetItem(t, n):
794798
if not isinstance(t, tuple):
795-
_PyErr_BadInternalCall(None, None, t)
799+
__bad_internal_call(None, None, t)
796800
return t[n]
797801

798802

799803
@may_raise(-1)
800804
def PyTuple_Size(t):
801805
if not isinstance(t, tuple):
802-
_PyErr_BadInternalCall(None, None, t)
806+
__bad_internal_call(None, None, t)
803807
return len(t)
804808

805809

806810
@may_raise
807811
def PyTuple_GetSlice(t, start, end):
808812
if not isinstance(t, tuple):
809-
_PyErr_BadInternalCall(None, None, t)
813+
__bad_internal_call(None, None, t)
810814
return t[start:end]
811815

812816

@@ -908,6 +912,11 @@ def PyErr_CreateAndSetException(exception_type, msg):
908912

909913
@may_raise(None)
910914
def _PyErr_BadInternalCall(filename, lineno, obj):
915+
__bad_internal_call(filename, lineno, obj)
916+
917+
918+
# IMPORTANT: only call from functions annotated with 'may_raise'
919+
def __bad_internal_call(filename, lineno, obj):
911920
if filename is not None and lineno is not None:
912921
msg = "{!s}:{!s}: bad argument to internal function".format(filename, lineno)
913922
else:

0 commit comments

Comments
 (0)