@@ -488,6 +488,155 @@ class C(with_metaclass(abc_ABCMeta, A, B)):
488
488
pass
489
489
self .assertEqual (C .__class__ , abc_ABCMeta )
490
490
491
+ def test_update_del (self ):
492
+ class A (metaclass = abc_ABCMeta ):
493
+ @abc .abstractmethod
494
+ def foo (self ):
495
+ pass
496
+
497
+ del A .foo
498
+ self .assertEqual (A .__abstractmethods__ , {'foo' })
499
+ self .assertFalse (hasattr (A , 'foo' ))
500
+
501
+ abc .update_abstractmethods (A )
502
+
503
+ self .assertEqual (A .__abstractmethods__ , set ())
504
+ A ()
505
+
506
+
507
+ def test_update_new_abstractmethods (self ):
508
+ class A (metaclass = abc_ABCMeta ):
509
+ @abc .abstractmethod
510
+ def bar (self ):
511
+ pass
512
+
513
+ @abc .abstractmethod
514
+ def updated_foo (self ):
515
+ pass
516
+
517
+ A .foo = updated_foo
518
+ abc .update_abstractmethods (A )
519
+ self .assertEqual (A .__abstractmethods__ , {'foo' , 'bar' })
520
+ msg = "class A with abstract methods bar, foo"
521
+ self .assertRaisesRegex (TypeError , msg , A )
522
+
523
+ def test_update_implementation (self ):
524
+ class A (metaclass = abc_ABCMeta ):
525
+ @abc .abstractmethod
526
+ def foo (self ):
527
+ pass
528
+
529
+ class B (A ):
530
+ pass
531
+
532
+ msg = "class B with abstract method foo"
533
+ self .assertRaisesRegex (TypeError , msg , B )
534
+ self .assertEqual (B .__abstractmethods__ , {'foo' })
535
+
536
+ B .foo = lambda self : None
537
+
538
+ abc .update_abstractmethods (B )
539
+
540
+ B ()
541
+ self .assertEqual (B .__abstractmethods__ , set ())
542
+
543
+ def test_update_as_decorator (self ):
544
+ class A (metaclass = abc_ABCMeta ):
545
+ @abc .abstractmethod
546
+ def foo (self ):
547
+ pass
548
+
549
+ def class_decorator (cls ):
550
+ cls .foo = lambda self : None
551
+ return cls
552
+
553
+ @abc .update_abstractmethods
554
+ @class_decorator
555
+ class B (A ):
556
+ pass
557
+
558
+ B ()
559
+ self .assertEqual (B .__abstractmethods__ , set ())
560
+
561
+ def test_update_non_abc (self ):
562
+ class A :
563
+ pass
564
+
565
+ @abc .abstractmethod
566
+ def updated_foo (self ):
567
+ pass
568
+
569
+ A .foo = updated_foo
570
+ abc .update_abstractmethods (A )
571
+ A ()
572
+ self .assertFalse (hasattr (A , '__abstractmethods__' ))
573
+
574
+ def test_update_del_implementation (self ):
575
+ class A (metaclass = abc_ABCMeta ):
576
+ @abc .abstractmethod
577
+ def foo (self ):
578
+ pass
579
+
580
+ class B (A ):
581
+ def foo (self ):
582
+ pass
583
+
584
+ B ()
585
+
586
+ del B .foo
587
+
588
+ abc .update_abstractmethods (B )
589
+
590
+ msg = "class B with abstract method foo"
591
+ self .assertRaisesRegex (TypeError , msg , B )
592
+
593
+ def test_update_layered_implementation (self ):
594
+ class A (metaclass = abc_ABCMeta ):
595
+ @abc .abstractmethod
596
+ def foo (self ):
597
+ pass
598
+
599
+ class B (A ):
600
+ pass
601
+
602
+ class C (B ):
603
+ def foo (self ):
604
+ pass
605
+
606
+ C ()
607
+
608
+ del C .foo
609
+
610
+ abc .update_abstractmethods (C )
611
+
612
+ msg = "class C with abstract method foo"
613
+ self .assertRaisesRegex (TypeError , msg , C )
614
+
615
+ def test_update_multi_inheritance (self ):
616
+ class A (metaclass = abc_ABCMeta ):
617
+ @abc .abstractmethod
618
+ def foo (self ):
619
+ pass
620
+
621
+ class B (metaclass = abc_ABCMeta ):
622
+ def foo (self ):
623
+ pass
624
+
625
+ class C (B , A ):
626
+ @abc .abstractmethod
627
+ def foo (self ):
628
+ pass
629
+
630
+ self .assertEqual (C .__abstractmethods__ , {'foo' })
631
+
632
+ del C .foo
633
+
634
+ abc .update_abstractmethods (C )
635
+
636
+ self .assertEqual (C .__abstractmethods__ , set ())
637
+
638
+ C ()
639
+
491
640
492
641
class TestABCWithInitSubclass (unittest .TestCase ):
493
642
def test_works_with_init_subclass (self ):
0 commit comments