|  | 
| 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