(root)/
Python-3.11.7/
Lib/
test/
test_abc.py
       1  # Copyright 2007 Google, Inc. All Rights Reserved.
       2  # Licensed to PSF under a Contributor Agreement.
       3  
       4  # Note: each test is run with Python and C versions of ABCMeta. Except for
       5  # test_ABC_helper(), which assures that abc.ABC is an instance of abc.ABCMeta.
       6  
       7  """Unit tests for abc.py."""
       8  
       9  import unittest
      10  
      11  import abc
      12  import _py_abc
      13  from inspect import isabstract
      14  
      15  def test_factory(abc_ABCMeta, abc_get_cache_token):
      16      class ESC[4;38;5;81mTestLegacyAPI(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      17  
      18          def test_abstractproperty_basics(self):
      19              @abc.abstractproperty
      20              def foo(self): pass
      21              self.assertTrue(foo.__isabstractmethod__)
      22              def bar(self): pass
      23              self.assertFalse(hasattr(bar, "__isabstractmethod__"))
      24  
      25              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
      26                  @abc.abstractproperty
      27                  def foo(self): return 3
      28              self.assertRaises(TypeError, C)
      29              class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
      30                  @property
      31                  def foo(self): return super().foo
      32              self.assertEqual(D().foo, 3)
      33              self.assertFalse(getattr(D.foo, "__isabstractmethod__", False))
      34  
      35          def test_abstractclassmethod_basics(self):
      36              @abc.abstractclassmethod
      37              def foo(cls): pass
      38              self.assertTrue(foo.__isabstractmethod__)
      39              @classmethod
      40              def bar(cls): pass
      41              self.assertFalse(getattr(bar, "__isabstractmethod__", False))
      42  
      43              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
      44                  @abc.abstractclassmethod
      45                  def foo(cls): return cls.__name__
      46              self.assertRaises(TypeError, C)
      47              class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
      48                  @classmethod
      49                  def foo(cls): return super().foo()
      50              self.assertEqual(D.foo(), 'D')
      51              self.assertEqual(D().foo(), 'D')
      52  
      53          def test_abstractstaticmethod_basics(self):
      54              @abc.abstractstaticmethod
      55              def foo(): pass
      56              self.assertTrue(foo.__isabstractmethod__)
      57              @staticmethod
      58              def bar(): pass
      59              self.assertFalse(getattr(bar, "__isabstractmethod__", False))
      60  
      61              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
      62                  @abc.abstractstaticmethod
      63                  def foo(): return 3
      64              self.assertRaises(TypeError, C)
      65              class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
      66                  @staticmethod
      67                  def foo(): return 4
      68              self.assertEqual(D.foo(), 4)
      69              self.assertEqual(D().foo(), 4)
      70  
      71  
      72      class ESC[4;38;5;81mTestABC(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      73  
      74          def test_ABC_helper(self):
      75              # create an ABC using the helper class and perform basic checks
      76              class ESC[4;38;5;81mC(ESC[4;38;5;149mabcESC[4;38;5;149m.ESC[4;38;5;149mABC):
      77                  @classmethod
      78                  @abc.abstractmethod
      79                  def foo(cls): return cls.__name__
      80              self.assertEqual(type(C), abc.ABCMeta)
      81              self.assertRaises(TypeError, C)
      82              class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
      83                  @classmethod
      84                  def foo(cls): return super().foo()
      85              self.assertEqual(D.foo(), 'D')
      86  
      87          def test_abstractmethod_basics(self):
      88              @abc.abstractmethod
      89              def foo(self): pass
      90              self.assertTrue(foo.__isabstractmethod__)
      91              def bar(self): pass
      92              self.assertFalse(hasattr(bar, "__isabstractmethod__"))
      93  
      94          def test_abstractproperty_basics(self):
      95              @property
      96              @abc.abstractmethod
      97              def foo(self): pass
      98              self.assertTrue(foo.__isabstractmethod__)
      99              def bar(self): pass
     100              self.assertFalse(getattr(bar, "__isabstractmethod__", False))
     101  
     102              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     103                  @property
     104                  @abc.abstractmethod
     105                  def foo(self): return 3
     106              self.assertRaises(TypeError, C)
     107              class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
     108                  @C.foo.getter
     109                  def foo(self): return super().foo
     110              self.assertEqual(D().foo, 3)
     111  
     112          def test_abstractclassmethod_basics(self):
     113              @classmethod
     114              @abc.abstractmethod
     115              def foo(cls): pass
     116              self.assertTrue(foo.__isabstractmethod__)
     117              @classmethod
     118              def bar(cls): pass
     119              self.assertFalse(getattr(bar, "__isabstractmethod__", False))
     120  
     121              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     122                  @classmethod
     123                  @abc.abstractmethod
     124                  def foo(cls): return cls.__name__
     125              self.assertRaises(TypeError, C)
     126              class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
     127                  @classmethod
     128                  def foo(cls): return super().foo()
     129              self.assertEqual(D.foo(), 'D')
     130              self.assertEqual(D().foo(), 'D')
     131  
     132          def test_abstractstaticmethod_basics(self):
     133              @staticmethod
     134              @abc.abstractmethod
     135              def foo(): pass
     136              self.assertTrue(foo.__isabstractmethod__)
     137              @staticmethod
     138              def bar(): pass
     139              self.assertFalse(getattr(bar, "__isabstractmethod__", False))
     140  
     141              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     142                  @staticmethod
     143                  @abc.abstractmethod
     144                  def foo(): return 3
     145              self.assertRaises(TypeError, C)
     146              class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
     147                  @staticmethod
     148                  def foo(): return 4
     149              self.assertEqual(D.foo(), 4)
     150              self.assertEqual(D().foo(), 4)
     151  
     152          def test_object_new_with_one_abstractmethod(self):
     153              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     154                  @abc.abstractmethod
     155                  def method_one(self):
     156                      pass
     157              msg = r"class C with abstract method method_one"
     158              self.assertRaisesRegex(TypeError, msg, C)
     159  
     160          def test_object_new_with_many_abstractmethods(self):
     161              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     162                  @abc.abstractmethod
     163                  def method_one(self):
     164                      pass
     165                  @abc.abstractmethod
     166                  def method_two(self):
     167                      pass
     168              msg = r"class C with abstract methods method_one, method_two"
     169              self.assertRaisesRegex(TypeError, msg, C)
     170  
     171          def test_abstractmethod_integration(self):
     172              for abstractthing in [abc.abstractmethod, abc.abstractproperty,
     173                                    abc.abstractclassmethod,
     174                                    abc.abstractstaticmethod]:
     175                  class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     176                      @abstractthing
     177                      def foo(self): pass  # abstract
     178                      def bar(self): pass  # concrete
     179                  self.assertEqual(C.__abstractmethods__, {"foo"})
     180                  self.assertRaises(TypeError, C)  # because foo is abstract
     181                  self.assertTrue(isabstract(C))
     182                  class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
     183                      def bar(self): pass  # concrete override of concrete
     184                  self.assertEqual(D.__abstractmethods__, {"foo"})
     185                  self.assertRaises(TypeError, D)  # because foo is still abstract
     186                  self.assertTrue(isabstract(D))
     187                  class ESC[4;38;5;81mE(ESC[4;38;5;149mD):
     188                      def foo(self): pass
     189                  self.assertEqual(E.__abstractmethods__, set())
     190                  E()  # now foo is concrete, too
     191                  self.assertFalse(isabstract(E))
     192                  class ESC[4;38;5;81mF(ESC[4;38;5;149mE):
     193                      @abstractthing
     194                      def bar(self): pass  # abstract override of concrete
     195                  self.assertEqual(F.__abstractmethods__, {"bar"})
     196                  self.assertRaises(TypeError, F)  # because bar is abstract now
     197                  self.assertTrue(isabstract(F))
     198  
     199          def test_descriptors_with_abstractmethod(self):
     200              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     201                  @property
     202                  @abc.abstractmethod
     203                  def foo(self): return 3
     204                  @foo.setter
     205                  @abc.abstractmethod
     206                  def foo(self, val): pass
     207              self.assertRaises(TypeError, C)
     208              class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
     209                  @C.foo.getter
     210                  def foo(self): return super().foo
     211              self.assertRaises(TypeError, D)
     212              class ESC[4;38;5;81mE(ESC[4;38;5;149mD):
     213                  @D.foo.setter
     214                  def foo(self, val): pass
     215              self.assertEqual(E().foo, 3)
     216              # check that the property's __isabstractmethod__ descriptor does the
     217              # right thing when presented with a value that fails truth testing:
     218              class ESC[4;38;5;81mNotBool(ESC[4;38;5;149mobject):
     219                  def __bool__(self):
     220                      raise ValueError()
     221                  __len__ = __bool__
     222              with self.assertRaises(ValueError):
     223                  class ESC[4;38;5;81mF(ESC[4;38;5;149mC):
     224                      def bar(self):
     225                          pass
     226                      bar.__isabstractmethod__ = NotBool()
     227                      foo = property(bar)
     228  
     229  
     230          def test_customdescriptors_with_abstractmethod(self):
     231              class ESC[4;38;5;81mDescriptor:
     232                  def __init__(self, fget, fset=None):
     233                      self._fget = fget
     234                      self._fset = fset
     235                  def getter(self, callable):
     236                      return Descriptor(callable, self._fget)
     237                  def setter(self, callable):
     238                      return Descriptor(self._fget, callable)
     239                  @property
     240                  def __isabstractmethod__(self):
     241                      return (getattr(self._fget, '__isabstractmethod__', False)
     242                              or getattr(self._fset, '__isabstractmethod__', False))
     243              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     244                  @Descriptor
     245                  @abc.abstractmethod
     246                  def foo(self): return 3
     247                  @foo.setter
     248                  @abc.abstractmethod
     249                  def foo(self, val): pass
     250              self.assertRaises(TypeError, C)
     251              class ESC[4;38;5;81mD(ESC[4;38;5;149mC):
     252                  @C.foo.getter
     253                  def foo(self): return super().foo
     254              self.assertRaises(TypeError, D)
     255              class ESC[4;38;5;81mE(ESC[4;38;5;149mD):
     256                  @D.foo.setter
     257                  def foo(self, val): pass
     258              self.assertFalse(E.foo.__isabstractmethod__)
     259  
     260          def test_metaclass_abc(self):
     261              # Metaclasses can be ABCs, too.
     262              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     263                  @abc.abstractmethod
     264                  def x(self):
     265                      pass
     266              self.assertEqual(A.__abstractmethods__, {"x"})
     267              class ESC[4;38;5;81mmeta(ESC[4;38;5;149mtype, ESC[4;38;5;149mA):
     268                  def x(self):
     269                      return 1
     270              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mmeta):
     271                  pass
     272  
     273          def test_registration_basics(self):
     274              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     275                  pass
     276              class ESC[4;38;5;81mB(ESC[4;38;5;149mobject):
     277                  pass
     278              b = B()
     279              self.assertFalse(issubclass(B, A))
     280              self.assertFalse(issubclass(B, (A,)))
     281              self.assertNotIsInstance(b, A)
     282              self.assertNotIsInstance(b, (A,))
     283              B1 = A.register(B)
     284              self.assertTrue(issubclass(B, A))
     285              self.assertTrue(issubclass(B, (A,)))
     286              self.assertIsInstance(b, A)
     287              self.assertIsInstance(b, (A,))
     288              self.assertIs(B1, B)
     289              class ESC[4;38;5;81mC(ESC[4;38;5;149mB):
     290                  pass
     291              c = C()
     292              self.assertTrue(issubclass(C, A))
     293              self.assertTrue(issubclass(C, (A,)))
     294              self.assertIsInstance(c, A)
     295              self.assertIsInstance(c, (A,))
     296  
     297          def test_register_as_class_deco(self):
     298              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     299                  pass
     300              @A.register
     301              class ESC[4;38;5;81mB(ESC[4;38;5;149mobject):
     302                  pass
     303              b = B()
     304              self.assertTrue(issubclass(B, A))
     305              self.assertTrue(issubclass(B, (A,)))
     306              self.assertIsInstance(b, A)
     307              self.assertIsInstance(b, (A,))
     308              @A.register
     309              class ESC[4;38;5;81mC(ESC[4;38;5;149mB):
     310                  pass
     311              c = C()
     312              self.assertTrue(issubclass(C, A))
     313              self.assertTrue(issubclass(C, (A,)))
     314              self.assertIsInstance(c, A)
     315              self.assertIsInstance(c, (A,))
     316              self.assertIs(C, A.register(C))
     317  
     318          def test_isinstance_invalidation(self):
     319              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     320                  pass
     321              class ESC[4;38;5;81mB:
     322                  pass
     323              b = B()
     324              self.assertFalse(isinstance(b, A))
     325              self.assertFalse(isinstance(b, (A,)))
     326              token_old = abc_get_cache_token()
     327              A.register(B)
     328              token_new = abc_get_cache_token()
     329              self.assertGreater(token_new, token_old)
     330              self.assertTrue(isinstance(b, A))
     331              self.assertTrue(isinstance(b, (A,)))
     332  
     333          def test_registration_builtins(self):
     334              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     335                  pass
     336              A.register(int)
     337              self.assertIsInstance(42, A)
     338              self.assertIsInstance(42, (A,))
     339              self.assertTrue(issubclass(int, A))
     340              self.assertTrue(issubclass(int, (A,)))
     341              class ESC[4;38;5;81mB(ESC[4;38;5;149mA):
     342                  pass
     343              B.register(str)
     344              class ESC[4;38;5;81mC(ESC[4;38;5;149mstr): pass
     345              self.assertIsInstance("", A)
     346              self.assertIsInstance("", (A,))
     347              self.assertTrue(issubclass(str, A))
     348              self.assertTrue(issubclass(str, (A,)))
     349              self.assertTrue(issubclass(C, A))
     350              self.assertTrue(issubclass(C, (A,)))
     351  
     352          def test_registration_edge_cases(self):
     353              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     354                  pass
     355              A.register(A)  # should pass silently
     356              class ESC[4;38;5;81mA1(ESC[4;38;5;149mA):
     357                  pass
     358              self.assertRaises(RuntimeError, A1.register, A)  # cycles not allowed
     359              class ESC[4;38;5;81mB(ESC[4;38;5;149mobject):
     360                  pass
     361              A1.register(B)  # ok
     362              A1.register(B)  # should pass silently
     363              class ESC[4;38;5;81mC(ESC[4;38;5;149mA):
     364                  pass
     365              A.register(C)  # should pass silently
     366              self.assertRaises(RuntimeError, C.register, A)  # cycles not allowed
     367              C.register(B)  # ok
     368  
     369          def test_register_non_class(self):
     370              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     371                  pass
     372              self.assertRaisesRegex(TypeError, "Can only register classes",
     373                                     A.register, 4)
     374  
     375          def test_registration_transitiveness(self):
     376              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     377                  pass
     378              self.assertTrue(issubclass(A, A))
     379              self.assertTrue(issubclass(A, (A,)))
     380              class ESC[4;38;5;81mB(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     381                  pass
     382              self.assertFalse(issubclass(A, B))
     383              self.assertFalse(issubclass(A, (B,)))
     384              self.assertFalse(issubclass(B, A))
     385              self.assertFalse(issubclass(B, (A,)))
     386              class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     387                  pass
     388              A.register(B)
     389              class ESC[4;38;5;81mB1(ESC[4;38;5;149mB):
     390                  pass
     391              self.assertTrue(issubclass(B1, A))
     392              self.assertTrue(issubclass(B1, (A,)))
     393              class ESC[4;38;5;81mC1(ESC[4;38;5;149mC):
     394                  pass
     395              B1.register(C1)
     396              self.assertFalse(issubclass(C, B))
     397              self.assertFalse(issubclass(C, (B,)))
     398              self.assertFalse(issubclass(C, B1))
     399              self.assertFalse(issubclass(C, (B1,)))
     400              self.assertTrue(issubclass(C1, A))
     401              self.assertTrue(issubclass(C1, (A,)))
     402              self.assertTrue(issubclass(C1, B))
     403              self.assertTrue(issubclass(C1, (B,)))
     404              self.assertTrue(issubclass(C1, B1))
     405              self.assertTrue(issubclass(C1, (B1,)))
     406              C1.register(int)
     407              class ESC[4;38;5;81mMyInt(ESC[4;38;5;149mint):
     408                  pass
     409              self.assertTrue(issubclass(MyInt, A))
     410              self.assertTrue(issubclass(MyInt, (A,)))
     411              self.assertIsInstance(42, A)
     412              self.assertIsInstance(42, (A,))
     413  
     414          def test_issubclass_bad_arguments(self):
     415              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     416                  pass
     417  
     418              with self.assertRaises(TypeError):
     419                  issubclass({}, A)  # unhashable
     420  
     421              with self.assertRaises(TypeError):
     422                  issubclass(42, A)  # No __mro__
     423  
     424              # Python version supports any iterable as __mro__.
     425              # But it's implementation detail and don't emulate it in C version.
     426              class ESC[4;38;5;81mC:
     427                  __mro__ = 42  # __mro__ is not tuple
     428  
     429              with self.assertRaises(TypeError):
     430                  issubclass(C(), A)
     431  
     432              # bpo-34441: Check that issubclass() doesn't crash on bogus
     433              # classes.
     434              bogus_subclasses = [
     435                  None,
     436                  lambda x: [],
     437                  lambda: 42,
     438                  lambda: [42],
     439              ]
     440  
     441              for i, func in enumerate(bogus_subclasses):
     442                  class ESC[4;38;5;81mS(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     443                      __subclasses__ = func
     444  
     445                  with self.subTest(i=i):
     446                      with self.assertRaises(TypeError):
     447                          issubclass(int, S)
     448  
     449              # Also check that issubclass() propagates exceptions raised by
     450              # __subclasses__.
     451              class ESC[4;38;5;81mCustomError(ESC[4;38;5;149mException): ...
     452              exc_msg = "exception from __subclasses__"
     453  
     454              def raise_exc():
     455                  raise CustomError(exc_msg)
     456  
     457              class ESC[4;38;5;81mS(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     458                  __subclasses__ = raise_exc
     459  
     460              with self.assertRaisesRegex(CustomError, exc_msg):
     461                  issubclass(int, S)
     462  
     463          def test_subclasshook(self):
     464              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabcESC[4;38;5;149m.ESC[4;38;5;149mABCMeta):
     465                  @classmethod
     466                  def __subclasshook__(cls, C):
     467                      if cls is A:
     468                          return 'foo' in C.__dict__
     469                      return NotImplemented
     470              self.assertFalse(issubclass(A, A))
     471              self.assertFalse(issubclass(A, (A,)))
     472              class ESC[4;38;5;81mB:
     473                  foo = 42
     474              self.assertTrue(issubclass(B, A))
     475              self.assertTrue(issubclass(B, (A,)))
     476              class ESC[4;38;5;81mC:
     477                  spam = 42
     478              self.assertFalse(issubclass(C, A))
     479              self.assertFalse(issubclass(C, (A,)))
     480  
     481          def test_all_new_methods_are_called(self):
     482              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     483                  pass
     484              class ESC[4;38;5;81mB(ESC[4;38;5;149mobject):
     485                  counter = 0
     486                  def __new__(cls):
     487                      B.counter += 1
     488                      return super().__new__(cls)
     489              class ESC[4;38;5;81mC(ESC[4;38;5;149mA, ESC[4;38;5;149mB):
     490                  pass
     491              self.assertEqual(B.counter, 0)
     492              C()
     493              self.assertEqual(B.counter, 1)
     494  
     495          def test_ABC_has___slots__(self):
     496              self.assertTrue(hasattr(abc.ABC, '__slots__'))
     497  
     498          def test_tricky_new_works(self):
     499              def with_metaclass(meta, *bases):
     500                  class ESC[4;38;5;81mmetaclass(ESC[4;38;5;149mtype):
     501                      def __new__(cls, name, this_bases, d):
     502                          return meta(name, bases, d)
     503                  return type.__new__(metaclass, 'temporary_class', (), {})
     504              class ESC[4;38;5;81mA: ...
     505              class ESC[4;38;5;81mB: ...
     506              class ESC[4;38;5;81mC(ESC[4;38;5;149mwith_metaclass(abc_ABCMeta, A, B)):
     507                  pass
     508              self.assertEqual(C.__class__, abc_ABCMeta)
     509  
     510          def test_update_del(self):
     511              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     512                  @abc.abstractmethod
     513                  def foo(self):
     514                      pass
     515  
     516              del A.foo
     517              self.assertEqual(A.__abstractmethods__, {'foo'})
     518              self.assertFalse(hasattr(A, 'foo'))
     519  
     520              abc.update_abstractmethods(A)
     521  
     522              self.assertEqual(A.__abstractmethods__, set())
     523              A()
     524  
     525  
     526          def test_update_new_abstractmethods(self):
     527              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     528                  @abc.abstractmethod
     529                  def bar(self):
     530                      pass
     531  
     532              @abc.abstractmethod
     533              def updated_foo(self):
     534                  pass
     535  
     536              A.foo = updated_foo
     537              abc.update_abstractmethods(A)
     538              self.assertEqual(A.__abstractmethods__, {'foo', 'bar'})
     539              msg = "class A with abstract methods bar, foo"
     540              self.assertRaisesRegex(TypeError, msg, A)
     541  
     542          def test_update_implementation(self):
     543              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     544                  @abc.abstractmethod
     545                  def foo(self):
     546                      pass
     547  
     548              class ESC[4;38;5;81mB(ESC[4;38;5;149mA):
     549                  pass
     550  
     551              msg = "class B with abstract method foo"
     552              self.assertRaisesRegex(TypeError, msg, B)
     553              self.assertEqual(B.__abstractmethods__, {'foo'})
     554  
     555              B.foo = lambda self: None
     556  
     557              abc.update_abstractmethods(B)
     558  
     559              B()
     560              self.assertEqual(B.__abstractmethods__, set())
     561  
     562          def test_update_as_decorator(self):
     563              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     564                  @abc.abstractmethod
     565                  def foo(self):
     566                      pass
     567  
     568              def class_decorator(cls):
     569                  cls.foo = lambda self: None
     570                  return cls
     571  
     572              @abc.update_abstractmethods
     573              @class_decorator
     574              class ESC[4;38;5;81mB(ESC[4;38;5;149mA):
     575                  pass
     576  
     577              B()
     578              self.assertEqual(B.__abstractmethods__, set())
     579  
     580          def test_update_non_abc(self):
     581              class ESC[4;38;5;81mA:
     582                  pass
     583  
     584              @abc.abstractmethod
     585              def updated_foo(self):
     586                  pass
     587  
     588              A.foo = updated_foo
     589              abc.update_abstractmethods(A)
     590              A()
     591              self.assertFalse(hasattr(A, '__abstractmethods__'))
     592  
     593          def test_update_del_implementation(self):
     594              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     595                  @abc.abstractmethod
     596                  def foo(self):
     597                      pass
     598  
     599              class ESC[4;38;5;81mB(ESC[4;38;5;149mA):
     600                  def foo(self):
     601                      pass
     602  
     603              B()
     604  
     605              del B.foo
     606  
     607              abc.update_abstractmethods(B)
     608  
     609              msg = "class B with abstract method foo"
     610              self.assertRaisesRegex(TypeError, msg, B)
     611  
     612          def test_update_layered_implementation(self):
     613              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     614                  @abc.abstractmethod
     615                  def foo(self):
     616                      pass
     617  
     618              class ESC[4;38;5;81mB(ESC[4;38;5;149mA):
     619                  pass
     620  
     621              class ESC[4;38;5;81mC(ESC[4;38;5;149mB):
     622                  def foo(self):
     623                      pass
     624  
     625              C()
     626  
     627              del C.foo
     628  
     629              abc.update_abstractmethods(C)
     630  
     631              msg = "class C with abstract method foo"
     632              self.assertRaisesRegex(TypeError, msg, C)
     633  
     634          def test_update_multi_inheritance(self):
     635              class ESC[4;38;5;81mA(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     636                  @abc.abstractmethod
     637                  def foo(self):
     638                      pass
     639  
     640              class ESC[4;38;5;81mB(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     641                  def foo(self):
     642                      pass
     643  
     644              class ESC[4;38;5;81mC(ESC[4;38;5;149mB, ESC[4;38;5;149mA):
     645                  @abc.abstractmethod
     646                  def foo(self):
     647                      pass
     648  
     649              self.assertEqual(C.__abstractmethods__, {'foo'})
     650  
     651              del C.foo
     652  
     653              abc.update_abstractmethods(C)
     654  
     655              self.assertEqual(C.__abstractmethods__, set())
     656  
     657              C()
     658  
     659  
     660      class ESC[4;38;5;81mTestABCWithInitSubclass(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     661          def test_works_with_init_subclass(self):
     662              class ESC[4;38;5;81mabc_ABC(metaclass=ESC[4;38;5;149mabc_ABCMeta):
     663                  __slots__ = ()
     664              saved_kwargs = {}
     665              class ESC[4;38;5;81mReceivesClassKwargs:
     666                  def __init_subclass__(cls, **kwargs):
     667                      super().__init_subclass__()
     668                      saved_kwargs.update(kwargs)
     669              class ESC[4;38;5;81mReceiver(ESC[4;38;5;149mReceivesClassKwargs, ESC[4;38;5;149mabc_ABC, x=1, y=2, z=3):
     670                  pass
     671              self.assertEqual(saved_kwargs, dict(x=1, y=2, z=3))
     672  
     673          def test_positional_only_and_kwonlyargs_with_init_subclass(self):
     674              saved_kwargs = {}
     675  
     676              class ESC[4;38;5;81mA:
     677                  def __init_subclass__(cls, **kwargs):
     678                      super().__init_subclass__()
     679                      saved_kwargs.update(kwargs)
     680  
     681              class ESC[4;38;5;81mB(ESC[4;38;5;149mA, metaclass=ESC[4;38;5;149mabc_ABCMeta, name="test"):
     682                  pass
     683              self.assertEqual(saved_kwargs, dict(name="test"))
     684  
     685      return TestLegacyAPI, TestABC, TestABCWithInitSubclass
     686  
     687  TestLegacyAPI_Py, TestABC_Py, TestABCWithInitSubclass_Py = test_factory(abc.ABCMeta,
     688                                                                          abc.get_cache_token)
     689  TestLegacyAPI_C, TestABC_C, TestABCWithInitSubclass_C = test_factory(_py_abc.ABCMeta,
     690                                                                       _py_abc.get_cache_token)
     691  
     692  if __name__ == "__main__":
     693      unittest.main()