Completed
Push — master ( d9aa1f...49a9b0 )
by Max
03:37
created

test_customdescriptors_with_abstractmethod_namespaced()   A

Complexity

Conditions 4

Size

Total Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 54
rs 9.0306
cc 4

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
from abc import abstractmethod
2
import abc as abc_main
3
from inspect import isabstract
4
import sys
5
6
import pytest
7
8
9
def test_import_compat(compat):
10
    """Test the module is importable. See conftest.py for the actual import."""
11
    assert compat
12
13
14
def test_import_abc(abc):
15
    """Test the module is importable. See conftest.py for the actual import."""
16
    assert abc
17
18
19
def test_has_class(abc):
20
    """Test the convenience class exists."""
21
    assert abc.NamespaceableABC
22
23
24
def test_ABC_helper(abc):
25
    """Test the convenience class works as expected."""
26
    # create an ABC using the helper class and perform basic checks
27
    class C(abc.NamespaceableABC):
28
        """A throwaway test class."""
29
        @classmethod
30
        @abstractmethod
31
        def footer(cls):
32
            return cls.__name__
33
    assert isinstance(C, abc.NamespaceableABCMeta)
34
    with pytest.raises(TypeError):
35
        print(C())
36
37
    class D(C):
38
        """A throwaway test class."""
39
        @classmethod
40
        def footer(cls):
41
            return super().footer()
42
    assert D.footer() == 'D'
43
44
45
def test_abstractmethod_basics(abc):
46
    """Test abstractmethod works as expected.
47
48
    Adapted from Python's test suite.
49
    """
50
    @abstractmethod
51
    def footer(self):
52
        """Return nothing. Abstract."""
53
    assert footer.__isabstractmethod__
54
55
    def barter(self):
56
        """Return nothing. Concrete."""
57
    assert not hasattr(barter, "__isabstractmethod__")
58
59
60
def test_abstractproperty_basics(abc):
61
    """Test abstract property works as expected.
62
63
    Adapted from Python's test suite.
64
    """
65
    @property
66
    @abstractmethod
67
    def footer(self):
68
        """Return nothing. Abstract."""
69
    assert footer.__isabstractmethod__
70
71
    def barter(self):
72
        """Return nothing. Concrete."""
73
    assert not getattr(barter, "__isabstractmethod__", False)
74
75
    class C(metaclass=abc.NamespaceableABCMeta):
76
        """A throwaway test class."""
77
        @property
78
        @abstractmethod
79
        def footer(self):
80
            """Return 3. Abstract."""
81
            return 3
82
    with pytest.raises(TypeError):
83
        print(C())
84
85
    class D(C):
86
        """A throwaway test class."""
87
        @C.footer.getter
88
        def footer(self):
89
            """Return 3. Concrete."""
90
            return super().footer
91
    assert D().footer == 3
92
93
94
def test_abstractproperty_namespaced(abc, namespace):
95
    """Test interaction between namespaces and abstract properties."""
96
    class C(metaclass=abc.NamespaceableABCMeta):
97
        """A throwaway test class."""
98
        with namespace() as ns:
99
            @property
100
            @abstractmethod
101
            def footer(self):
102
                """Return 3. Abstract."""
103
                return 3
104
    with pytest.raises(TypeError):
105
        print(C())
106
107
    class D(C):
108
        """A throwaway test class."""
109
        with namespace() as ns:
110
            @C.ns.footer.getter
111
            def footer(self):
112
                """Return 3. Concrete."""
113
                return super().ns.footer
114
    assert D().ns.footer == 3
115
116
117 View Code Duplication
def test_abstractclassmethod_basics(abc):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
118
    """Test abstract classmethod works as expected.
119
120
    Adapted from Python's test suite.
121
    """
122
    @classmethod
123
    @abstractmethod
124
    def footer(cls):
125
        pass
126
    assert footer.__isabstractmethod__
127
128
    @classmethod
129
    def barter(cls):
130
        pass
131
    assert not getattr(barter, "__isabstractmethod__", False)
132
133
    class C(metaclass=abc.NamespaceableABCMeta):
134
        """A throwaway test class."""
135
        @classmethod
136
        @abstractmethod
