summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2023-04-24 12:55:30 +0200
committerStefan Behnel <stefan_ml@behnel.de>2023-04-24 18:57:21 +0200
commit8e0d4df40d1bca3d44eb185f74d6f4d23be4b213 (patch)
tree28a762e3024796a70ae7e37594effcccf6042710
parentd88426829e413ea02780c6502c686de099eb368b (diff)
downloadcython-8e0d4df40d1bca3d44eb185f74d6f4d23be4b213.tar.gz
Warn about useless directives that do not change the previous setting.
Also, make sure that we correctly allow resetting directives, even if the new value is the same as the value from outside (since we might already have set it differently in the same directives block).
-rw-r--r--Cython/Compiler/ParseTreeTransforms.py3
-rw-r--r--tests/errors/pure_errors.py1
-rw-r--r--tests/run/pure_py.py61
3 files changed, 65 insertions, 0 deletions
diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py
index 987142f37..8008cba9a 100644
--- a/Cython/Compiler/ParseTreeTransforms.py
+++ b/Cython/Compiler/ParseTreeTransforms.py
@@ -1329,6 +1329,9 @@ class InterpretCompilerDirectives(CythonTransform):
error(dec.pos, "Cannot apply @cfunc to @ufunc, please reverse the decorators.")
directives.append(directive)
current_opt_dict[name] = value
+ else:
+ warning(dec.pos, "Directive does not change previous value (%s%s)" % (
+ name, '=%r' % value if value is not None else ''))
if directive[0] == 'staticmethod':
both.append(dec)
# Adapt scope type based on decorators that change it.
diff --git a/tests/errors/pure_errors.py b/tests/errors/pure_errors.py
index 75682a5a1..e348abbae 100644
--- a/tests/errors/pure_errors.py
+++ b/tests/errors/pure_errors.py
@@ -85,6 +85,7 @@ _ERRORS = """
"""
_WARNINGS = """
+30:0: Directive does not change previous value (nogil=False)
# bugs:
59:0: 'test_contradicting_decorators1' redeclared
65:0: 'test_contradicting_decorators2' redeclared
diff --git a/tests/run/pure_py.py b/tests/run/pure_py.py
index ae1f820d3..de53e2351 100644
--- a/tests/run/pure_py.py
+++ b/tests/run/pure_py.py
@@ -1,3 +1,6 @@
+# mode: run
+# tag: warnings
+
import sys
IS_PY2 = sys.version_info[0] < 3
@@ -602,3 +605,61 @@ def array_init_with_list():
x[12] = 42
return [x[10], x[12]]
+
+
+with cython.cdivision(True):
+
+ @cython.cdivision(False)
+ @cython.cdivision(True)
+ def test_override_reset(x: cython.int):
+ """
+ >>> test_override_reset(-3) if is_compiled else -2 # @cdivision(False)
+ -2
+ """
+ return x / 2
+
+ @cython.cdivision(True)
+ @cython.cdivision(False)
+ def test_override_set(x: cython.int):
+ """
+ >>> test_override_set(-5) if is_compiled else -1 # @cdivision(True)
+ -1
+ """
+ return x / 3
+
+ @cython.cdivision(True)
+ @cython.cdivision(False)
+ @cython.cdivision(True)
+ @cython.cdivision(False)
+ @cython.cdivision(False)
+ @cython.cdivision(False)
+ @cython.cdivision(True)
+ @cython.cdivision(False)
+ @cython.cdivision(True)
+ @cython.cdivision(True)
+ @cython.cdivision(True)
+ @cython.cdivision(False)
+ def test_override_set_repeated(x: cython.int):
+ """
+ >>> test_override_set_repeated(-5) if is_compiled else -1 # @cdivision(True)
+ -1
+ """
+ return x / 3
+
+
+_WARNINGS = """
+305:0: Directive does not change previous value (nogil=False)
+436:0: Unraisable exception in function 'pure_py.ccall_except_no_check'.
+613:4: Directive does not change previous value (cdivision=True)
+633:4: Directive does not change previous value (cdivision=False)
+634:4: Directive does not change previous value (cdivision=False)
+638:4: Directive does not change previous value (cdivision=True)
+639:4: Directive does not change previous value (cdivision=True)
+
+# BUGS:
+227:0: 'c_call' redeclared
+361:0: 'ccall_except' redeclared
+399:0: 'ccall_except_check' redeclared
+418:0: 'ccall_except_check_always' redeclared
+436:0: 'ccall_except_no_check' redeclared
+"""