|
9 | 9 | import importlib |
10 | 10 | import inspect |
11 | 11 | import io |
| 12 | +import itertools |
12 | 13 | import pickle |
13 | 14 | import re |
14 | 15 | import subprocess |
@@ -7751,6 +7752,71 @@ def f(x: int): |
7751 | 7752 | self.assertEqual(get_annotations(f), {"x": str}) |
7752 | 7753 |
|
7753 | 7754 |
|
| 7755 | +class TestGetAnnotationsMetaclasses(BaseTestCase): |
| 7756 | + def test_annotated_meta(self): |
| 7757 | + class Meta(type): |
| 7758 | + a: int |
| 7759 | + |
| 7760 | + class X(metaclass=Meta): |
| 7761 | + pass |
| 7762 | + |
| 7763 | + class Y(metaclass=Meta): |
| 7764 | + b: float |
| 7765 | + |
| 7766 | + self.assertEqual(get_annotations(Meta), {"a": int}) |
| 7767 | + self.assertEqual(get_annotations(X), {}) |
| 7768 | + self.assertEqual(get_annotations(Y), {"b": float}) |
| 7769 | + |
| 7770 | + def test_unannotated_meta(self): |
| 7771 | + class Meta(type): pass |
| 7772 | + |
| 7773 | + class X(metaclass=Meta): |
| 7774 | + a: str |
| 7775 | + |
| 7776 | + class Y(X): pass |
| 7777 | + |
| 7778 | + self.assertEqual(get_annotations(Meta), {}) |
| 7779 | + self.assertEqual(get_annotations(Y), {}) |
| 7780 | + self.assertEqual(get_annotations(X), {"a": str}) |
| 7781 | + |
| 7782 | + def test_ordering(self): |
| 7783 | + # Based on a sample by David Ellis |
| 7784 | + # https://discuss.python.org/t/pep-749-implementing-pep-649/54974/38 |
| 7785 | + |
| 7786 | + def make_classes(): |
| 7787 | + class Meta(type): |
| 7788 | + a: int |
| 7789 | + expected_annotations = {"a": int} |
| 7790 | + |
| 7791 | + class A(type, metaclass=Meta): |
| 7792 | + b: float |
| 7793 | + expected_annotations = {"b": float} |
| 7794 | + |
| 7795 | + class B(metaclass=A): |
| 7796 | + c: str |
| 7797 | + expected_annotations = {"c": str} |
| 7798 | + |
| 7799 | + class C(B): |
| 7800 | + expected_annotations = {} |
| 7801 | + |
| 7802 | + class D(metaclass=Meta): |
| 7803 | + expected_annotations = {} |
| 7804 | + |
| 7805 | + return Meta, A, B, C, D |
| 7806 | + |
| 7807 | + classes = make_classes() |
| 7808 | + class_count = len(classes) |
| 7809 | + for order in itertools.permutations(range(class_count), class_count): |
| 7810 | + names = ", ".join(classes[i].__name__ for i in order) |
| 7811 | + with self.subTest(names=names): |
| 7812 | + classes = make_classes() # Regenerate classes |
| 7813 | + for i in order: |
| 7814 | + get_annotations(classes[i]) |
| 7815 | + for c in classes: |
| 7816 | + with self.subTest(c=c): |
| 7817 | + self.assertEqual(get_annotations(c), c.expected_annotations) |
| 7818 | + |
| 7819 | + |
7754 | 7820 | @skipIf(STRINGIZED_ANNOTATIONS_PEP_695 is None, "PEP 695 has yet to be") |
7755 | 7821 | class TestGetAnnotationsWithPEP695(BaseTestCase): |
7756 | 7822 | @classmethod |
|
0 commit comments