137
        def footer(cls):
138
            return cls.__name__
139
    with pytest.raises(TypeError):
140
        print(C())
141
142
    class D(C):
143
        """A throwaway test class."""
144
        @classmethod
145
        def footer(cls):
146
            return super().footer()
147
    assert D.footer() == 'D'
148
    assert D().footer() == 'D'
149
150
151 View Code Duplication
def test_abstractclassmethod_namespaced(abc, namespace):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
152
    """Test interaction between namespaces and abstract classmethods."""
153
    class C(metaclass=abc.NamespaceableABCMeta):
154
        """A throwaway test class."""
155
        with namespace() as ns:
156
            @classmethod
157
            @abstractmethod
158
            def footer(cls):
159
                return cls.__name__
160
    with pytest.raises(TypeError):
161
        print(C())
162
163
    class D(C):
164
        """A throwaway test class."""
165
        with namespace() as ns:
166
            @classmethod
167
            def footer(cls):
168
                return super().ns.footer()
169
    assert D.ns.footer() == 'D'
170
    assert D().ns.footer() == 'D'
171
172
173 View Code Duplication
def test_abstractstaticmethod_basics(abc):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
174
    """Test abstract staticmethod works as expected.
175
176
    Adapted from Python's test suite.
177
    """
178
    @staticmethod
179
    @abstractmethod
180
    def footer():
181
        pass
182
    assert footer.__isabstractmethod__
183
184
    @staticmethod
185
    def barter():
186
        pass
187
    assert not (getattr(barter, "__isabstractmethod__", False))
188
189
    class C(metaclass=abc.NamespaceableABCMeta):
190
        """A throwaway test class."""
191
        @staticmethod
192
        @abstractmethod
193
        def footer():
194
            return 3
195
    with pytest.raises(TypeError):
196
        print(C())
197
198
    class D(C):
199
        """A throwaway test class."""
200
        @staticmethod
201
        def footer():
202
            return 4
203
    assert D.footer() == 4
204
    assert D().footer() == 4
205
206
207 View Code Duplication
def test_abstractstaticmethod_namespaced(abc, namespace):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
208
    """Test interaction between namespaces and abstract staticmethods."""
209
    class C(metaclass=abc.NamespaceableABCMeta):
210
        """A throwaway test class."""
211
        with namespace() as ns:
212
            @staticmethod
213
            @abstractmethod
214
            def footer():
215
                return 3
216
    with pytest.raises(TypeError):
217
        print(C())
218
219
    class D(C):
220
        """A throwaway test class."""
221
        with namespace() as ns:
222
            @staticmethod
223
            def footer():
224
                return 4
225
    assert D.ns.footer() == 4
226
    assert D().ns.footer() == 4
227
228
229
def test_abstractmethod_integration(abc):
230
    """Test abstract shortcut decorators work as expected.
231
232
    Adapted from Python's test suite.
233
    """
234
    for abstractthing in [abstractmethod, abc_main.abstractproperty,
235
                          abc_main.abstractclassmethod,
236
                          abc_main.abstractstaticmethod]:
237
        class C(metaclass=abc.NamespaceableABCMeta):
238
            """A throwaway test class."""
239
            @abstractthing
240
            def footer(self):
241
                pass  # abstract
242
243
            def barter(self):
244
                pass  # concrete
245
        assert C.__abstractmethods__ == {"footer"}
246
        with pytest.raises(TypeError):
247
            print(C())  # because footer is abstract
248
        assert isabstract(C)
249
250
        class D(C):
251
            """A throwaway test class."""
252
253
            def barter(self):
254
                pass  # concrete override of concrete
255
        assert D.__abstractmethods__ == {"footer"}
256
        with pytest.raises(TypeError):
257
            print(D())  # because footer is still abstract
258
        assert isabstract(D)
259
260
        class E(D):
261
            """A throwaway test class."""
262
263
            def footer(self):
264
                pass
265
        assert E.__abstractmethods__ == set()
266
        E()  # now footer is concrete, too
267
        assert not isabstract(E)
268
269
        class F(E):
270
            """A throwaway test class."""
271
            @abstractthing
272
            def barter(self):
273
                pass  # abstract override of concrete
