python (3.11.7)

(root)/
lib/
python3.11/
test/
test_class.py
       1  "Test the functionality of Python classes implementing operators."
       2  
       3  import unittest
       4  
       5  
       6  testmeths = [
       7  
       8  # Binary operations
       9      "add",
      10      "radd",
      11      "sub",
      12      "rsub",
      13      "mul",
      14      "rmul",
      15      "matmul",
      16      "rmatmul",
      17      "truediv",
      18      "rtruediv",
      19      "floordiv",
      20      "rfloordiv",
      21      "mod",
      22      "rmod",
      23      "divmod",
      24      "rdivmod",
      25      "pow",
      26      "rpow",
      27      "rshift",
      28      "rrshift",
      29      "lshift",
      30      "rlshift",
      31      "and",
      32      "rand",
      33      "or",
      34      "ror",
      35      "xor",
      36      "rxor",
      37  
      38  # List/dict operations
      39      "contains",
      40      "getitem",
      41      "setitem",
      42      "delitem",
      43  
      44  # Unary operations
      45      "neg",
      46      "pos",
      47      "abs",
      48  
      49  # generic operations
      50      "init",
      51      ]
      52  
      53  # These need to return something other than None
      54  #    "hash",
      55  #    "str",
      56  #    "repr",
      57  #    "int",
      58  #    "float",
      59  
      60  # These are separate because they can influence the test of other methods.
      61  #    "getattr",
      62  #    "setattr",
      63  #    "delattr",
      64  
      65  callLst = []
      66  def trackCall(f):
      67      def track(*args, **kwargs):
      68          callLst.append((f.__name__, args))
      69          return f(*args, **kwargs)
      70      return track
      71  
      72  statictests = """
      73  @trackCall
      74  def __hash__(self, *args):
      75      return hash(id(self))
      76  
      77  @trackCall
      78  def __str__(self, *args):
      79      return "AllTests"
      80  
      81  @trackCall
      82  def __repr__(self, *args):
      83      return "AllTests"
      84  
      85  @trackCall
      86  def __int__(self, *args):
      87      return 1
      88  
      89  @trackCall
      90  def __index__(self, *args):
      91      return 1
      92  
      93  @trackCall
      94  def __float__(self, *args):
      95      return 1.0
      96  
      97  @trackCall
      98  def __eq__(self, *args):
      99      return True
     100  
     101  @trackCall
     102  def __ne__(self, *args):
     103      return False
     104  
     105  @trackCall
     106  def __lt__(self, *args):
     107      return False
     108  
     109  @trackCall
     110  def __le__(self, *args):
     111      return True
     112  
     113  @trackCall
     114  def __gt__(self, *args):
     115      return False
     116  
     117  @trackCall
     118  def __ge__(self, *args):
     119      return True
     120  """
     121  
     122  # Synthesize all the other AllTests methods from the names in testmeths.
     123  
     124  method_template = """\
     125  @trackCall
     126  def __%s__(self, *args):
     127      pass
     128  """
     129  
     130  d = {}
     131  exec(statictests, globals(), d)
     132  for method in testmeths:
     133      exec(method_template % method, globals(), d)
     134  AllTests = type("AllTests", (object,), d)
     135  del d, statictests, method, method_template
     136  
     137  class ESC[4;38;5;81mClassTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     138      def setUp(self):
     139          callLst[:] = []
     140  
     141      def assertCallStack(self, expected_calls):
     142          actualCallList = callLst[:]  # need to copy because the comparison below will add
     143                                       # additional calls to callLst
     144          if expected_calls != actualCallList:
     145              self.fail("Expected call list:\n  %s\ndoes not match actual call list\n  %s" %
     146                        (expected_calls, actualCallList))
     147  
     148      def testInit(self):
     149          foo = AllTests()
     150          self.assertCallStack([("__init__", (foo,))])
     151  
     152      def testBinaryOps(self):
     153          testme = AllTests()
     154          # Binary operations
     155  
     156          callLst[:] = []
     157          testme + 1
     158          self.assertCallStack([("__add__", (testme, 1))])
     159  
     160          callLst[:] = []
     161          1 + testme
     162          self.assertCallStack([("__radd__", (testme, 1))])
     163  
     164          callLst[:] = []
     165          testme - 1
     166          self.assertCallStack([("__sub__", (testme, 1))])
     167  
     168          callLst[:] = []
     169          1 - testme
     170          self.assertCallStack([("__rsub__", (testme, 1))])
     171  
     172          callLst[:] = []
     173          testme * 1
     174          self.assertCallStack([("__mul__", (testme, 1))])
     175  
     176          callLst[:] = []
     177          1 * testme
     178          self.assertCallStack([("__rmul__", (testme, 1))])
     179  
     180          callLst[:] = []
     181          testme @ 1
     182          self.assertCallStack([("__matmul__", (testme, 1))])
     183  
     184          callLst[:] = []
     185          1 @ testme
     186          self.assertCallStack([("__rmatmul__", (testme, 1))])
     187  
     188          callLst[:] = []
     189          testme / 1
     190          self.assertCallStack([("__truediv__", (testme, 1))])
     191  
     192  
     193          callLst[:] = []
     194          1 / testme
     195          self.assertCallStack([("__rtruediv__", (testme, 1))])
     196  
     197          callLst[:] = []
     198          testme // 1
     199          self.assertCallStack([("__floordiv__", (testme, 1))])
     200  
     201  
     202          callLst[:] = []
     203          1 // testme
     204          self.assertCallStack([("__rfloordiv__", (testme, 1))])
     205  
     206          callLst[:] = []
     207          testme % 1
     208          self.assertCallStack([("__mod__", (testme, 1))])
     209  
     210          callLst[:] = []
     211          1 % testme
     212          self.assertCallStack([("__rmod__", (testme, 1))])
     213  
     214  
     215          callLst[:] = []
     216          divmod(testme,1)
     217          self.assertCallStack([("__divmod__", (testme, 1))])
     218  
     219          callLst[:] = []
     220          divmod(1, testme)
     221          self.assertCallStack([("__rdivmod__", (testme, 1))])
     222  
     223          callLst[:] = []
     224          testme ** 1
     225          self.assertCallStack([("__pow__", (testme, 1))])
     226  
     227          callLst[:] = []
     228          1 ** testme
     229          self.assertCallStack([("__rpow__", (testme, 1))])
     230  
     231          callLst[:] = []
     232          testme >> 1
     233          self.assertCallStack([("__rshift__", (testme, 1))])
     234  
     235          callLst[:] = []
     236          1 >> testme
     237          self.assertCallStack([("__rrshift__", (testme, 1))])
     238  
     239          callLst[:] = []
     240          testme << 1
     241          self.assertCallStack([("__lshift__", (testme, 1))])
     242  
     243          callLst[:] = []
     244          1 << testme
     245          self.assertCallStack([("__rlshift__", (testme, 1))])
     246  
     247          callLst[:] = []
     248          testme & 1
     249          self.assertCallStack([("__and__", (testme, 1))])
     250  
     251          callLst[:] = []
     252          1 & testme
     253          self.assertCallStack([("__rand__", (testme, 1))])
     254  
     255          callLst[:] = []
     256          testme | 1
     257          self.assertCallStack([("__or__", (testme, 1))])
     258  
     259          callLst[:] = []
     260          1 | testme
     261          self.assertCallStack([("__ror__", (testme, 1))])
     262  
     263          callLst[:] = []
     264          testme ^ 1
     265          self.assertCallStack([("__xor__", (testme, 1))])
     266  
     267          callLst[:] = []
     268          1 ^ testme
     269          self.assertCallStack([("__rxor__", (testme, 1))])
     270  
     271      def testListAndDictOps(self):
     272          testme = AllTests()
     273  
     274          # List/dict operations
     275  
     276          class ESC[4;38;5;81mEmpty: pass
     277  
     278          try:
     279              1 in Empty()
     280              self.fail('failed, should have raised TypeError')
     281          except TypeError:
     282              pass
     283  
     284          callLst[:] = []
     285          1 in testme
     286          self.assertCallStack([('__contains__', (testme, 1))])
     287  
     288          callLst[:] = []
     289          testme[1]
     290          self.assertCallStack([('__getitem__', (testme, 1))])
     291  
     292          callLst[:] = []
     293          testme[1] = 1
     294          self.assertCallStack([('__setitem__', (testme, 1, 1))])
     295  
     296          callLst[:] = []
     297          del testme[1]
     298          self.assertCallStack([('__delitem__', (testme, 1))])
     299  
     300          callLst[:] = []
     301          testme[:42]
     302          self.assertCallStack([('__getitem__', (testme, slice(None, 42)))])
     303  
     304          callLst[:] = []
     305          testme[:42] = "The Answer"
     306          self.assertCallStack([('__setitem__', (testme, slice(None, 42),
     307                                                 "The Answer"))])
     308  
     309          callLst[:] = []
     310          del testme[:42]
     311          self.assertCallStack([('__delitem__', (testme, slice(None, 42)))])
     312  
     313          callLst[:] = []
     314          testme[2:1024:10]
     315          self.assertCallStack([('__getitem__', (testme, slice(2, 1024, 10)))])
     316  
     317          callLst[:] = []
     318          testme[2:1024:10] = "A lot"
     319          self.assertCallStack([('__setitem__', (testme, slice(2, 1024, 10),
     320                                                                      "A lot"))])
     321          callLst[:] = []
     322          del testme[2:1024:10]
     323          self.assertCallStack([('__delitem__', (testme, slice(2, 1024, 10)))])
     324  
     325          callLst[:] = []
     326          testme[:42, ..., :24:, 24, 100]
     327          self.assertCallStack([('__getitem__', (testme, (slice(None, 42, None),
     328                                                          Ellipsis,
     329                                                          slice(None, 24, None),
     330                                                          24, 100)))])
     331          callLst[:] = []
     332          testme[:42, ..., :24:, 24, 100] = "Strange"
     333          self.assertCallStack([('__setitem__', (testme, (slice(None, 42, None),
     334                                                          Ellipsis,
     335                                                          slice(None, 24, None),
     336                                                          24, 100), "Strange"))])
     337          callLst[:] = []
     338          del testme[:42, ..., :24:, 24, 100]
     339          self.assertCallStack([('__delitem__', (testme, (slice(None, 42, None),
     340                                                          Ellipsis,
     341                                                          slice(None, 24, None),
     342                                                          24, 100)))])
     343  
     344      def testUnaryOps(self):
     345          testme = AllTests()
     346  
     347          callLst[:] = []
     348          -testme
     349          self.assertCallStack([('__neg__', (testme,))])
     350          callLst[:] = []
     351          +testme
     352          self.assertCallStack([('__pos__', (testme,))])
     353          callLst[:] = []
     354          abs(testme)
     355          self.assertCallStack([('__abs__', (testme,))])
     356          callLst[:] = []
     357          int(testme)
     358          self.assertCallStack([('__int__', (testme,))])
     359          callLst[:] = []
     360          float(testme)
     361          self.assertCallStack([('__float__', (testme,))])
     362          callLst[:] = []
     363          oct(testme)
     364          self.assertCallStack([('__index__', (testme,))])
     365          callLst[:] = []
     366          hex(testme)
     367          self.assertCallStack([('__index__', (testme,))])
     368  
     369  
     370      def testMisc(self):
     371          testme = AllTests()
     372  
     373          callLst[:] = []
     374          hash(testme)
     375          self.assertCallStack([('__hash__', (testme,))])
     376  
     377          callLst[:] = []
     378          repr(testme)
     379          self.assertCallStack([('__repr__', (testme,))])
     380  
     381          callLst[:] = []
     382          str(testme)
     383          self.assertCallStack([('__str__', (testme,))])
     384  
     385          callLst[:] = []
     386          testme == 1
     387          self.assertCallStack([('__eq__', (testme, 1))])
     388  
     389          callLst[:] = []
     390          testme < 1
     391          self.assertCallStack([('__lt__', (testme, 1))])
     392  
     393          callLst[:] = []
     394          testme > 1
     395          self.assertCallStack([('__gt__', (testme, 1))])
     396  
     397          callLst[:] = []
     398          testme != 1
     399          self.assertCallStack([('__ne__', (testme, 1))])
     400  
     401          callLst[:] = []
     402          1 == testme
     403          self.assertCallStack([('__eq__', (1, testme))])
     404  
     405          callLst[:] = []
     406          1 < testme
     407          self.assertCallStack([('__gt__', (1, testme))])
     408  
     409          callLst[:] = []
     410          1 > testme
     411          self.assertCallStack([('__lt__', (1, testme))])
     412  
     413          callLst[:] = []
     414          1 != testme
     415          self.assertCallStack([('__ne__', (1, testme))])
     416  
     417  
     418      def testGetSetAndDel(self):
     419          # Interfering tests
     420          class ESC[4;38;5;81mExtraTests(ESC[4;38;5;149mAllTests):
     421              @trackCall
     422              def __getattr__(self, *args):
     423                  return "SomeVal"
     424  
     425              @trackCall
     426              def __setattr__(self, *args):
     427                  pass
     428  
     429              @trackCall
     430              def __delattr__(self, *args):
     431                  pass
     432  
     433          testme = ExtraTests()
     434  
     435          callLst[:] = []
     436          testme.spam
     437          self.assertCallStack([('__getattr__', (testme, "spam"))])
     438  
     439          callLst[:] = []
     440          testme.eggs = "spam, spam, spam and ham"
     441          self.assertCallStack([('__setattr__', (testme, "eggs",
     442                                                 "spam, spam, spam and ham"))])
     443  
     444          callLst[:] = []
     445          del testme.cardinal
     446          self.assertCallStack([('__delattr__', (testme, "cardinal"))])
     447  
     448      def testDel(self):
     449          x = []
     450  
     451          class ESC[4;38;5;81mDelTest:
     452              def __del__(self):
     453                  x.append("crab people, crab people")
     454          testme = DelTest()
     455          del testme
     456          import gc
     457          gc.collect()
     458          self.assertEqual(["crab people, crab people"], x)
     459  
     460      def testBadTypeReturned(self):
     461          # return values of some method are type-checked
     462          class ESC[4;38;5;81mBadTypeClass:
     463              def __int__(self):
     464                  return None
     465              __float__ = __int__
     466              __complex__ = __int__
     467              __str__ = __int__
     468              __repr__ = __int__
     469              __bytes__ = __int__
     470              __bool__ = __int__
     471              __index__ = __int__
     472          def index(x):
     473              return [][x]
     474  
     475          for f in [float, complex, str, repr, bytes, bin, oct, hex, bool, index]:
     476              self.assertRaises(TypeError, f, BadTypeClass())
     477  
     478      def testHashStuff(self):
     479          # Test correct errors from hash() on objects with comparisons but
     480          #  no __hash__
     481  
     482          class ESC[4;38;5;81mC0:
     483              pass
     484  
     485          hash(C0()) # This should work; the next two should raise TypeError
     486  
     487          class ESC[4;38;5;81mC2:
     488              def __eq__(self, other): return 1
     489  
     490          self.assertRaises(TypeError, hash, C2())
     491  
     492  
     493      def testSFBug532646(self):
     494          # Test for SF bug 532646
     495  
     496          class ESC[4;38;5;81mA:
     497              pass
     498          A.__call__ = A()
     499          a = A()
     500  
     501          try:
     502              a() # This should not segfault
     503          except RecursionError:
     504              pass
     505          else:
     506              self.fail("Failed to raise RecursionError")
     507  
     508      def testForExceptionsRaisedInInstanceGetattr2(self):
     509          # Tests for exceptions raised in instance_getattr2().
     510  
     511          def booh(self):
     512              raise AttributeError("booh")
     513  
     514          class ESC[4;38;5;81mA:
     515              a = property(booh)
     516          try:
     517              A().a # Raised AttributeError: A instance has no attribute 'a'
     518          except AttributeError as x:
     519              if str(x) != "booh":
     520                  self.fail("attribute error for A().a got masked: %s" % x)
     521  
     522          class ESC[4;38;5;81mE:
     523              __eq__ = property(booh)
     524          E() == E() # In debug mode, caused a C-level assert() to fail
     525  
     526          class ESC[4;38;5;81mI:
     527              __init__ = property(booh)
     528          try:
     529              # In debug mode, printed XXX undetected error and
     530              #  raises AttributeError
     531              I()
     532          except AttributeError:
     533              pass
     534          else:
     535              self.fail("attribute error for I.__init__ got masked")
     536  
     537      def assertNotOrderable(self, a, b):
     538          with self.assertRaises(TypeError):
     539              a < b
     540          with self.assertRaises(TypeError):
     541              a > b
     542          with self.assertRaises(TypeError):
     543              a <= b
     544          with self.assertRaises(TypeError):
     545              a >= b
     546  
     547      def testHashComparisonOfMethods(self):
     548          # Test comparison and hash of methods
     549          class ESC[4;38;5;81mA:
     550              def __init__(self, x):
     551                  self.x = x
     552              def f(self):
     553                  pass
     554              def g(self):
     555                  pass
     556              def __eq__(self, other):
     557                  return True
     558              def __hash__(self):
     559                  raise TypeError
     560          class ESC[4;38;5;81mB(ESC[4;38;5;149mA):
     561              pass
     562  
     563          a1 = A(1)
     564          a2 = A(1)
     565          self.assertTrue(a1.f == a1.f)
     566          self.assertFalse(a1.f != a1.f)
     567          self.assertFalse(a1.f == a2.f)
     568          self.assertTrue(a1.f != a2.f)
     569          self.assertFalse(a1.f == a1.g)
     570          self.assertTrue(a1.f != a1.g)
     571          self.assertNotOrderable(a1.f, a1.f)
     572          self.assertEqual(hash(a1.f), hash(a1.f))
     573  
     574          self.assertFalse(A.f == a1.f)
     575          self.assertTrue(A.f != a1.f)
     576          self.assertFalse(A.f == A.g)
     577          self.assertTrue(A.f != A.g)
     578          self.assertTrue(B.f == A.f)
     579          self.assertFalse(B.f != A.f)
     580          self.assertNotOrderable(A.f, A.f)
     581          self.assertEqual(hash(B.f), hash(A.f))
     582  
     583          # the following triggers a SystemError in 2.4
     584          a = A(hash(A.f)^(-1))
     585          hash(a.f)
     586  
     587      def testSetattrWrapperNameIntern(self):
     588          # Issue #25794: __setattr__ should intern the attribute name
     589          class ESC[4;38;5;81mA:
     590              pass
     591  
     592          def add(self, other):
     593              return 'summa'
     594  
     595          name = str(b'__add__', 'ascii')  # shouldn't be optimized
     596          self.assertIsNot(name, '__add__')  # not interned
     597          type.__setattr__(A, name, add)
     598          self.assertEqual(A() + 1, 'summa')
     599  
     600          name2 = str(b'__add__', 'ascii')
     601          self.assertIsNot(name2, '__add__')
     602          self.assertIsNot(name2, name)
     603          type.__delattr__(A, name2)
     604          with self.assertRaises(TypeError):
     605              A() + 1
     606  
     607      def testSetattrNonStringName(self):
     608          class ESC[4;38;5;81mA:
     609              pass
     610  
     611          with self.assertRaises(TypeError):
     612              type.__setattr__(A, b'x', None)
     613  
     614      def testTypeAttributeAccessErrorMessages(self):
     615          class ESC[4;38;5;81mA:
     616              pass
     617  
     618          error_msg = "type object 'A' has no attribute 'x'"
     619          with self.assertRaisesRegex(AttributeError, error_msg):
     620              A.x
     621          with self.assertRaisesRegex(AttributeError, error_msg):
     622              del A.x
     623  
     624      def testObjectAttributeAccessErrorMessages(self):
     625          class ESC[4;38;5;81mA:
     626              pass
     627          class ESC[4;38;5;81mB:
     628              y = 0
     629              __slots__ = ('z',)
     630  
     631          error_msg = "'A' object has no attribute 'x'"
     632          with self.assertRaisesRegex(AttributeError, error_msg):
     633              A().x
     634          with self.assertRaisesRegex(AttributeError, error_msg):
     635              del A().x
     636  
     637          error_msg = "'B' object has no attribute 'x'"
     638          with self.assertRaisesRegex(AttributeError, error_msg):
     639              B().x
     640          with self.assertRaisesRegex(AttributeError, error_msg):
     641              del B().x
     642          with self.assertRaisesRegex(AttributeError, error_msg):
     643              B().x = 0
     644  
     645          error_msg = "'B' object attribute 'y' is read-only"
     646          with self.assertRaisesRegex(AttributeError, error_msg):
     647              del B().y
     648          with self.assertRaisesRegex(AttributeError, error_msg):
     649              B().y = 0
     650  
     651          error_msg = 'z'
     652          with self.assertRaisesRegex(AttributeError, error_msg):
     653              B().z
     654          with self.assertRaisesRegex(AttributeError, error_msg):
     655              del B().z
     656  
     657      def testConstructorErrorMessages(self):
     658          # bpo-31506: Improves the error message logic for object_new & object_init
     659  
     660          # Class without any method overrides
     661          class ESC[4;38;5;81mC:
     662              pass
     663  
     664          error_msg = r'C.__init__\(\) takes exactly one argument \(the instance to initialize\)'
     665  
     666          with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'):
     667              C(42)
     668  
     669          with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'):
     670              C.__new__(C, 42)
     671  
     672          with self.assertRaisesRegex(TypeError, error_msg):
     673              C().__init__(42)
     674  
     675          with self.assertRaisesRegex(TypeError, r'C\(\) takes no arguments'):
     676              object.__new__(C, 42)
     677  
     678          with self.assertRaisesRegex(TypeError, error_msg):
     679              object.__init__(C(), 42)
     680  
     681          # Class with both `__init__` & `__new__` method overridden
     682          class ESC[4;38;5;81mD:
     683              def __new__(cls, *args, **kwargs):
     684                  super().__new__(cls, *args, **kwargs)
     685              def __init__(self, *args, **kwargs):
     686                  super().__init__(*args, **kwargs)
     687  
     688          error_msg =  r'object.__new__\(\) takes exactly one argument \(the type to instantiate\)'
     689  
     690          with self.assertRaisesRegex(TypeError, error_msg):
     691              D(42)
     692  
     693          with self.assertRaisesRegex(TypeError, error_msg):
     694              D.__new__(D, 42)
     695  
     696          with self.assertRaisesRegex(TypeError, error_msg):
     697              object.__new__(D, 42)
     698  
     699          # Class that only overrides __init__
     700          class ESC[4;38;5;81mE:
     701              def __init__(self, *args, **kwargs):
     702                  super().__init__(*args, **kwargs)
     703  
     704          error_msg = r'object.__init__\(\) takes exactly one argument \(the instance to initialize\)'
     705  
     706          with self.assertRaisesRegex(TypeError, error_msg):
     707              E().__init__(42)
     708  
     709          with self.assertRaisesRegex(TypeError, error_msg):
     710              object.__init__(E(), 42)
     711  
     712      def testClassWithExtCall(self):
     713          class ESC[4;38;5;81mMeta(ESC[4;38;5;149mint):
     714              def __init__(*args, **kwargs):
     715                  pass
     716  
     717              def __new__(cls, name, bases, attrs, **kwargs):
     718                  return bases, kwargs
     719  
     720          d = {'metaclass': Meta}
     721  
     722          class ESC[4;38;5;81mA(**ESC[4;38;5;149md): pass
     723          self.assertEqual(A, ((), {}))
     724          class ESC[4;38;5;81mA(0, 1, 2, 3, 4, 5, 6, 7, **ESC[4;38;5;149md): pass
     725          self.assertEqual(A, (tuple(range(8)), {}))
     726          class ESC[4;38;5;81mA(0, *ESC[4;38;5;149mrange(1, 8), **ESC[4;38;5;149md, foo='bar'): pass
     727          self.assertEqual(A, (tuple(range(8)), {'foo': 'bar'}))
     728  
     729  
     730  if __name__ == '__main__':
     731      unittest.main()