diff options
author | da-woods <dw-git@d-woods.co.uk> | 2022-07-27 10:19:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-27 11:19:35 +0200 |
commit | 72848313d8b8f06c14ae171e66d6f09f5312c325 (patch) | |
tree | ded2703d525a3a610febb5d5d6e40faef5ccfa13 | |
parent | 3de4be40a1642ffeec18d783cde9d285622b24ce (diff) | |
download | cython-72848313d8b8f06c14ae171e66d6f09f5312c325.tar.gz |
Backport "noexcept" function modifier to Cython 0.29.x (GH-4903)
As a no-op, but it parses fine.
Also add some basic compile tests, and some brief documentation.
-rw-r--r-- | Cython/Compiler/Parsing.py | 8 | ||||
-rw-r--r-- | docs/src/userguide/language_basics.rst | 11 | ||||
-rw-r--r-- | tests/compile/excvaldecl.pyx | 8 |
3 files changed, 26 insertions, 1 deletions
diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 82bf82d3d..2aafcb99a 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -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, @@ -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 diff --git a/docs/src/userguide/language_basics.rst b/docs/src/userguide/language_basics.rst index 0fdd87783..c3b9f36e4 100644 --- a/docs/src/userguide/language_basics.rst +++ b/docs/src/userguide/language_basics.rst @@ -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 + diff --git a/tests/compile/excvaldecl.pyx b/tests/compile/excvaldecl.pyx index 63f3c65dc..06af71ce0 100644 --- a/tests/compile/excvaldecl.pyx +++ b/tests/compile/excvaldecl.pyx @@ -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() |