summaryrefslogtreecommitdiff
path: root/Cython/Compiler/ParseTreeTransforms.py
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2017-09-08 16:24:04 +0200
committerStefan Behnel <stefan_ml@behnel.de>2017-09-09 19:26:41 +0200
commita3ffd72f344b543a57dbc213e1952ee20567d54d (patch)
tree76e70dee6c82e677f4eedcd3231d9312cd15533a /Cython/Compiler/ParseTreeTransforms.py
parent69e08695ba5f307e3e14c8d6969706148772b9d3 (diff)
downloadcython-a3ffd72f344b543a57dbc213e1952ee20567d54d.tar.gz
Attempt to use a faster exception value for return type annotations that check for exceptions.
Inside of a module, it is safe to convert a function declared cdef int func() except *: ... into cdef int func() except? -1 because a) we need an exception return value anyway and b) there will always be an explicit exception check afterwards. Thus, changing the function implementation itself is safe. We must exclude functions that are only declared but not implemented since we do not control their signature and it is not safe to assume a specific exception return value if it is not declared.
Diffstat (limited to 'Cython/Compiler/ParseTreeTransforms.py')
-rw-r--r--Cython/Compiler/ParseTreeTransforms.py9
1 files changed, 8 insertions, 1 deletions
diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py
index a90603719..61625e842 100644
--- a/Cython/Compiler/ParseTreeTransforms.py
+++ b/Cython/Compiler/ParseTreeTransforms.py
@@ -905,8 +905,9 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
if optname == 'np_pythran' and not self.context.cpp:
raise PostParseError(pos, 'The %s directive can only be used in C++ mode.' % optname)
elif optname == 'exceptval':
+ # default: exceptval(None, check=True)
arg_error = len(args) > 1
- check = False
+ check = True
if kwds and kwds.key_value_pairs:
kw = kwds.key_value_pairs[0]
if (len(kwds.key_value_pairs) == 1 and
@@ -2344,6 +2345,12 @@ class AdjustDefByDirectives(CythonTransform, SkipDeclarations):
return_type_node = self.directives.get('returns')
if return_type_node is None and self.directives['annotation_typing']:
return_type_node = node.return_type_annotation
+ # for Python anntations, prefer safe exception handling by default
+ if return_type_node is not None and except_val is None:
+ except_val = (None, True) # except *
+ elif except_val is None:
+ # backward compatible default: no exception check
+ except_val = (None, False)
if 'ccall' in self.directives:
node = node.as_cfunction(
overridable=True, modifiers=modifiers,