Skip to content

Commit

Permalink
Backport "noexcept" function modifier to Cython 0.29.x (GH-4903)
Browse files Browse the repository at this point in the history
As a no-op, but it parses fine.

Also add some basic compile tests, and some brief documentation.
  • Loading branch information
da-woods authored Jul 27, 2022
1 parent 3de4be4 commit 7284831
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
8 changes: 7 additions & 1 deletion Cython/Compiler/Parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2820,6 +2820,8 @@ def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
s.expect(')')
nogil = p_nogil(s)
exc_val, exc_check = p_exception_value_clause(s)
# TODO - warning to enforce preferred exception specification order
nogil = nogil or p_nogil(s)
with_gil = p_with_gil(s)
return Nodes.CFuncDeclaratorNode(pos,
base = base, args = args, has_varargs = ellipsis,
Expand Down Expand Up @@ -2938,7 +2940,11 @@ def p_with_gil(s):
def p_exception_value_clause(s):
exc_val = None
exc_check = 0
if s.sy == 'except':

if s.sy == 'IDENT' and s.systring == 'noexcept':
s.next()
exc_check = False # No-op in Cython 0.29.x
elif s.sy == 'except':
s.next()
if s.sy == '*':
exc_check = 1
Expand Down
11 changes: 11 additions & 0 deletions docs/src/userguide/language_basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,17 @@ use this form, since there isn't any error return value to test.
Otherwise, an explicit error return value allows the C compiler to generate
more efficient code and is thus generally preferable.

To explicitly mark a function as not returning an exception use
``noexcept``.

cdef int spam() noexcept:
...

This is worth doing because (a) "explicit is better than implicit", and
(b) the default behaviour for ``cdef`` functions will change in Cython 3.0
so that functions will propagate exceptions by default. Therefore, it is
best to mark them now if you want them to swallow exceptions in the future.

An external C++ function that may raise an exception can be declared with::

cdef int spam() except +
Expand Down
8 changes: 8 additions & 0 deletions tests/compile/excvaldecl.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@ cdef int brian() except? 0:
cdef int silly() except -1:
pass

cdef int not_so_silly() noexcept:
pass

cdef int not_so_silly_and_gilless() noexcept nogil:
pass

spam()
eggs()
grail()
tomato()
brian()
silly()
not_so_silly()
not_so_silly_and_gilless()

0 comments on commit 7284831

Please sign in to comment.