text: "Test the functionality of Python classes implementing operators."
  
  import unittest
  
  
  testmeths = [
  
  # Binary operations
      "add",
      "radd",
      "sub",
      "rsub",
      "mul",
      "rmul",
      "matmul",
      "rmatmul",
      "truediv",
      "rtruediv",
      "floordiv",
      "rfloordiv",
      "mod",
      "rmod",
      "divmod",
      "rdivmod",
      "pow",
      "rpow",
      "rshift",
      "rrshift",
      "lshift",
      "rlshift",
      "and",
      "rand",
      "or",
      "ror",
      "xor",
      "rxor",
  
  # List/dict operations
      "contains",
      "getitem",
      "setitem",
      "delitem",
  
  # Unary operations
      "neg",
      "pos",
      "abs",
  
  # generic operations
      "init",
      ]
  
  # These need to return something other than None
  #    "hash",
  #    "str",
  #    "repr",
  #    "int",
  #    "float",
  
  # These are separate because they can influence the test of other methods.
  #    "getattr",
  #    "setattr",
  #    "delattr",
  
  callLst = []
  def trackCall(f):
      def track(*args, **kwargs):
          callLst.append((f.__name__, args))
          return f(*args, **kwargs)
      return track
  
  statictests = """
  @trackCall
  def __hash__(self, *args):
      return hash(id(self))
  
  @trackCall
  def __str__(self, *args):
      return "AllTests"
  
  @trackCall
  def __repr__(self, *args):
      return "AllTests"
  
  @trackCall
  def __int__(self, *args):
      return 1
  
  @trackCall
  def __index__(self, *args):
      return 1
  
  @trackCall
  def __float__(self, *args):
      return 1.0
  
  @trackCall
  def __eq__(self, *args):
      return True
  
  @trackCall
  def __ne__(self, *args):
      return False
  
  @trackCall
  def __lt__(self, *args):
      return False
  
  @trackCall
  def __le__(self, *args):
      return True
  
  @trackCall
  def __gt__(self, *args):
      return False
  
  @trackCall
  def __ge__(self, *args):
      return True
  """
  
  # Synthesize all the other AllTests methods from the names in testmeths.
  
  method_template = """\
  @trackCall
  def __%s__(self, *args):
      pass
  """
  
  d = {}
  exec(statictests, globals(), d)
  for method in testmeths:
      exec(method_template % method, globals(), d)
  AllTests = type("AllTests", (object,), d)
  del d, statictests, method, method_template
  
  class ClassTests(unittest.TestCase):
      def setUp(self):
          callLst[:] = []
  
      def assertCallStack(self, expected_calls):
          actualCallList = callLst[:]  # need to copy because the comparison below will add
                                       # additional calls to callLst
          if expected_calls != actualCallList:
              self.fail("Expected call list:\n  %s\ndoes not match actual call list\n  %s" %
                        (expected_calls, actualCallList))
  
      def testInit(self):
          foo = AllTests()
          self.assertCallStack([("__init__", (foo,))])
  
      def testBinaryOps(self):
          testme = AllTests()
          # Binary operations
  
          callLst[:] = []
          testme + 1
          self.assertCallStack([("__add__", (testme, 1))])
  
          callLst[:] = []
          1 + testme
          self.assertCallStack([("__radd__", (testme, 1))])
  
          callLst[:] = []
          testme - 1
          self.assertCallStack([("__sub__", (testme, 1))])
  
          callLst[:] = []
          1 - testme
          self.assertCallStack([("__rsub__", (testme, 1))])
  
          callLst[:] = []
          testme * 1
          self.assertCallStack([("__mul__", (testme, 1))])
  
          callLst[:] = []
          1 * testme
          self.assertCallStack([("__rmul__", (testme, 1))])
  
          callLst[:] = []
          testme @ 1
          self.assertCallStack([("__matmul__", (testme, 1))])
  
          callLst[:] = []
          1 @ testme
          self.assertCallStack([("__rmatmul__", (testme, 1))])
  
          callLst[:] = []
          testme / 1
          self.assertCallStack([("__truediv__", (testme, 1))])
  
  
          callLst[:] = []
          1 / testme
          self.assertCallStack([("__rtruediv__", (testme, 1))])
  
          callLst[:] = []
          testme // 1
          self.assertCallStack([("__floordiv__", (testme, 1))])
  
  
          callLst[:] = []
          1 // testme
          self.assertCallStack([("__rfloordiv__", (testme, 1))])
  
          callLst[:] = []
          testme % 1
          self.assertCallStack([("__mod__", (testme, 1))])
  
          callLst[:] = []
          1 % testme
          self.assertCallStack([("__rmod__", (testme, 1))])
  
  
          callLst[:] = []
          divmod(testme,1)
          self.assertCallStack([("__divmod__", (testme, 1))])
  
          callLst[:] = []
          divmod(1, testme)
          self.assertCallStack([("__rdivmod__", (testme, 1))])
  
          callLst[:] = []
          testme ** 1
          self.assertCallStack([("__pow__", (testme, 1))])
  
          callLst[:] = []
          1 ** testme
          self.assertCallStack([("__rpow__", (testme, 1))])
  
          callLst[:] = []
          testme >> 1
          self.assertCallStack([("__rshift__", (testme, 1))])
  
          callLst[:] = []
          1 >> testme
          self.assertCallStack([("__rrshift__", (testme, 1))])
  
          callLst[:] = []
          testme << 1
          self.assertCallStack([("__lshift__", (testme, 1))])
  
          callLst[:] = []
          1 << testme
          self.assertCallStack([("__rlshift__", (testme, 1))])
  
          callLst[:] = []
          testme & 1
          self.assertCallStack([("__and__", (testme, 1))])
  
          callLst[:] = []
          1 & testme
          self.assertCallStack([("__rand__", (testme, 1))])
  
          callLst[:] = []
          testme | 1
          self.assertCallStack([("__or__", (testme, 1))])
  
          callLst[:] = []
          1 | testme
          self.assertCallStack([("__ror__", (testme, 1))])
  
          callLst[:] = []
          testme ^ 1
          self.assertCallStack([("__xor__", (testme, 1))])
  
          callLst[:] = []
          1 ^ testme
          self.assertCallStack([("__rxor__", (testme, 1))])
  
      def testListAndDictOps(self):
          testme = AllTests()
  
          # List/dict operations
  
          class Empty: pass
  
          try:
              1 in Empty()
              self.fail('failed, should have raised TypeError')
          except TypeError:
              pass
  
          callLst[:] = []
          1 in testme
          self.assertCallStack([('__contains__', (testme, 1))])
  
          callLst[:] = []
          testme[1]
          self.assertCallStack([('__getitem__', (testme, 1))])
  
          callLst[:] = []
          testme[1] = 1
          self.assertCallStack([('__setitem__', (testme, 1, 1))])
  
          callLst[:] = []
          del testme[1]
          self.assertCallStack([('__delitem__', (testme, 1))])
  
          callLst[:] = []
          testme[:42]
          self.assertCallStack([('__getitem__', (testme, slice(None, 42)))])
  
          callLst[:] = []
          testme[:42] = "The Answer"
          self.assertCallStack([('__setitem__', (testme, slice(None, 42),
                                                 "The Answer"))])
  
          callLst[:] = []
          del testme[:42]
          self.assertCallStack([('__delitem__', (testme, slice(None, 42)))])
  
          callLst[:] = []
          testme[2:1024:10]
          self.assertCallStack([('__getitem__', (testme, slice(2, 1024, 10)))])
  
          callLst[:] = []
          testme[2:1024:10] = "A lot"
          self.assertCallStack([('__setitem__', (testme, slice(2, 1024, 10),
                                                                      "A lot"))])
          callLst[:] = []
          del testme[2:1024:10]
          self.assertCallStack([('__delitem__', (testme, slice(2, 1024, 10)))])
  
          callLst[:] = []
          testme[:42, ..., :24:, 24, 100]
          self.assertCallStack([('__getitem__', (testme, (slice(None, 42, None),
                                                          Ellipsis,
                                                          slice(None, 24, None),
                                                          24, 100)))])
          callLst[:] = []
          testme[:42, ..., :24:, 24, 100] = "Strange"
          self.assertCallStack([('__setitem__', (testme, (slice(None, 42, None),
                                                          Ellipsis,
                                                          slice(None, 24, None),
                                                          24, 100), "Strange"))])
          callLst[:] = []
          del testme[:42, ..., :24:, 24, 100]
          self.assertCallStack([('__delitem__', (testme, (slice(None, 42, None),
                                                          Ellipsis,
                                                          slice(None, 24, None),
                                                          24, 100)))])
  
      def testUnaryOps(self):
          testme = AllTests()
  
          callLst[:] = []
          -testme
          self.assertCallStack([('__neg__', (testme,))])
          callLst[:] = []
          +testme
          self.assertCallStack([('__pos__', (testme,))])
          callLst[:] = []
          abs(testme)
          self.assertCallStack([('__abs__', (testme,))])
          callLst[:] = []
          int(testme)
          self.assertCallStack([('__int__', (testme,))])
          callLst[:] = []
          float(testme)
          self.assertCallStack([('__float__', (testme,))])
          callLst[:] = []
          oct(testme)
          self.assertCallStack([('__index__', (testme,))])
          callLst[:] = []
          hex(testme)
          self.assertCallStack([('__index__', (testme,))])
  
  
      def testMisc(self):
          testme = AllTests()
  
          callLst[:] = []
          hash(testme)
          self.assertCallStack([('__hash__', (testme,))])
  
          callLst[:] = []
          repr(testme)
          self.assertCallStack([('__repr__', (testme,))])
  
          callLst[:] = []
          str(testme)
          self.assertCallStack([('__str__', (testme,))])
  
          callLst[:] = []
          testme == 1
          self.assertCallStack([('__eq__', (testme, 1))])
  
          callLst[:] = []
          testme < 1
          self.assertCallStack([('__lt__', (testme, 1))])
  
          callLst[:] = []
          testme > 1
          self.assertCallStack([('__gt__', (testme, 1))])
  
          callLst[:] = []
          testme != 1
          self.assertCallStack([('__ne__', (testme, 1))])
  
          callLst[:] = []
          1 == testme
          self.assertCallStack([('__eq__', (1, testme))])
  
          callLst[:] = []
          1 < testme
          self.assertCallStack([('__gt__', (1, testme))])
  
          callLst[:] = []
          1 > testme
          self.assertCallStack([('__lt__', (1, testme))])
  
          callLst[:] = []
          1 != testme
          self.assertCallStack([('__ne__', (1, testme))])
  
  
      def testGetSetAndDel(self):
          # Interfering tests
          class ExtraTests(AllTests):
              @trackCall
              def __getattr__(self, *args):
                  return "SomeVal"
  
              @trackCall
              def __setattr__(self, *args):
                  pass
  
              @trackCall
              def __delattr__(self, *args):
                  pass
  
          testme = ExtraTests()
  
          callLst[:] = []
          testme.spam
          self.assertCallStack([('__getattr__', (testme, "spam"))])
  
          callLst[:] = []
          testme.eggs = "spam, spam, spam and ham"
          self.assertCallStack([('__setattr__', (testme, "eggs",
                                                 "spam, spam, spam and ham"))])
  
          callLst[:] = []
          del testme.cardinal
          self.assertCallStack([('__delattr__', (testme, "cardinal"))])
  
      def testDel(self):
          x = []
  
          class DelTest:
              def __del__(self):
                  x.append("crab people, crab people")
          testme = DelTest()
          del testme
          import gc
          gc.collect()
          self.assertEqual(["crab people, crab people"], x)
  
      def testBadTypeReturned(self):
          # return values of some method are type-checked
          class BadTypeClass:
              def __int__(self):
                  return None
              __float__ = __int__
              __complex__ = __int__
              __str__ = __int__
              __repr__ = __int__
              __bytes__ = __int__
              __bool__ = __int__
              __index__ = __int__
          def index(x):
              return [][x]
  
          for f in [float, complex, str, repr, bytes, bin, oct, hex, bool, index]:
              self.assertRaises(TypeError, f, BadTypeClass())
  
      def testHashStuff(self):
          # Test correct errors from hash() on objects with comparisons but
          #  no __hash__
  
          class C0:
              pass
  
          hash(C0()) # This should work; the next two should raise TypeError
  
          class C2:
              def __eq__(self, other): return 1
  
          self.assertRaises(TypeError, hash, C2())
  
  
      def testSFBug532646(self):
          # Test for SF bug 532646
  
          class A:
              pass
          A.__call__ = A()
          a = A()
  
          try:
              a() # This should not segfault
          except RecursionError:
              pass
          else:
              self.fail("Failed to raise RecursionError")
  
      def testForExceptionsRaisedInInstanceGetattr2(self):
          # Tests for exceptions raised in instance_getattr2().
  
          def booh(self):
              raise AttributeError("booh")
  
          class A:
              a = property(booh)
          try:
              A().a # Raised AttributeError: A instance has no attribute 'a'
          except AttributeError as x:
              if str(x) != "booh":
                  self.fail("attribute error for A().a got masked: %s" % x)
  
          class E:
              __eq__ = property(booh)
          E() == E() # In debug mode, caused a C-level assert() to fail
  
          class I:
              __init__ = property(booh)
          try:
              # In debug mode, printed XXX undetected error and
              #  raises AttributeError
              I()
          except AttributeError as x:
              pass
          else:
              self.fail("attribute error for I.__init__ got masked")
  
      def assertNotOrderable(self, a, b):
          with self.assertRaises(TypeError):
              a < b
          with self.assertRaises(TypeError):
              a > b
          with self.assertRaises(TypeError):
              a <= b
          with self.assertRaises(TypeError):
              a >= b
  
      def testHashComparisonOfMethods(self):
          # Test comparison and hash of methods
          class A:
              def __init__(self, x):
                  self.x = x
              def f(self):
                  pass
              def g(self):
                  pass
              def __eq__(self, other):
                  return True
              def __hash__(self):
                  raise TypeError
          class B(A):
              pass
  
          a1 = A(1)
          a2 = A(1)
          self.assertTrue(a1.f == a1.f)
          self.assertFalse(a1.f != a1.f)
          self.assertFalse(a1.f == a2.f)
          self.assertTrue(a1.f != a2.f)
          self.assertFalse(a1.f == a1.g)
          self.assertTrue(a1.f != a1.g)
          self.assertNotOrderable(a1.f, a1.f)
          self.assertEqual(hash(a1.f), hash(a1.f))
  
          self.assertFalse(A.f == a1.f)
          self.assertTrue(A.f != a1.f)
          self.assertFalse(A.f == A.g)
          self.assertTrue(A.f != A.g)
          self.assertTrue(B.f == A.f)
          self.assertFalse(B.f != A.f)
          self.assertNotOrderable(A.f, A.f)
          self.assertEqual(hash(B.f), hash(A.f))
  
          # the following triggers a SystemError in 2.4
          a = A(hash(A.f)^(-1))
          hash(a.f)
  
      def testSetattrWrapperNameIntern(self):
          # Issue #25794: __setattr__ should intern the attribute name
          class A:
              pass
  
          def add(self, other):
              return 'summa'
  
          name = str(b'__add__', 'ascii')  # shouldn't be optimized
          self.assertIsNot(name, '__add__')  # not interned
          type.__setattr__(A, name, add)
          self.assertEqual(A() + 1, 'summa')
  
          name2 = str(b'__add__', 'ascii')
          self.assertIsNot(name2, '__add__')
          self.assertIsNot(name2, name)
          type.__delattr__(A, name2)
          with self.assertRaises(TypeError):
              A() + 1
  
      def testSetattrNonStringName(self):
          class A:
              pass
  
          with self.assertRaises(TypeError):
              type.__setattr__(A, b'x', None)
  
      def testConstructorErrorMessages(self):
          # bpo-31506: Improves the error message logic for object_new & object_init
  
          # Class without any method overrides
          class C:
              pass
  
          with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'):
              C(42)
  
          with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'):
              C.__new__(C, 42)
  
          with self.assertRaisesRegex(TypeError, r'C\(\).__init__\(\) takes no arguments'):
              C().__init__(42)
  
          with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'):
              object.__new__(C, 42)
  
          with self.assertRaisesRegex(TypeError, r'C\(\).__init__\(\) takes no arguments'):
              object.__init__(C(), 42)
  
          # Class with both `__init__` & `__new__` method overridden
          class D:
              def __new__(cls, *args, **kwargs):
                  super().__new__(cls, *args, **kwargs)
              def __init__(self, *args, **kwargs):
                  super().__init__(*args, **kwargs)
  
          with self.assertRaisesRegex(TypeError, r'object.__new__\(\) takes no argument'):
              D(42)
  
          with self.assertRaisesRegex(TypeError, r'object.__new__\(\) takes no argument'):
              D.__new__(D, 42)
  
          with self.assertRaisesRegex(TypeError, r'object.__new__\(\) takes no argument'):
              object.__new__(D, 42)
  
          # Class that only overrides __init__
          class E:
              def __init__(self, *args, **kwargs):
                  super().__init__(*args, **kwargs)
  
          with self.assertRaisesRegex(TypeError, r'object.__init__\(\) takes no argument'):
              E().__init__(42)
  
          with self.assertRaisesRegex(TypeError, r'object.__init__\(\) takes no argument'):
              object.__init__(E(), 42)
  
  if __name__ == '__main__':
      unittest.main()
  