summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2022-07-27 10:19:35 +0100
committerGitHub <noreply@github.com>2022-07-27 11:19:35 +0200
commit72848313d8b8f06c14ae171e66d6f09f5312c325 (patch)
treeded2703d525a3a610febb5d5d6e40faef5ccfa13
parent3de4be40a1642ffeec18d783cde9d285622b24ce (diff)
downloadcython-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.py8
-rw-r--r--docs/src/userguide/language_basics.rst11
-rw-r--r--tests/compile/excvaldecl.pyx8
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()