|
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 |
@@ -7896,6 +7897,71 @@ def f(x: int): |
7896 | 7897 | self.assertEqual(get_annotations(f), {"x": str}) |
7897 | 7898 |
|
7898 | 7899 |
|
| 7900 | +class TestGetAnnotationsMetaclasses(BaseTestCase): |
| 7901 | + def test_annotated_meta(self): |
| 7902 | + class Meta(type): |
| 7903 | + a: int |
| 7904 | + |
| 7905 | + class X(metaclass=Meta): |
| 7906 | + pass |
| 7907 | + |
| 7908 | + class Y(metaclass=Meta): |
| 7909 | + b: float |
| 7910 | + |
| 7911 | + self.assertEqual(get_annotations(Meta), {"a": int}) |
| 7912 | + self.assertEqual(get_annotations(X), {}) |
| 7913 | + self.assertEqual(get_annotations(Y), {"b": float}) |
| 7914 | + |
| 7915 | + def test_unannotated_meta(self): |
| 7916 | + class Meta(type): pass |
| 7917 | + |
| 7918 | + class X(metaclass=Meta): |
| 7919 | + a: str |
| 7920 | + |
| 7921 | + class Y(X): pass |
| 7922 | + |
| 7923 | + self.assertEqual(get_annotations(Meta), {}) |
| 7924 | + self.assertEqual(get_annotations(Y), {}) |
| 7925 | + self.assertEqual(get_annotations(X), {"a": str}) |
| 7926 | + |
| 7927 | + def test_ordering(self): |
| 7928 | + # Based on a sample by David Ellis |
| 7929 | + # https://discuss.python.org/t/pep-749-implementing-pep-649/54974/38 |
| 7930 | + |
| 7931 | + def make_classes(): |
| 7932 | + class Meta(type): |
| 7933 | + a: int |
| 7934 | + expected_annotations = {"a": int} |
| 7935 | + |
| 7936 | + class A(type, metaclass=Meta): |
| 7937 | + b: float |
| 7938 | + expected_annotations = {"b": float} |
| 7939 | + |
| 7940 | + class B(metaclass=A): |
| 7941 | + c: str |
| 7942 | + expected_annotations = {"c": str} |
| 7943 | + |
| 7944 | + class C(B): |
| 7945 | + expected_annotations = {} |
| 7946 | + |
| 7947 | + class D(metaclass=Meta): |
| 7948 | + expected_annotations = {} |
| 7949 | + |
| 7950 | + return Meta, A, B, C, D |
| 7951 | + |
| 7952 | + classes = make_classes() |
| 7953 | + class_count = len(classes) |
| 7954 | + for order in itertools.permutations(range(class_count), class_count): |
| 7955 | + names = ", ".join(classes[i].__name__ for i in order) |
| 7956 | + with self.subTest(names=names): |
| 7957 | + classes = make_classes() # Regenerate classes |
| 7958 | + for i in order: |
| 7959 | + get_annotations(classes[i]) |
| 7960 | + for c in classes: |
| 7961 | + with self.subTest(c=c): |
| 7962 | + self.assertEqual(get_annotations(c), c.expected_annotations) |
| 7963 | + |
| 7964 | + |
7899 | 7965 | @skipIf(STRINGIZED_ANNOTATIONS_PEP_695 is None, "PEP 695 has yet to be") |
7900 | 7966 | class TestGetAnnotationsWithPEP695(BaseTestCase): |
7901 | 7967 | @classmethod |
|
0 commit comments