|
7 | 7 | import functools |
8 | 8 | import itertools |
9 | 9 | import pickle |
10 | | -from string.templatelib import Interpolation, Template |
| 10 | +from string.templatelib import Template |
11 | 11 | import typing |
12 | 12 | import unittest |
13 | 13 | from annotationlib import ( |
@@ -815,6 +815,70 @@ def test_stringized_annotations_on_class(self): |
815 | 815 | {"x": int}, |
816 | 816 | ) |
817 | 817 |
|
| 818 | + def test_stringized_annotation_permutations(self): |
| 819 | + def define_class(name, has_future, has_annos, base_text, extra_names=None): |
| 820 | + lines = [] |
| 821 | + if has_future: |
| 822 | + lines.append("from __future__ import annotations") |
| 823 | + lines.append(f"class {name}({base_text}):") |
| 824 | + if has_annos: |
| 825 | + lines.append(f" {name}_attr: int") |
| 826 | + else: |
| 827 | + lines.append(" pass") |
| 828 | + code = "\n".join(lines) |
| 829 | + ns = support.run_code(code, extra_names=extra_names) |
| 830 | + return ns[name] |
| 831 | + |
| 832 | + def check_annotations(cls, has_future, has_annos): |
| 833 | + if has_annos: |
| 834 | + if has_future: |
| 835 | + anno = "int" |
| 836 | + else: |
| 837 | + anno = int |
| 838 | + self.assertEqual(get_annotations(cls), {f"{cls.__name__}_attr": anno}) |
| 839 | + else: |
| 840 | + self.assertEqual(get_annotations(cls), {}) |
| 841 | + |
| 842 | + for meta_future, base_future, child_future, meta_has_annos, base_has_annos, child_has_annos in itertools.product( |
| 843 | + (False, True), |
| 844 | + (False, True), |
| 845 | + (False, True), |
| 846 | + (False, True), |
| 847 | + (False, True), |
| 848 | + (False, True), |
| 849 | + ): |
| 850 | + with self.subTest( |
| 851 | + meta_future=meta_future, |
| 852 | + base_future=base_future, |
| 853 | + child_future=child_future, |
| 854 | + meta_has_annos=meta_has_annos, |
| 855 | + base_has_annos=base_has_annos, |
| 856 | + child_has_annos=child_has_annos, |
| 857 | + ): |
| 858 | + meta = define_class( |
| 859 | + "Meta", |
| 860 | + has_future=meta_future, |
| 861 | + has_annos=meta_has_annos, |
| 862 | + base_text="type", |
| 863 | + ) |
| 864 | + base = define_class( |
| 865 | + "Base", |
| 866 | + has_future=base_future, |
| 867 | + has_annos=base_has_annos, |
| 868 | + base_text="metaclass=Meta", |
| 869 | + extra_names={"Meta": meta}, |
| 870 | + ) |
| 871 | + child = define_class( |
| 872 | + "Child", |
| 873 | + has_future=child_future, |
| 874 | + has_annos=child_has_annos, |
| 875 | + base_text="Base", |
| 876 | + extra_names={"Base": base}, |
| 877 | + ) |
| 878 | + check_annotations(meta, meta_future, meta_has_annos) |
| 879 | + check_annotations(base, base_future, base_has_annos) |
| 880 | + check_annotations(child, child_future, child_has_annos) |
| 881 | + |
818 | 882 | def test_modify_annotations(self): |
819 | 883 | def f(x: int): |
820 | 884 | pass |
|
0 commit comments