1cimport cython 2 3import sys 4IS_PYTHON2 = sys.version_info[0] == 2 5 6__doc__ = "" 7 8 9@cython.c_api_binop_methods(False) 10@cython.cclass 11class Base(object): 12 """ 13 >>> Base() + 2 14 'Base.__add__(Base(), 2)' 15 >>> 2 + Base() 16 'Base.__radd__(Base(), 2)' 17 18 >>> Base(implemented=False) + 2 #doctest: +ELLIPSIS 19 Traceback (most recent call last): 20 ... 21 TypeError: unsupported operand type... 22 >>> 2 + Base(implemented=False) #doctest: +ELLIPSIS 23 Traceback (most recent call last): 24 ... 25 TypeError: unsupported operand type... 26 27 >>> Base() ** 2 28 'Base.__pow__(Base(), 2, None)' 29 >>> 2 ** Base() 30 'Base.__rpow__(Base(), 2, None)' 31 >>> pow(Base(), 2, 100) 32 'Base.__pow__(Base(), 2, 100)' 33 """ 34 implemented: cython.bint 35 36 def __init__(self, *, implemented=True): 37 self.implemented = implemented 38 39 def __add__(self, other): 40 if (<Base>self).implemented: 41 return "Base.__add__(%s, %s)" % (self, other) 42 else: 43 return NotImplemented 44 45 def __radd__(self, other): 46 if (<Base>self).implemented: 47 return "Base.__radd__(%s, %s)" % (self, other) 48 else: 49 return NotImplemented 50 51 def __pow__(self, other, mod): 52 if (<Base>self).implemented: 53 return "Base.__pow__(%s, %s, %s)" % (self, other, mod) 54 else: 55 return NotImplemented 56 57 def __rpow__(self, other, mod): 58 if (<Base>self).implemented: 59 return "Base.__rpow__(%s, %s, %s)" % (self, other, mod) 60 else: 61 return NotImplemented 62 63 def __repr__(self): 64 return "%s()" % (self.__class__.__name__) 65 66 67@cython.c_api_binop_methods(False) 68@cython.cclass 69class OverloadLeft(Base): 70 """ 71 >>> OverloadLeft() + 2 72 'OverloadLeft.__add__(OverloadLeft(), 2)' 73 >>> 2 + OverloadLeft() 74 'Base.__radd__(OverloadLeft(), 2)' 75 76 >>> OverloadLeft() + Base() 77 'OverloadLeft.__add__(OverloadLeft(), Base())' 78 >>> Base() + OverloadLeft() 79 'Base.__add__(Base(), OverloadLeft())' 80 81 >>> OverloadLeft(implemented=False) + Base(implemented=False) #doctest: +ELLIPSIS 82 Traceback (most recent call last): 83 ... 84 TypeError: unsupported operand type... 85 >>> Base(implemented=False) + OverloadLeft(implemented=False) #doctest: +ELLIPSIS 86 Traceback (most recent call last): 87 ... 88 TypeError: unsupported operand type... 89 """ 90 derived_implemented: cython.bint 91 92 def __init__(self, *, implemented=True): 93 super().__init__(implemented=implemented) 94 self.derived_implemented = implemented 95 96 def __add__(self, other): 97 if (<OverloadLeft>self).derived_implemented: 98 return "OverloadLeft.__add__(%s, %s)" % (self, other) 99 else: 100 return NotImplemented 101 102 103@cython.c_api_binop_methods(False) 104@cython.cclass 105class OverloadRight(Base): 106 """ 107 >>> OverloadRight() + 2 108 'Base.__add__(OverloadRight(), 2)' 109 >>> 2 + OverloadRight() 110 'OverloadRight.__radd__(OverloadRight(), 2)' 111 112 >>> OverloadRight() + Base() 113 'Base.__add__(OverloadRight(), Base())' 114 >>> Base() + OverloadRight() 115 'OverloadRight.__radd__(OverloadRight(), Base())' 116 117 >>> OverloadRight(implemented=False) + Base(implemented=False) #doctest: +ELLIPSIS 118 Traceback (most recent call last): 119 ... 120 TypeError: unsupported operand type... 121 >>> Base(implemented=False) + OverloadRight(implemented=False) #doctest: +ELLIPSIS 122 Traceback (most recent call last): 123 ... 124 TypeError: unsupported operand type... 125 """ 126 derived_implemented: cython.bint 127 128 def __init__(self, *, implemented=True): 129 super().__init__(implemented=implemented) 130 self.derived_implemented = implemented 131 132 def __radd__(self, other): 133 if (<OverloadRight>self).derived_implemented: 134 return "OverloadRight.__radd__(%s, %s)" % (self, other) 135 else: 136 return NotImplemented 137 138 139@cython.c_api_binop_methods(True) 140@cython.cclass 141class OverloadCApi(Base): 142 """ 143 >>> OverloadCApi() + 2 144 'OverloadCApi.__add__(OverloadCApi(), 2)' 145 >>> 2 + OverloadCApi() 146 'OverloadCApi.__add__(2, OverloadCApi())' 147 148 >>> OverloadCApi() + Base() 149 'OverloadCApi.__add__(OverloadCApi(), Base())' 150 >>> Base() + OverloadCApi() 151 'OverloadCApi.__add__(Base(), OverloadCApi())' 152 153 >>> OverloadCApi(derived_implemented=False) + 2 #doctest: +ELLIPSIS 154 Traceback (most recent call last): 155 ... 156 TypeError: unsupported operand type... 157 >>> 2 + OverloadCApi(derived_implemented=False) #doctest: +ELLIPSIS 158 Traceback (most recent call last): 159 ... 160 TypeError: unsupported operand type... 161 """ 162 derived_implemented: cython.bint 163 164 def __init__(self, *, derived_implemented=True): 165 super().__init__(implemented=True) 166 self.derived_implemented = derived_implemented 167 168 def __add__(self, other): 169 if isinstance(self, OverloadCApi): 170 derived_implemented = (<OverloadCApi>self).derived_implemented 171 else: 172 derived_implemented = (<OverloadCApi>other).derived_implemented 173 if derived_implemented: 174 return "OverloadCApi.__add__(%s, %s)" % (self, other) 175 else: 176 return NotImplemented 177 178 179if sys.version_info >= (3, 5): 180 __doc__ += """ 181 >>> d = PyVersionDependent() 182 >>> d @ 2 183 9 184 >>> 2 @ d 185 99 186 >>> i = d 187 >>> i @= 2 188 >>> i 189 999 190""" 191 192 193@cython.c_api_binop_methods(False) 194@cython.cclass 195class PyVersionDependent: 196 """ 197 >>> d = PyVersionDependent() 198 >>> d / 2 199 5 200 >>> 2 / d 201 2 202 >>> d // 2 203 55 204 >>> 2 // d 205 22 206 >>> i = d 207 >>> i /= 2 208 >>> i 209 4 210 >>> i = d 211 >>> i //= 2 212 >>> i 213 44 214 """ 215 def __div__(self, other): 216 assert IS_PYTHON2 217 return 5 218 219 def __rdiv__(self, other): 220 assert IS_PYTHON2 221 return 2 222 223 def __idiv__(self, other): 224 assert IS_PYTHON2 225 return 4 226 227 def __truediv__(self, other): 228 assert not IS_PYTHON2 229 return 5 230 231 def __rtruediv__(self, other): 232 assert not IS_PYTHON2 233 return 2 234 235 def __itruediv__(self, other): 236 assert not IS_PYTHON2 237 return 4 238 239 def __floordiv__(self, other): 240 return 55 241 242 def __rfloordiv__(self, other): 243 return 22 244 245 def __ifloordiv__(self, other): 246 return 44 247 248 def __matmul__(self, other): 249 return 9 250 251 def __rmatmul__(self, other): 252 return 99 253 254 def __imatmul__(self, other): 255 return 999 256 257 258# TODO: Test a class that only defines the `__r...__()` methods. 259