1# mode: run 2 3import cython 4compiled = cython.compiled 5 6import sys 7IS_PY2 = sys.version_info[0] == 2 8 9 10@cython.cclass 11class X(object): 12 x = cython.declare(cython.int) 13 14 def __init__(self, x): 15 self.x = x 16 17 def __repr__(self): 18 return "<%d>" % self.x 19 20 21@cython.cfunc 22@cython.locals(x=X) 23def x_of(x): 24 return x.x 25 26 27@cython.cclass 28class ClassEq(X): 29 """ 30 >>> a = ClassEq(1) 31 >>> b = ClassEq(2) 32 >>> c = ClassEq(1) 33 >>> a == a 34 True 35 >>> a != a 36 False 37 38 >>> a == b 39 False 40 >>> a != b 41 True 42 43 >>> a == c 44 True 45 >>> if IS_PY2 and not compiled: a is c 46 ... else: a != c 47 False 48 49 >>> b == c 50 False 51 >>> b != c 52 True 53 54 >>> c == a 55 True 56 >>> if IS_PY2 and not compiled: c is a 57 ... else: c != a 58 False 59 60 >>> b == a 61 False 62 >>> b != a 63 True 64 65 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 66 ... else: a < b 67 Traceback (most recent call last): 68 TypeError... 69 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 70 ... else: a > b 71 Traceback (most recent call last): 72 TypeError... 73 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 74 ... else: a <= b 75 Traceback (most recent call last): 76 TypeError... 77 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 78 ... else: a >= b 79 Traceback (most recent call last): 80 TypeError... 81 82 >>> print(a.__eq__.__doc__) 83 EQ 84 """ 85 def __eq__(self, other): 86 """EQ""" 87 assert 1 <= self.x <= 2 88 assert isinstance(self, ClassEq), type(self) 89 if isinstance(other, X): 90 return self.x == x_of(other) 91 elif isinstance(other, int): 92 return self.x < other 93 return NotImplemented 94 95 96@cython.cclass 97class ClassEqNe(ClassEq): 98 """ 99 >>> a = ClassEqNe(1) 100 >>> b = ClassEqNe(2) 101 >>> c = ClassEqNe(1) 102 >>> a == a 103 True 104 >>> a != a 105 False 106 107 >>> a == b 108 False 109 >>> a != b 110 True 111 112 >>> a == c 113 True 114 >>> a != c 115 False 116 117 >>> b == c 118 False 119 >>> b != c 120 True 121 122 >>> c == a 123 True 124 >>> c != a 125 False 126 127 >>> b == a 128 False 129 >>> b != a 130 True 131 132 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 133 ... else: a < b 134 Traceback (most recent call last): 135 TypeError... 136 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 137 ... else: a > b 138 Traceback (most recent call last): 139 TypeError... 140 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 141 ... else: a <= b 142 Traceback (most recent call last): 143 TypeError... 144 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 145 ... else: a >= b 146 Traceback (most recent call last): 147 TypeError... 148 149 #>>> print(a.__eq__.__doc__) 150 #EQ 151 >>> print(a.__ne__.__doc__) 152 NE 153 """ 154 def __ne__(self, other): 155 """NE""" 156 assert 1 <= self.x <= 2 157 assert isinstance(self, ClassEqNe), type(self) 158 if isinstance(other, X): 159 return self.x != x_of(other) 160 elif isinstance(other, int): 161 return self.x < other 162 return NotImplemented 163 164 165@cython.cclass 166class ClassEqNeGe(ClassEqNe): 167 """ 168 >>> a = ClassEqNeGe(1) 169 >>> b = ClassEqNeGe(2) 170 >>> c = ClassEqNeGe(1) 171 >>> a == a 172 True 173 >>> a != a 174 False 175 >>> a >= a 176 True 177 >>> a <= a 178 True 179 180 >>> a == b 181 False 182 >>> a != b 183 True 184 >>> a >= b 185 False 186 >>> b <= a 187 False 188 189 >>> a == c 190 True 191 >>> a != c 192 False 193 >>> a >= c 194 True 195 >>> c <= a 196 True 197 198 >>> b == c 199 False 200 >>> b != c 201 True 202 >>> b >= c 203 True 204 >>> c <= b 205 True 206 207 >>> c == a 208 True 209 >>> c != a 210 False 211 >>> c >= a 212 True 213 >>> a <= c 214 True 215 216 >>> b == a 217 False 218 >>> b != a 219 True 220 >>> b >= a 221 True 222 >>> a <= b 223 True 224 225 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 226 ... else: a < b 227 Traceback (most recent call last): 228 TypeError... 229 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 230 ... else: a > b 231 Traceback (most recent call last): 232 TypeError... 233 234 >>> 2 <= a 235 False 236 >>> a >= 2 237 False 238 >>> 1 <= a 239 True 240 >>> a >= 1 241 True 242 >>> a >= 2 243 False 244 245 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 246 ... else: 'x' <= a 247 Traceback (most recent call last): 248 TypeError... 249 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 250 ... else: a >= 'x' 251 Traceback (most recent call last): 252 TypeError... 253 254 #>>> print(a.__eq__.__doc__) 255 #EQ 256 #>>> print(a.__ne__.__doc__) 257 #NE 258 >>> print(a.__ge__.__doc__) 259 GE 260 """ 261 def __ge__(self, other): 262 """GE""" 263 assert 1 <= self.x <= 2 264 assert isinstance(self, ClassEqNeGe), type(self) 265 if isinstance(other, X): 266 return self.x >= x_of(other) 267 elif isinstance(other, int): 268 return self.x >= other 269 return NotImplemented 270 271 272@cython.cclass 273class ClassRichcmpOverride(ClassEqNeGe): 274 """ 275 >>> a = ClassRichcmpOverride(1) 276 >>> b = ClassRichcmpOverride(1) 277 278 >>> a == a 279 True 280 >>> a != a 281 False 282 283 >>> a != b if compiled else a == b # Python ignores __richcmp__() 284 True 285 >>> a == b if compiled else a != b # Python ignores __richcmp__() 286 False 287 288 >>> if IS_PY2 or not compiled: raise TypeError # doctest: +ELLIPSIS 289 ... else: a >= b # should no longer work when __richcmp__ is overwritten 290 Traceback (most recent call last): 291 TypeError... 292 """ 293 def __richcmp__(self, other, op): 294 return NotImplemented 295 296 297@cython.cclass 298class ClassLe(X): 299 """ 300 >>> a = ClassLe(1) 301 >>> b = ClassLe(2) 302 >>> c = ClassLe(1) 303 304 >>> a <= b 305 True 306 >>> b >= a 307 True 308 >>> b <= a 309 False 310 >>> a >= b 311 False 312 313 >>> a <= c 314 True 315 >>> c >= a 316 True 317 >>> c <= a 318 True 319 >>> a >= c 320 True 321 322 >>> b <= c 323 False 324 >>> c >= b 325 False 326 >>> c <= b 327 True 328 >>> b >= c 329 True 330 331 >>> 2 >= a 332 True 333 >>> a <= 2 334 True 335 >>> 1 >= a 336 True 337 >>> a <= 1 338 True 339 >>> a <= 0 340 False 341 342 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 343 ... else: 'x' >= a 344 Traceback (most recent call last): 345 TypeError... 346 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 347 ... else: a <= 'x' 348 Traceback (most recent call last): 349 TypeError... 350 """ 351 def __le__(self, other): 352 assert 1 <= self.x <= 2 353 assert isinstance(self, ClassLe), type(self) 354 if isinstance(other, X): 355 return self.x <= x_of(other) 356 elif isinstance(other, int): 357 return self.x <= other 358 return NotImplemented 359 360 361@cython.cclass 362class ClassLt(X): 363 """ 364 >>> a = ClassLt(1) 365 >>> b = ClassLt(2) 366 >>> c = ClassLt(1) 367 368 >>> a < b 369 True 370 >>> b > a 371 True 372 >>> b < a 373 False 374 >>> a > b 375 False 376 377 >>> a < c 378 False 379 >>> c > a 380 False 381 >>> c < a 382 False 383 >>> a > c 384 False 385 386 >>> b < c 387 False 388 >>> c > b 389 False 390 >>> c < b 391 True 392 >>> b > c 393 True 394 395 >>> sorted([a, b, c]) 396 [<1>, <1>, <2>] 397 >>> sorted([b, a, c]) 398 [<1>, <1>, <2>] 399 400 >>> 2 > a 401 True 402 >>> a < 2 403 True 404 >>> 1 > a 405 False 406 >>> a < 1 407 False 408 409 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 410 ... else: 1 < a 411 Traceback (most recent call last): 412 TypeError... 413 414 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 415 ... else: 'x' > a 416 Traceback (most recent call last): 417 TypeError... 418 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 419 ... else: a < 'x' 420 Traceback (most recent call last): 421 TypeError... 422 """ 423 def __lt__(self, other): 424 assert 1 <= self.x <= 2 425 assert isinstance(self, ClassLt), type(self) 426 if isinstance(other, X): 427 return self.x < x_of(other) 428 elif isinstance(other, int): 429 return self.x < other 430 return NotImplemented 431 432 433@cython.cclass 434class ClassLtGtInherited(X): 435 """ 436 >>> a = ClassLtGtInherited(1) 437 >>> b = ClassLtGtInherited(2) 438 >>> c = ClassLtGtInherited(1) 439 440 >>> a < b 441 True 442 >>> b > a 443 True 444 >>> b < a 445 False 446 >>> a > b 447 False 448 449 >>> a < c 450 False 451 >>> c > a 452 False 453 >>> c < a 454 False 455 >>> a > c 456 False 457 458 >>> b < c 459 False 460 >>> c > b 461 False 462 >>> c < b 463 True 464 >>> b > c 465 True 466 467 >>> sorted([a, b, c]) 468 [<1>, <1>, <2>] 469 >>> sorted([b, a, c]) 470 [<1>, <1>, <2>] 471 """ 472 def __gt__(self, other): 473 assert 1 <= self.x <= 2 474 assert isinstance(self, ClassLtGtInherited), type(self) 475 if isinstance(other, X): 476 return self.x > x_of(other) 477 elif isinstance(other, int): 478 return self.x > other 479 return NotImplemented 480 481 482@cython.cclass 483class ClassLtGt(X): 484 """ 485 >>> a = ClassLtGt(1) 486 >>> b = ClassLtGt(2) 487 >>> c = ClassLtGt(1) 488 489 >>> a < b 490 True 491 >>> b > a 492 True 493 >>> b < a 494 False 495 >>> a > b 496 False 497 498 >>> a < c 499 False 500 >>> c > a 501 False 502 >>> c < a 503 False 504 >>> a > c 505 False 506 507 >>> b < c 508 False 509 >>> c > b 510 False 511 >>> c < b 512 True 513 >>> b > c 514 True 515 516 >>> sorted([a, b, c]) 517 [<1>, <1>, <2>] 518 >>> sorted([b, a, c]) 519 [<1>, <1>, <2>] 520 521 >>> 2 > a 522 True 523 >>> 2 < a 524 False 525 >>> a < 2 526 True 527 >>> a > 2 528 False 529 530 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 531 ... else: 'x' > a 532 Traceback (most recent call last): 533 TypeError... 534 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 535 ... else: 'x' < a 536 Traceback (most recent call last): 537 TypeError... 538 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 539 ... else: a < 'x' 540 Traceback (most recent call last): 541 TypeError... 542 >>> if IS_PY2: raise TypeError # doctest: +ELLIPSIS 543 ... else: a > 'x' 544 Traceback (most recent call last): 545 TypeError... 546 """ 547 def __lt__(self, other): 548 assert 1 <= self.x <= 2 549 assert isinstance(self, ClassLtGt), type(self) 550 if isinstance(other, X): 551 return self.x < x_of(other) 552 elif isinstance(other, int): 553 return self.x < other 554 return NotImplemented 555 556 def __gt__(self, other): 557 assert 1 <= self.x <= 2 558 assert isinstance(self, ClassLtGt), type(self) 559 if isinstance(other, X): 560 return self.x > x_of(other) 561 elif isinstance(other, int): 562 return self.x > other 563 return NotImplemented 564 565 566@cython.cclass 567class List(list): 568 """ 569 >>> l = [1, 2, 3, 4] 570 >>> notl = List(l) 571 >>> notl == l 572 False 573 >>> notl != l # implemented by base type 574 False 575 >>> notl == notl 576 True 577 >>> notl != notl # implemented by base type 578 False 579 """ 580 def __eq__(self, other): 581 return self is other or list(self) != list(other) 582