Skip to content

Commit 42af319

Browse files
committed
Faster-to-compile pathway for raising exceptions.
1 parent a1fe0d3 commit 42af319

File tree

4 files changed

+57
-22
lines changed

4 files changed

+57
-22
lines changed

typed_python/_runtime.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2754,15 +2754,16 @@ extern "C" {
27542754
}
27552755

27562756
// set the python exception state, but don't actually throw.
2757-
void np_raise_exception_fastpath(const char* message, const char* exceptionTypeName) {
2757+
void np_raise_exception_str(PythonObjectOfType::layout_type* exceptionType, const char* message) {
27582758
PyEnsureGilAcquired getTheGil;
27592759

2760-
PyObject* excType = PyObject_GetAttrString(builtinsModule(), exceptionTypeName);
2761-
if (!excType) {
2762-
return;
2760+
if (message) {
2761+
PyErr_SetString(exceptionType->pyObj, message);
2762+
} else {
2763+
PyErr_SetNone(exceptionType->pyObj);
27632764
}
27642765

2765-
PyErr_SetString(excType, message);
2766+
throw PythonExceptionSet();
27662767
}
27672768

27682769
BytesType::layout* np_serialize_no_context(instance_ptr data, Type* type) {

typed_python/compiler/expression_conversion_context.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,33 +1286,44 @@ def pushException(self, excType, *args, **kwargs):
12861286
Returns:
12871287
None
12881288
"""
1289+
if len(args) == 0 and isinstance(excType, type):
1290+
self.pushEffect(
1291+
runtime_functions.np_raise_exception_str.call(
1292+
self.constantPyObject(excType).nonref_expr.cast(native_ast.VoidPtr),
1293+
native_ast.UInt8.pointer().zero(),
1294+
)
1295+
)
1296+
return None
1297+
12891298
if len(args) == 1 and isinstance(args[0], str) and isinstance(excType, type):
12901299
# this is the most common pathway
1291-
if id(excType) in builtinValueIdToNameAndValue:
1292-
self.pushEffect(
1293-
runtime_functions.raise_exception_fastpath.call(
1294-
native_ast.const_utf8_cstr(args[0]),
1295-
native_ast.const_utf8_cstr(builtinValueIdToNameAndValue[id(excType)][0])
1296-
)
1300+
self.pushEffect(
1301+
runtime_functions.np_raise_exception_str.call(
1302+
self.constantPyObject(excType).nonref_expr.cast(native_ast.VoidPtr),
1303+
native_ast.const_utf8_cstr(args[0]),
12971304
)
1298-
self.pushEffect(
1299-
native_ast.Expression.Throw(
1300-
expr=native_ast.Expression.Constant(
1301-
val=native_ast.Constant.NullPointer(value_type=native_ast.UInt8.pointer())
1302-
)
1303-
)
1304-
)
1305-
return None
1305+
)
1306+
return None
13061307

13071308
def toTyped(x):
13081309
if isinstance(x, TypedExpression):
13091310
return x
13101311
return self.constant(x)
13111312

1313+
origExcType = excType
13121314
excType = toTyped(excType)
13131315
args = [toTyped(x) for x in args]
13141316
kwargs = {k: toTyped(v) for k, v in kwargs.items()}
13151317

1318+
if len(args) == 1 and isinstance(args[0].constantValue, str) and isinstance(origExcType, type):
1319+
self.pushEffect(
1320+
runtime_functions.np_raise_exception_str.call(
1321+
self.constantPyObject(origExcType).nonref_expr.cast(native_ast.VoidPtr),
1322+
native_ast.const_utf8_cstr(args[0].constantValue),
1323+
)
1324+
)
1325+
return None
1326+
13161327
if excType is None:
13171328
return None
13181329

typed_python/compiler/tests/exception_handling_test.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,25 @@ def catcher(toRaise):
220220

221221
with pytest.raises(RuntimeError):
222222
catcher(RuntimeError)
223+
224+
225+
def test_convert_assert():
226+
@Entrypoint
227+
def assertIt(x):
228+
assert x
229+
230+
assertIt(True)
231+
232+
with pytest.raises(AssertionError):
233+
assertIt(False)
234+
235+
236+
def test_convert_assert_str():
237+
@Entrypoint
238+
def assertIt(x):
239+
assert x, "failed"
240+
241+
assertIt(True)
242+
243+
with pytest.raises(AssertionError):
244+
assertIt(False)

typed_python/compiler/type_wrappers/runtime_functions.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,11 +1163,12 @@ def unaryPyobjCallTarget(name, retType=Void.pointer()):
11631163
)
11641164

11651165
# sets the python exception state to an exception of type
1166-
raise_exception_fastpath = externalCallTarget(
1167-
"np_raise_exception_fastpath",
1166+
np_raise_exception_str = externalCallTarget(
1167+
"np_raise_exception_str",
11681168
Void,
1169+
Void.pointer(),
11691170
UInt8Ptr,
1170-
UInt8Ptr
1171+
canThrow=True
11711172
)
11721173

11731174
raiseAttributeError = externalCallTarget(

0 commit comments

Comments
 (0)