diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2021-10-24 21:18:10 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2021-10-24 21:18:10 +0200 |
commit | 346c81fe9b0a13892a2dbd137d994f198940b435 (patch) | |
tree | 1e6ad304c4238fc435d7ea39f60306fad8d0922a | |
parent | 3748c3cd20be1e0440477b906f5c9d10a0afd254 (diff) | |
download | cython-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.py | 4 | ||||
-rw-r--r-- | tests/run/binop_reverse_methods_GH2056.pyx | 88 |
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. |