summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2021-10-24 21:18:10 +0200
committerStefan Behnel <stefan_ml@behnel.de>2021-10-24 21:18:10 +0200
commit346c81fe9b0a13892a2dbd137d994f198940b435 (patch)
tree1e6ad304c4238fc435d7ea39f60306fad8d0922a
parent3748c3cd20be1e0440477b906f5c9d10a0afd254 (diff)
downloadcython-346c81fe9b0a13892a2dbd137d994f198940b435.tar.gz
Make sure that version dependent special methods are correctly and completely excluded via preprocessor guards.
Previously, implementing "__div__" could fail in Py3 (if the code for adapting the Python wrapper was generated) or would at least generate C compiler warnings about unused "__div__" C functions.
-rw-r--r--Cython/Compiler/TypeSlots.py4
-rw-r--r--tests/run/binop_reverse_methods_GH2056.pyx88
2 files changed, 90 insertions, 2 deletions
diff --git a/Cython/Compiler/TypeSlots.py b/Cython/Compiler/TypeSlots.py
index c260ada1d..d7b68bbd3 100644
--- a/Cython/Compiler/TypeSlots.py
+++ b/Cython/Compiler/TypeSlots.py
@@ -515,8 +515,8 @@ class BinopSlot(SyntheticSlot):
SyntheticSlot.__init__(
self, slot_name, [left_method, right_method], "0", is_binop=True, **kargs)
# MethodSlot causes special method registration.
- self.left_slot = MethodSlot(signature, "", left_method)
- self.right_slot = MethodSlot(signature, "", right_method)
+ self.left_slot = MethodSlot(signature, "", left_method, **kargs)
+ self.right_slot = MethodSlot(signature, "", right_method, **kargs)
class RichcmpSlot(MethodSlot):
diff --git a/tests/run/binop_reverse_methods_GH2056.pyx b/tests/run/binop_reverse_methods_GH2056.pyx
index 15ef5b0e7..bce2f1df1 100644
--- a/tests/run/binop_reverse_methods_GH2056.pyx
+++ b/tests/run/binop_reverse_methods_GH2056.pyx
@@ -1,5 +1,11 @@
cimport cython
+import sys
+IS_PYTHON2 = sys.version_info[0] == 2
+
+__doc__ = ""
+
+
@cython.c_api_binop_methods(False)
@cython.cclass
class Base(object):
@@ -57,6 +63,7 @@ class Base(object):
def __repr__(self):
return "%s()" % (self.__class__.__name__)
+
@cython.c_api_binop_methods(False)
@cython.cclass
class OverloadLeft(Base):
@@ -128,6 +135,7 @@ class OverloadRight(Base):
else:
return NotImplemented
+
@cython.c_api_binop_methods(True)
@cython.cclass
class OverloadCApi(Base):
@@ -167,4 +175,84 @@ class OverloadCApi(Base):
else:
return NotImplemented
+
+if sys.version_info >= (3, 5):
+ __doc__ += """
+ >>> d = PyVersionDependent()
+ >>> d @ 2
+ 9
+ >>> 2 @ d
+ 99
+ >>> i = d
+ >>> i @= 2
+ >>> i
+ 999
+"""
+
+
+@cython.c_api_binop_methods(False)
+@cython.cclass
+class PyVersionDependent:
+ """
+ >>> d = PyVersionDependent()
+ >>> d / 2
+ 5
+ >>> 2 / d
+ 2
+ >>> d // 2
+ 55
+ >>> 2 // d
+ 22
+ >>> i = d
+ >>> i /= 2
+ >>> i
+ 4
+ >>> i = d
+ >>> i //= 2
+ >>> i
+ 44
+ """
+ def __div__(self, other):
+ assert IS_PYTHON2
+ return 5
+
+ def __rdiv__(self, other):
+ assert IS_PYTHON2
+ return 2
+
+ def __idiv__(self, other):
+ assert IS_PYTHON2
+ return 4
+
+ def __truediv__(self, other):
+ assert not IS_PYTHON2
+ return 5
+
+ def __rtruediv__(self, other):
+ assert not IS_PYTHON2
+ return 2
+
+ def __itruediv__(self, other):
+ assert not IS_PYTHON2
+ return 4
+
+ def __floordiv__(self, other):
+ return 55
+
+ def __rfloordiv__(self, other):
+ return 22
+
+ def __ifloordiv__(self, other):
+ return 44
+
+ def __matmul__(self, other):
+ return 9
+
+ def __rmatmul__(self, other):
+ return 99
+
+ def __imatmul__(self, other):
+ return 999
+
+
# TODO: Test a class that only defines the `__r...__()` methods.