|
8 | 8 | import importlib |
9 | 9 | import inspect |
10 | 10 | import io |
| 11 | +import itertools |
11 | 12 | import pickle |
12 | 13 | import re |
13 | 14 | import subprocess |
@@ -7647,6 +7648,71 @@ def f(x: int): |
7647 | 7648 | self.assertEqual(get_annotations(f), {"x": str}) |
7648 | 7649 |
|
7649 | 7650 |
|
| 7651 | +class TestGetAnnotationsMetaclasses(BaseTestCase): |
| 7652 | + def test_annotated_meta(self): |
| 7653 | + class Meta(type): |
| 7654 | + a: int |
| 7655 | + |
| 7656 | + class X(metaclass=Meta): |
| 7657 | + pass |
| 7658 | + |
| 7659 | + class Y(metaclass=Meta): |
| 7660 | + b: float |
| 7661 | + |
| 7662 | + self.assertEqual(get_annotations(Meta), {"a": int}) |
| 7663 | + self.assertEqual(get_annotations(X), {}) |
| 7664 | + self.assertEqual(get_annotations(Y), {"b": float}) |
| 7665 | + |
| 7666 | + def test_unannotated_meta(self): |
| 7667 | + class Meta(type): pass |
| 7668 | + |
| 7669 | + class X(metaclass=Meta): |
| 7670 | + a: str |
| 7671 | + |
| 7672 | + class Y(X): pass |
| 7673 | + |
| 7674 | + self.assertEqual(get_annotations(Meta), {}) |
| 7675 | + self.assertEqual(get_annotations(Y), {}) |
| 7676 | + self.assertEqual(get_annotations(X), {"a": str}) |
| 7677 | + |
| 7678 | + def test_ordering(self): |
| 7679 | + # Based on a sample by David Ellis |
| 7680 | + # https://discuss.python.org/t/pep-749-implementing-pep-649/54974/38 |
| 7681 | + |
| 7682 | + def make_classes(): |
| 7683 | + class Meta(type): |
| 7684 | + a: int |
| 7685 | + expected_annotations = {"a": int} |
| 7686 | + |
| 7687 | + class A(type, metaclass=Meta): |
| 7688 | + b: float |
| 7689 | + expected_annotations = {"b": float} |
| 7690 | + |
| 7691 | + class B(metaclass=A): |
| 7692 | + c: str |
| 7693 | + expected_annotations = {"c": str} |
| 7694 | + |
| 7695 | + class C(B): |
| 7696 | + expected_annotations = {} |
| 7697 | + |
| 7698 | + class D(metaclass=Meta): |
| 7699 | + expected_annotations = {} |
| 7700 | + |
| 7701 | + return Meta, A, B, C, D |
| 7702 | + |
| 7703 | + classes = make_classes() |
| 7704 | + class_count = len(classes) |
| 7705 | + for order in itertools.permutations(range(class_count), class_count): |
| 7706 | + names = ", ".join(classes[i].__name__ for i in order) |
| 7707 | + with self.subTest(names=names): |
| 7708 | + classes = make_classes() # Regenerate classes |
| 7709 | + for i in order: |
| 7710 | + get_annotations(classes[i]) |
| 7711 | + for c in classes: |
| 7712 | + with self.subTest(c=c): |
| 7713 | + self.assertEqual(get_annotations(c), c.expected_annotations) |
| 7714 | + |
| 7715 | + |
7650 | 7716 | @skipIf(STRINGIZED_ANNOTATIONS_PEP_695 is None, "PEP 695 has yet to be") |
7651 | 7717 | class TestGetAnnotationsWithPEP695(BaseTestCase): |
7652 | 7718 | @classmethod |
|
0 commit comments