274
        assert F.__abstractmethods__ == {"barter"}
275
        with pytest.raises(TypeError):
276
            print(F())  # because barter is abstract now
277
        assert isabstract(F)
278
279
280
def test_abstractmethod_integration_namespaced(abc, namespace):
281
    """Test abstract shortcut decorators work as expected, under a namespace.
282
283
    Adapted from Python's test suite.
284
    """
285
    for abstractthing in [abstractmethod, abc_main.abstractproperty,
286
                          abc_main.abstractclassmethod,
287
                          abc_main.abstractstaticmethod]:
288
        class C(metaclass=abc.NamespaceableABCMeta):
289
            """A throwaway test class."""
290
            with namespace() as ns:
291
                @abstractthing
292
                def footer(self):
293
                    pass  # abstract
294
295
                def barter(self):
296
                    pass  # concrete
297
        assert C.__abstractmethods__ == {"ns.footer"}
298
        with pytest.raises(TypeError):
299
            print(C())  # because footer is abstract
300
        assert isabstract(C)
301
302
        class D(C):
303
            """A throwaway test class."""
304
            with namespace() as ns:
305
                def barter(self):
306
                    pass  # concrete override of concrete
307
        assert D.__abstractmethods__ == {"ns.footer"}
308
        with pytest.raises(TypeError):
309
            print(D())  # because footer is still abstract
310
        assert isabstract(D)
311
312
        class E(D):
313
            """A throwaway test class."""
314
            with namespace() as ns:
315
                def footer(self):
316
                    pass
317
        assert E.__abstractmethods__ == set()
318
        E()  # now footer is concrete, too
319
        assert not isabstract(E)
320
321
        class F(E):
322
            """A throwaway test class."""
323
            with namespace() as ns:
324
                @abstractthing
325
                def barter(self):
326
                    pass  # abstract override of concrete
327
        assert F.__abstractmethods__ == {"ns.barter"}
328
        with pytest.raises(TypeError):
329
            print(F())  # because barter is abstract now
330
        assert isabstract(F)
331
332
333
def test_descriptors_with_abstractmethod(abc):
334
    """Test abstract property methods work as expected.
335
336
    Adapted from Python's test suite.
337
    """
338
    class C(metaclass=abc.NamespaceableABCMeta):
339
        """A throwaway test class."""
340
        @property
341
        @abstractmethod
342
        def footer(self):
343
            return 3
344
345
        @footer.setter
346
        @abstractmethod
347
        def footer(self, val):
348
            pass
349
    with pytest.raises(TypeError):
350
        print(C())
351
352
    class D(C):
353
        """A throwaway test class."""
354
        @C.footer.getter
355
        def footer(self):
356
            return super().footer
357
    with pytest.raises(TypeError):
358
        print(D())
359
360
    class E(D):
361
        """A throwaway test class."""
362
        @D.footer.setter
363
        def footer(self, val):
364
            pass
365
    assert E().footer == 3
366
    # check that the property's __isabstractmethod__ descriptor does the
367
    # right thing when presented with a value that fails truth testing:
368
369
    class NotBool(object):
370
        """A pathological class for test purposes."""
371
372
        def __bool__(self):
373
            raise ValueError()
374
        __len__ = __bool__
375
    with pytest.raises(ValueError):
376
        class F(C):
377
            """A throwaway test class."""
378
379
            def barter(self):
380
                pass
381
            barter.__isabstractmethod__ = NotBool()
382
            footer = property(barter)
383
384
385
def test_descriptors_with_abstractmethod_namespaced(abc, namespace):
386
    """Test abstract property methods work as expected under a namespace.
387
388
    Adapted from Python's test suite.
389
    """
390
    class C(metaclass=abc.NamespaceableABCMeta):
391
        """A throwaway test class."""
392
        with namespace() as ns:
393
            @property
394
            @abstractmethod
395
            def footer(self):
396
                return 3
397
398
            @footer.setter
399
            @abstractmethod
400
            def footer(self, val):
401
                pass
402
    with pytest.raises(TypeError):
403
        print(C())
404
405
    class D(C):
406
        """A throwaway test class."""
407
        with namespace() as ns:
408
            @C.ns.footer.getter
409
            def footer(self):
410
                return super().ns.footer
411
    with pytest.raises(TypeError):
412
        print(D())
413
414
    class E(D):
415
        """A throwaway test class."""
416
        with namespace() as ns:
417
            @D.ns.footer.setter
418
            def footer(self, val):
419
                pass
420
    assert E().ns.footer == 3
421
    # check that the property's __isabstractmethod__ descriptor does the
422
    # right thing when presented with a value that fails truth testing:
423
424
    class NotBool(object):
425
        """A pathological class for test purposes."""
426
427
        def __bool__(self):
428
            raise ValueError()
429
        __len__ = __bool__
430
    with pytest.raises(ValueError):
431
        class F(C):
432
            """A throwaway test class."""
433
            with namespace() as ns:
434
                def barter(self):
435
                    pass
436
                barter.__isabstractmethod__ = NotBool()
437
                footer = property(barter)
438
439
440
def test_customdescriptors_with_abstractmethod(abc):
441
    """Test abstract custom descriptors work as expected.
442
443
    Adapted from Python's test suite.
444
    """
445
    class Descriptor:
446
        """A descriptor class integrated some with the ABC protocol."""
447
448
        def __init__(self, fget, fset=None):
449
            self._fget = fget
450
            self._fset = fset
451
452
        def getter(self, callable):
453
            return Descriptor(callable, self._fget)
454
455
        def setter(self, callable):
456
            return Descriptor(self._fget, callable)
457
458
        @property
459
        def __isabstractmethod__(self):
460
            return (getattr(self._fget, '__isabstractmethod__', False) or
461
                    getattr(self._fset, '__isabstractmethod__', False))
462
463
    class C(metaclass=abc.NamespaceableABCMeta):
464
        """A throwaway test class."""
465
        @Descriptor
466
        @abstractmethod
467
        def footer(self):
468
            return 3
469
470
        @footer.setter
471
        @abstractmethod
472
        def footer(self, val):
473
            pass
474
    with pytest.raises(TypeError):
475
        print(C())
476
477
    class D(C):
478
        """A throwaway test class."""
479
        @C.footer.getter
480
        def footer(self):
481
            return super().footer
482
    with pytest.raises(TypeError):
483
        print(D())
484
485
    class E(D):
486
        """A throwaway test class."""
487
        @D.footer.setter
488
        def footer(self, val):
489
            pass
490
    assert not (E.footer.__isabstractmethod__)
491
492
493
def test_customdescriptors_with_abstractmethod_namespaced(abc, namespace):
494
    """Test abstract custom descriptors work as expected under a namespace.
495
496
    Adapted from Python's test suite.
497
    """
498
    class Descriptor:
499
        """A descriptor class integrated some with the ABC protocol."""
500
501
        def __init__(self, fget, fset=None):
502
            self._fget = fget
503
            self._fset = fset
504
505
        def getter(self, callable):
506
            return Descriptor(callable, self._fget)
507
508
        def setter(self, callable):
509
            return Descriptor(self._fget, callable)
510
511
        @property
512
        def __isabstractmethod__(self):
513
            return (getattr(self._fget, '__isabstractmethod__', False) or
514
                    getattr(self._fset, '__isabstractmethod__', False))
515
516
    class C(metaclass=abc.NamespaceableABCMeta):
517
        """A throwaway test class."""
518
        with namespace() as ns:
519
            @Descriptor
520
            @abstractmethod
521
            def footer(self):
522
                return 3
523
524
            @footer.setter
525
            @abstractmethod
526
            def footer(self, val):
527
                pass
528
    with pytest.raises(TypeError):
529
        print(C())
530
531
    class D(C):
532
        """A throwaway test class."""
533
        with namespace() as ns:
534
            @C.ns.footer.getter
535
            def footer(self):
536
                return super().ns.footer
537
    with pytest.raises(TypeError):
538
        print(D())
539
540
    class E(D):
541
        """A throwaway test class."""
542
        with namespace() as ns:
543
            @D.ns.footer.setter
544
            def footer(self, val):
545
                pass
546
    assert not (E.ns.footer.__isabstractmethod__)
547
548
549
def test_metaclass_abc(abc):
550
    """Test abstract metaclasses work as expected.
551
552
    Adapted from Python's test suite.
553
    """
554
    # Metaclasses can be ABCs, too.
555
    class A(metaclass=abc.NamespaceableABCMeta):
556
        """A throwaway test class."""
557
        @abstractmethod
558
        def x(self):
559
            pass
560
    assert A.__abstractmethods__ == {"x"}
561
562
    class meta(type, A):
563
        """A throwaway test metaclass."""
564
565
        def x(self):
566
            return 1
567
568
    class C(metaclass=meta):
569
        """A throwaway test class."""
570
571
572
def test_metaclass_abc_namespaced(abc, namespace):
573
    """Test abstract metaclasses work as expected, with namespaces.
574
575
    Adapted from Python's test suite.
576
    """
577
    # Metaclasses can be ABCs, too.
578
    class A(metaclass=abc.NamespaceableABCMeta):
579
        """A throwaway test class."""
580
        with namespace() as ns:
581
            @abstractmethod
582
            def x(self):
583
                pass
584
    assert A.__abstractmethods__ == {"ns.x"}
585
586
    class meta(type, A):
587
        """A throwaway test metaclass."""
588
        with namespace() as ns:
589
            def x(self):
590
                return 1
591
592
    class C(metaclass=meta):
593
        """A throwaway test class."""
594
595
596
def test_registration_basics(abc):
597
    """Test ABC registration.
598
599
    Adapted from Python's test suite.
600
    """
601
    class A(metaclass=abc.NamespaceableABCMeta):
602
        """A throwaway test class."""
603
604
    class B(object):
605
        """A throwaway test class."""
606
    b = B()
607
    assert not (issubclass(B, A))
608
    assert not (issubclass(B, (A,)))
609
    assert not isinstance(b, A)
610
    assert not isinstance(b, (A,))
611
    B1 = A.register(B)
612
    assert issubclass(B, A)
613
    assert issubclass(B, (A,))
614
    assert isinstance(b, A)
615
    assert isinstance(b, (A,))
616
    assert B1 is B
617
618
    class C(B):
619
        """A throwaway test class."""
620
    c = C()
621
    assert issubclass(C, A)
622
    assert issubclass(C, (A,))
623
    assert isinstance(c, A)
624
    assert isinstance(c, (A,))
625
626
627
def test_register_as_class_deco(abc):
628
    """Test ABC registration decorator.
629
630
    Adapted from Python's test suite.
631
    """
632
    class A(metaclass=abc.NamespaceableABCMeta):
633
        """A throwaway test class."""
634
635
    @A.register
636
    class B(object):
637
        """A throwaway test class."""
638
    b = B()
639
    assert issubclass(B, A)
640
    assert issubclass(B, (A,))
641
    assert isinstance(b, A)
642
    assert isinstance(b, (A,))
643
644
    @A.register
645
    class C(B):
646
        """A throwaway test class."""
647
    c = C()
648
    assert issubclass(C, A)
649
    assert issubclass(C, (A,))
650
    assert isinstance(c, A)
651
    assert isinstance(c, (A,))
652
    assert C is A.register(C)
653
654
655
@pytest.mark.xfail(sys.version_info < (3, 4),
656
                   reason="python3.4 api changes?", strict=True)
657
def test_isinstance_invalidation(abc):
658
    """Test after-the-fact registration behavior.
659
660
    Adapted from Python's test suite.
661
    """
662
    class A(metaclass=abc.NamespaceableABCMeta):
663
        """A throwaway test class."""
664
665
    class B:
666
        """A throwaway test class."""
667
    b = B()
668
    assert not (isinstance(b, A))
669
    assert not (isinstance(b, (A,)))
670
    token_old = abc_main.get_cache_token()
671
    A.register(B)
672
    token_new = abc_main.get_cache_token()
673
    assert token_old != token_new
674
    assert isinstance(b, A)
675
    assert isinstance(b, (A,))
676
677
678
def test_registration_builtins(abc):
679
    """Test making builtin classes into registered subclasses.
680
681
    Adapted from Python's test suite.
682
    """
683
    class A(metaclass=abc.NamespaceableABCMeta):
684
        """A throwaway test class."""
685
    A.register(int)
686
    assert isinstance(42, A)
687
    assert isinstance(42, (A,))
688
    assert issubclass(int, A)
689
    assert issubclass(int, (A,))
690
691
    class B(A):
692
        """A throwaway test class."""
693
    B.register(str)
694
695
    class C(str):
696
        """A throwaway test class."""
697
    assert isinstance("", A)
698
    assert isinstance("", (A,))
699
    assert issubclass(str, A)
700
    assert issubclass(str, (A,))
701
    assert issubclass(C, A)
702
    assert issubclass(C, (A,))
703
704
705
def test_registration_edge_cases(abc):
706
    """Test edge cases in registration: reflexive, cyclic, repeated...
707
708
    Adapted from Python's test suite.
709
    """
710
    class A(metaclass=abc.NamespaceableABCMeta):
711
        """A throwaway test class."""
712
    A.register(A)  # should pass silently
713
714
    class A1(A):
715
        """A throwaway test class."""
716
    with pytest.raises(RuntimeError):
717
        A1.register(A)  # cycles not allowed
718
719
    class B(object):
720
        """A throwaway test class."""
721
    A1.register(B)  # ok
722
    A1.register(B)  # should pass silently
723
724
    class C(A):
725
        """A throwaway test class."""
726
    A.register(C)  # should pass silently
727
    with pytest.raises(RuntimeError):
728
        C.register(A)  # cycles not allowed
729
    C.register(B)  # ok
730
731
732
def test_register_non_class(abc):
733
    """Test that non-classes cannot be registered.
734
735
    Adapted from Python's test suite.
736
    """
737
    class A(metaclass=abc.NamespaceableABCMeta):
738
        """A throwaway test class."""
739
    with pytest.raises(TypeError, message="Can only register classes"):
740
        print(A.register(4))
741
742
743
def test_registration_transitiveness(abc):
744
    """Test that chains of registration hold.
745
746
    Adapted from Python's test suite.
747
    """
748
    class A(metaclass=abc.NamespaceableABCMeta):
749
        """A throwaway test class."""
750
    assert issubclass(A, A)
751
    assert issubclass(A, (A,))
752
753
    class B(metaclass=abc.NamespaceableABCMeta):
754
        """A throwaway test class."""
755
    assert not (issubclass(A, B))
756
    assert not (issubclass(A, (B,)))
757
    assert not (issubclass(B, A))
758
    assert not (issubclass(B, (A,)))
759
760
    class C(metaclass=abc.NamespaceableABCMeta):
761
        """A throwaway test class."""
762
    A.register(B)
763
764
    class B1(B):
765
        """A throwaway test class."""
766
    assert issubclass(B1, A)
767
    assert issubclass(B1, (A,))
768
769
    class C1(C):
770
        """A throwaway test class."""
771
    B1.register(C1)
772
    assert not issubclass(C, B)
773
    assert not issubclass(C, (B,))
774
    assert not issubclass(C, B1)
775
    assert not issubclass(C, (B1,))
776
    assert issubclass(C1, A)
777
    assert issubclass(C1, (A,))
778
    assert issubclass(C1, B)
779
    assert issubclass(C1, (B,))
780
    assert issubclass(C1, B1)
781
    assert issubclass(C1, (B1,))
782
    C1.register(int)
783
784
    class MyInt(int):
785
        """A throwaway test class."""
786
    assert issubclass(MyInt, A)
787
    assert issubclass(MyInt, (A,))
788
    assert isinstance(42, A)
789
    assert isinstance(42, (A,))
790
791
792
def test_all_new_methods_are_called(abc):
793
    """Test that super delegation still works using abstract classes.
794
795
    Adapted from Python's test suite.
796
    """
797
    class A(metaclass=abc.NamespaceableABCMeta):
798
        """A throwaway test class."""
799
800
    class B(object):
801
        """A throwaway test class."""
802
        counter = 0
803
804
        def __new__(cls):
805
            B.counter += 1
806
            return super().__new__(cls)
807
808
    class C(A, B):
809
        """A throwaway test class."""
810
    assert B.counter == 0
811
    C()
812
    assert B.counter == 1
813