Commit cc0273c1 authored by Stefan Behnel's avatar Stefan Behnel

Allow mismatches of broader exception declarations in .pxd signatures as long...

Allow mismatches of broader exception declarations in .pxd signatures as long the implemented signature is covered.
parent f0d69e38
......@@ -2712,11 +2712,17 @@ class CFuncType(CType):
return 0
if self.nogil != other_type.nogil:
return 0
if not self.exception_check and other_type.exception_check:
# a redundant exception check doesn't make functions incompatible, but a missing one does
return 0
if not self._same_exception_value(other_type.exception_value):
# narrower exception checks are ok, but prevent mismatches
if self.exception_check == '+' and other_type.exception_check != '+':
# must catch C++ exceptions if we raise them
return 0
if not other_type.exception_check or other_type.exception_value is not None:
# if other does not *always* check exceptions, self must comply
if not self._same_exception_value(other_type.exception_value):
return 0
if self.exception_check and self.exception_check != other_type.exception_check:
# a redundant exception check doesn't make functions incompatible, but a missing one does
return 0
self.original_sig = other_type.original_sig or other_type
return 1
......
......@@ -771,6 +771,10 @@ class Scope(object):
else:
warning(pos, "Function signature does not match previous declaration", 1)
entry.type = type
elif not in_pxd and entry.defined_in_pxd and type.compatible_signature_with(entry.type):
# TODO: check that this was done by a signature optimisation and not a user error.
#warning(pos, "Function signature does not match previous declaration", 1)
entry.type = type
else:
error(pos, "Function signature does not match previous declaration")
else:
......
# OK
cdef int wider_exception_check(int x, int y) except? 0
cdef int no_exception_raised(int x, int y) except *
cdef int any_exception_value1(int x, int y) except *
cdef int any_exception_value2(int x, int y) except *
cdef int any_exception_value3(int x, int y) except *
cdef int any_exception_value4(int x, int y) except *
cdef int optimised_exception_value(int x, int y) except? -1
# NOK
cdef int wrong_args(int x, long y)
cdef long wrong_return_type(int x, int y)
cdef int wrong_exception_check(int x, int y) except 0
cdef int foreign_exception_value(int x, int y) except 0
cdef int narrower_exception_check(int x, int y) except 0
cdef int wrong_exception_value(int x, int y) except 0
cdef int wrong_exception_value_check(int x, int y) except 0
cdef int inherit_exception_value(int x, int y) except 0
cdef int wrong_exception_value_optimised_check(int x, int y) except? -2
cdef int wrong_exception_value_optimised(int x, int y) except -2
cdef int inherit_exception_check(int x, int y) except *
cdef int narrower_exception_check_optimised(int x, int y) except -1
# mode: error
# tag: pxd
# OK
cdef int wider_exception_check(int x, int y) except 0:
return 2
cdef int no_exception_raised(int x, int y):
return 2
cdef int any_exception_value1(int x, int y) except *:
return 2
cdef int any_exception_value2(int x, int y) except -1:
return 2
cdef int any_exception_value3(int x, int y) except -2:
return 2
cdef int any_exception_value4(int x, int y) except? -2:
return 2
cdef int optimised_exception_value(int x, int y) except *: # => except? -1
return 2
# NOK
cdef int wrong_args(int x, int y):
return 2
cdef int wrong_return_type(int x, int y):
return 2
cdef int wrong_exception_check(int x, int y) except? 0:
cdef int foreign_exception_value(int x, int y):
return 2
cdef int narrower_exception_check(int x, int y) except? 0:
return 2
cdef int wrong_exception_value(int x, int y) except 1:
......@@ -16,19 +45,24 @@ cdef int wrong_exception_value(int x, int y) except 1:
cdef int wrong_exception_value_check(int x, int y) except? 1:
return 2
cdef int inherit_exception_value(int x, int y):
cdef int wrong_exception_value_optimised_check(int x, int y) except *:
return 2
cdef int wrong_exception_value_optimised(int x, int y) except *:
return 2
cdef int inherit_exception_check(int x, int y):
cdef int narrower_exception_check_optimised(int x, int y) except *:
return 2
_ERRORS = """
4:5: Function signature does not match previous declaration
7:5: Function signature does not match previous declaration
10:5: Function signature does not match previous declaration
13:5: Function signature does not match previous declaration
16:5: Function signature does not match previous declaration
19:5: Function signature does not match previous declaration
22:5: Function signature does not match previous declaration
30:5: Function signature does not match previous declaration
33:5: Function signature does not match previous declaration
36:5: Function signature does not match previous declaration
39:5: Function signature does not match previous declaration
42:5: Function signature does not match previous declaration
45:5: Function signature does not match previous declaration
48:5: Function signature does not match previous declaration
51:5: Function signature does not match previous declaration
54:5: Function signature does not match previous declaration
"""
PYTHON setup.py build_ext --inplace
PYTHON -c "import foo"
PYTHON -c "import a"
######## setup.py ########
from Cython.Build import cythonize
from distutils.core import setup
setup(
ext_modules = cythonize("*.pyx"),
)
######## foo.pxd ########
cdef int bar(int i) except *
######## foo.pyx ########
cdef int bar(int i) except *:
if i == 10:
raise ValueError()
return i + 1
######## a.pyx ########
cimport cython
from foo cimport bar
def test():
assert bar(-2) == -1
try:
bar(10)
except ValueError:
pass
else:
assert False, "exception not raised"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment