"""Tests for the annotations module."""

import annotationlib
import functools
import itertools
import pickle
import unittest
from annotationlib import Format, ForwardRef, get_annotations, get_annotate_function
from typing import Unpack

from test import support
from test.test_inspect import inspect_stock_annotations
from test.test_inspect import inspect_stringized_annotations
from test.test_inspect import inspect_stringized_annotations_2
from test.test_inspect import inspect_stringized_annotations_pep695


def times_three(fn):
    @functools.wraps(fn)
    def wrapper(a, b):
        return fn(a * 3, b * 3)

    return wrapper


class TestFormat(unittest.TestCase):
    def test_enum(self):
        self.assertEqual(annotationlib.Format.VALUE.value, 1)
        self.assertEqual(annotationlib.Format.VALUE, 1)

        self.assertEqual(annotationlib.Format.FORWARDREF.value, 2)
        self.assertEqual(annotationlib.Format.FORWARDREF, 2)

        self.assertEqual(annotationlib.Format.SOURCE.value, 3)
        self.assertEqual(annotationlib.Format.SOURCE, 3)


class TestForwardRefFormat(unittest.TestCase):
    def test_closure(self):
        def inner(arg: x):
            pass

        anno = annotationlib.get_annotations(
            inner, format=annotationlib.Format.FORWARDREF
        )
        fwdref = anno["arg"]
        self.assertIsInstance(fwdref, annotationlib.ForwardRef)
        self.assertEqual(fwdref.__forward_arg__, "x")
        with self.assertRaises(NameError):
            fwdref.evaluate()

        x = 1
        self.assertEqual(fwdref.evaluate(), x)

        anno = annotationlib.get_annotations(
            inner, format=annotationlib.Format.FORWARDREF
        )
        self.assertEqual(anno["arg"], x)

    def test_function(self):
        def f(x: int, y: doesntexist):
            pass

        anno = annotationlib.get_annotations(f, format=annotationlib.Format.FORWARDREF)
        self.assertIs(anno["x"], int)
        fwdref = anno["y"]
        self.assertIsInstance(fwdref, annotationlib.ForwardRef)
        self.assertEqual(fwdref.__forward_arg__, "doesntexist")
        with self.assertRaises(NameError):
            fwdref.evaluate()
        self.assertEqual(fwdref.evaluate(globals={"doesntexist": 1}), 1)


class TestSourceFormat(unittest.TestCase):
    def test_closure(self):
        x = 0

        def inner(arg: x):
            pass

        anno = annotationlib.get_annotations(inner, format=annotationlib.Format.SOURCE)
        self.assertEqual(anno, {"arg": "x"})

    def test_function(self):
        def f(x: int, y: doesntexist):
            pass

        anno = annotationlib.get_annotations(f, format=annotationlib.Format.SOURCE)
        self.assertEqual(anno, {"x": "int", "y": "doesntexist"})

    def test_expressions(self):
        def f(
            add: a + b,
            sub: a - b,
            mul: a * b,
            matmul: a @ b,
            truediv: a / b,
            mod: a % b,
            lshift: a << b,
            rshift: a >> b,
            or_: a | b,
            xor: a ^ b,
            and_: a & b,
            floordiv: a // b,
            pow_: a**b,
            lt: a < b,
            le: a <= b,
            eq: a == b,
            ne: a != b,
            gt: a > b,
            ge: a >= b,
            invert: ~a,
            neg: -a,
            pos: +a,
            getitem: a[b],
            getattr: a.b,
            call: a(b, *c, d=e),  # **kwargs are not supported
            *args: *a,
        ):
            pass

        anno = annotationlib.get_annotations(f, format=annotationlib.Format.SOURCE)
        self.assertEqual(
            anno,
            {
                "add": "a + b",
                "sub": "a - b",
                "mul": "a * b",
                "matmul": "a @ b",
                "truediv": "a / b",
                "mod": "a % b",
                "lshift": "a << b",
                "rshift": "a >> b",
                "or_": "a | b",
                "xor": "a ^ b",
                "and_": "a & b",
                "floordiv": "a // b",
                "pow_": "a ** b",
                "lt": "a < b",
                "le": "a <= b",
                "eq": "a == b",
                "ne": "a != b",
                "gt": "a > b",
                "ge": "a >= b",
                "invert": "~a",
                "neg": "-a",
                "pos": "+a",
                "getitem": "a[b]",
                "getattr": "a.b",
                "call": "a(b, *c, d=e)",
                "args": "*a",
            },
        )

    def test_reverse_ops(self):
        def f(
            radd: 1 + a,
            rsub: 1 - a,
            rmul: 1 * a,
            rmatmul: 1 @ a,
            rtruediv: 1 / a,
            rmod: 1 % a,
            rlshift: 1 << a,
            rrshift: 1 >> a,
            ror: 1 | a,
            rxor: 1 ^ a,
            rand: 1 & a,
            rfloordiv: 1 // a,
            rpow: 1**a,
        ):
            pass

        anno = annotationlib.get_annotations(f, format=annotationlib.Format.SOURCE)
        self.assertEqual(
            anno,
            {
                "radd": "1 + a",
                "rsub": "1 - a",
                "rmul": "1 * a",
                "rmatmul": "1 @ a",
                "rtruediv": "1 / a",
                "rmod": "1 % a",
                "rlshift": "1 << a",
                "rrshift": "1 >> a",
                "ror": "1 | a",
                "rxor": "1 ^ a",
                "rand": "1 & a",
                "rfloordiv": "1 // a",
                "rpow": "1 ** a",
            },
        )

    def test_nested_expressions(self):
        def f(
            nested: list[Annotated[set[int], "set of ints", 4j]],
            set: {a + b},  # single element because order is not guaranteed
            dict: {a + b: c + d, "key": e + g},
            list: [a, b, c],
            tuple: (a, b, c),
            slice: (a[b:c], a[b:c:d], a[:c], a[b:], a[:], a[::d], a[b::d]),
            extended_slice: a[:, :, c:d],
            unpack1: [*a],
            unpack2: [*a, b, c],
        ):
            pass

        anno = annotationlib.get_annotations(f, format=annotationlib.Format.SOURCE)
        self.assertEqual(
            anno,
            {
                "nested": "list[Annotated[set[int], 'set of ints', 4j]]",
                "set": "{a + b}",
                "dict": "{a + b: c + d, 'key': e + g}",
                "list": "[a, b, c]",
                "tuple": "(a, b, c)",
                "slice": "(a[b:c], a[b:c:d], a[:c], a[b:], a[:], a[::d], a[b::d])",
                "extended_slice": "a[:, :, c:d]",
                "unpack1": "[*a]",
                "unpack2": "[*a, b, c]",
            },
        )

    def test_unsupported_operations(self):
        format_msg = "Cannot stringify annotation containing string formatting"

        def f(fstring: f"{a}"):
            pass

        with self.assertRaisesRegex(TypeError, format_msg):
            annotationlib.get_annotations(f, format=annotationlib.Format.SOURCE)

        def f(fstring_format: f"{a:02d}"):
            pass

        with self.assertRaisesRegex(TypeError, format_msg):
            annotationlib.get_annotations(f, format=annotationlib.Format.SOURCE)


class TestForwardRefClass(unittest.TestCase):
    def test_special_attrs(self):
        # Forward refs provide a different introspection API. __name__ and
        # __qualname__ make little sense for forward refs as they can store
        # complex typing expressions.
        fr = annotationlib.ForwardRef("set[Any]")
        self.assertFalse(hasattr(fr, "__name__"))
        self.assertFalse(hasattr(fr, "__qualname__"))
        self.assertEqual(fr.__module__, "annotationlib")
        # Forward refs are currently unpicklable once they contain a code object.
        fr.__forward_code__  # fill the cache
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            with self.assertRaises(TypeError):
                pickle.dumps(fr, proto)

    def test_evaluate_with_type_params(self):
        class Gen[T]:
            alias = int

        with self.assertRaises(NameError):
            ForwardRef("T").evaluate()
        with self.assertRaises(NameError):
            ForwardRef("T").evaluate(type_params=())
        with self.assertRaises(NameError):
            ForwardRef("T").evaluate(owner=int)

        T, = Gen.__type_params__
        self.assertIs(ForwardRef("T").evaluate(type_params=Gen.__type_params__), T)
        self.assertIs(ForwardRef("T").evaluate(owner=Gen), T)

        with self.assertRaises(NameError):
            ForwardRef("alias").evaluate(type_params=Gen.__type_params__)
        self.assertIs(ForwardRef("alias").evaluate(owner=Gen), int)
        # If you pass custom locals, we don't look at the owner's locals
        with self.assertRaises(NameError):
            ForwardRef("alias").evaluate(owner=Gen, locals={})
        # But if the name exists in the locals, it works
        self.assertIs(
            ForwardRef("alias").evaluate(owner=Gen, locals={"alias": str}), str
        )

    def test_fwdref_with_module(self):
        self.assertIs(ForwardRef("Format", module=annotationlib).evaluate(), Format)

        with self.assertRaises(NameError):
            # If globals are passed explicitly, we don't look at the module dict
            ForwardRef("Format", module=annotationlib).evaluate(globals={})

    def test_fwdref_value_is_cached(self):
        fr = ForwardRef("hello")
        with self.assertRaises(NameError):
            fr.evaluate()
        self.assertIs(fr.evaluate(globals={"hello": str}), str)
        self.assertIs(fr.evaluate(), str)


class TestGetAnnotations(unittest.TestCase):
    def test_builtin_type(self):
        self.assertEqual(annotationlib.get_annotations(int), {})
        self.assertEqual(annotationlib.get_annotations(object), {})

    def test_custom_metaclass(self):
        class Meta(type):
            pass

        class C(metaclass=Meta):
            x: int

        self.assertEqual(annotationlib.get_annotations(C), {"x": int})

    def test_missing_dunder_dict(self):
        class NoDict(type):
            @property
            def __dict__(cls):
                raise AttributeError

            b: str

        class C1(metaclass=NoDict):
            a: int

        self.assertEqual(annotationlib.get_annotations(C1), {"a": int})
        self.assertEqual(
            annotationlib.get_annotations(C1, format=annotationlib.Format.FORWARDREF),
            {"a": int},
        )
        self.assertEqual(
            annotationlib.get_annotations(C1, format=annotationlib.Format.SOURCE),
            {"a": "int"},
        )
        self.assertEqual(annotationlib.get_annotations(NoDict), {"b": str})
        self.assertEqual(
            annotationlib.get_annotations(
                NoDict, format=annotationlib.Format.FORWARDREF
            ),
            {"b": str},
        )
        self.assertEqual(
            annotationlib.get_annotations(NoDict, format=annotationlib.Format.SOURCE),
            {"b": "str"},
        )

    def test_format(self):
        def f1(a: int):
            pass

        def f2(a: undefined):
            pass

        self.assertEqual(
            annotationlib.get_annotations(f1, format=annotationlib.Format.VALUE),
            {"a": int},
        )
        self.assertEqual(annotationlib.get_annotations(f1, format=1), {"a": int})

        fwd = annotationlib.ForwardRef("undefined")
        self.assertEqual(
            annotationlib.get_annotations(f2, format=annotationlib.Format.FORWARDREF),
            {"a": fwd},
        )
        self.assertEqual(annotationlib.get_annotations(f2, format=2), {"a": fwd})

        self.assertEqual(
            annotationlib.get_annotations(f1, format=annotationlib.Format.SOURCE),
            {"a": "int"},
        )
        self.assertEqual(annotationlib.get_annotations(f1, format=3), {"a": "int"})

        with self.assertRaises(ValueError):
            annotationlib.get_annotations(f1, format=0)

        with self.assertRaises(ValueError):
            annotationlib.get_annotations(f1, format=4)

    def test_custom_object_with_annotations(self):
        class C:
            def __init__(self):
                self.__annotations__ = {"x": int, "y": str}

        self.assertEqual(annotationlib.get_annotations(C()), {"x": int, "y": str})

    def test_custom_format_eval_str(self):
        def foo():
            pass

        with self.assertRaises(ValueError):
            annotationlib.get_annotations(
                foo, format=annotationlib.Format.FORWARDREF, eval_str=True
            )
            annotationlib.get_annotations(
                foo, format=annotationlib.Format.SOURCE, eval_str=True
            )

    def test_stock_annotations(self):
        def foo(a: int, b: str):
            pass

        for format in (annotationlib.Format.VALUE, annotationlib.Format.FORWARDREF):
            with self.subTest(format=format):
                self.assertEqual(
                    annotationlib.get_annotations(foo, format=format),
                    {"a": int, "b": str},
                )
        self.assertEqual(
            annotationlib.get_annotations(foo, format=annotationlib.Format.SOURCE),
            {"a": "int", "b": "str"},
        )

        foo.__annotations__ = {"a": "foo", "b": "str"}
        for format in annotationlib.Format:
            with self.subTest(format=format):
                self.assertEqual(
                    annotationlib.get_annotations(foo, format=format),
                    {"a": "foo", "b": "str"},
                )

        self.assertEqual(
            annotationlib.get_annotations(foo, eval_str=True, locals=locals()),
            {"a": foo, "b": str},
        )
        self.assertEqual(
            annotationlib.get_annotations(foo, eval_str=True, globals=locals()),
            {"a": foo, "b": str},
        )

    def test_stock_annotations_in_module(self):
        isa = inspect_stock_annotations

        for kwargs in [
            {},
            {"eval_str": False},
            {"format": annotationlib.Format.VALUE},
            {"format": annotationlib.Format.FORWARDREF},
            {"format": annotationlib.Format.VALUE, "eval_str": False},
            {"format": annotationlib.Format.FORWARDREF, "eval_str": False},
        ]:
            with self.subTest(**kwargs):
                self.assertEqual(
                    annotationlib.get_annotations(isa, **kwargs), {"a": int, "b": str}
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.MyClass, **kwargs),
                    {"a": int, "b": str},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function, **kwargs),
                    {"a": int, "b": str, "return": isa.MyClass},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function2, **kwargs),
                    {"a": int, "b": "str", "c": isa.MyClass, "return": isa.MyClass},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function3, **kwargs),
                    {"a": "int", "b": "str", "c": "MyClass"},
                )
                self.assertEqual(
                    annotationlib.get_annotations(annotationlib, **kwargs), {}
                )  # annotations module has no annotations
                self.assertEqual(
                    annotationlib.get_annotations(isa.UnannotatedClass, **kwargs), {}
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.unannotated_function, **kwargs),
                    {},
                )

        for kwargs in [
            {"eval_str": True},
            {"format": annotationlib.Format.VALUE, "eval_str": True},
        ]:
            with self.subTest(**kwargs):
                self.assertEqual(
                    annotationlib.get_annotations(isa, **kwargs), {"a": int, "b": str}
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.MyClass, **kwargs),
                    {"a": int, "b": str},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function, **kwargs),
                    {"a": int, "b": str, "return": isa.MyClass},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function2, **kwargs),
                    {"a": int, "b": str, "c": isa.MyClass, "return": isa.MyClass},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function3, **kwargs),
                    {"a": int, "b": str, "c": isa.MyClass},
                )
                self.assertEqual(
                    annotationlib.get_annotations(annotationlib, **kwargs), {}
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.UnannotatedClass, **kwargs), {}
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.unannotated_function, **kwargs),
                    {},
                )

        self.assertEqual(
            annotationlib.get_annotations(isa, format=annotationlib.Format.SOURCE),
            {"a": "int", "b": "str"},
        )
        self.assertEqual(
            annotationlib.get_annotations(
                isa.MyClass, format=annotationlib.Format.SOURCE
            ),
            {"a": "int", "b": "str"},
        )
        self.assertEqual(
            annotationlib.get_annotations(
                isa.function, format=annotationlib.Format.SOURCE
            ),
            {"a": "int", "b": "str", "return": "MyClass"},
        )
        self.assertEqual(
            annotationlib.get_annotations(
                isa.function2, format=annotationlib.Format.SOURCE
            ),
            {"a": "int", "b": "str", "c": "MyClass", "return": "MyClass"},
        )
        self.assertEqual(
            annotationlib.get_annotations(
                isa.function3, format=annotationlib.Format.SOURCE
            ),
            {"a": "int", "b": "str", "c": "MyClass"},
        )
        self.assertEqual(
            annotationlib.get_annotations(
                annotationlib, format=annotationlib.Format.SOURCE
            ),
            {},
        )
        self.assertEqual(
            annotationlib.get_annotations(
                isa.UnannotatedClass, format=annotationlib.Format.SOURCE
            ),
            {},
        )
        self.assertEqual(
            annotationlib.get_annotations(
                isa.unannotated_function, format=annotationlib.Format.SOURCE
            ),
            {},
        )

    def test_stock_annotations_on_wrapper(self):
        isa = inspect_stock_annotations

        wrapped = times_three(isa.function)
        self.assertEqual(wrapped(1, "x"), isa.MyClass(3, "xxx"))
        self.assertIsNot(wrapped.__globals__, isa.function.__globals__)
        self.assertEqual(
            annotationlib.get_annotations(wrapped),
            {"a": int, "b": str, "return": isa.MyClass},
        )
        self.assertEqual(
            annotationlib.get_annotations(
                wrapped, format=annotationlib.Format.FORWARDREF
            ),
            {"a": int, "b": str, "return": isa.MyClass},
        )
        self.assertEqual(
            annotationlib.get_annotations(wrapped, format=annotationlib.Format.SOURCE),
            {"a": "int", "b": "str", "return": "MyClass"},
        )
        self.assertEqual(
            annotationlib.get_annotations(wrapped, eval_str=True),
            {"a": int, "b": str, "return": isa.MyClass},
        )
        self.assertEqual(
            annotationlib.get_annotations(wrapped, eval_str=False),
            {"a": int, "b": str, "return": isa.MyClass},
        )

    def test_stringized_annotations_in_module(self):
        isa = inspect_stringized_annotations
        for kwargs in [
            {},
            {"eval_str": False},
            {"format": annotationlib.Format.VALUE},
            {"format": annotationlib.Format.FORWARDREF},
            {"format": annotationlib.Format.SOURCE},
            {"format": annotationlib.Format.VALUE, "eval_str": False},
            {"format": annotationlib.Format.FORWARDREF, "eval_str": False},
            {"format": annotationlib.Format.SOURCE, "eval_str": False},
        ]:
            with self.subTest(**kwargs):
                self.assertEqual(
                    annotationlib.get_annotations(isa, **kwargs),
                    {"a": "int", "b": "str"},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.MyClass, **kwargs),
                    {"a": "int", "b": "str"},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function, **kwargs),
                    {"a": "int", "b": "str", "return": "MyClass"},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function2, **kwargs),
                    {"a": "int", "b": "'str'", "c": "MyClass", "return": "MyClass"},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function3, **kwargs),
                    {"a": "'int'", "b": "'str'", "c": "'MyClass'"},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.UnannotatedClass, **kwargs), {}
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.unannotated_function, **kwargs),
                    {},
                )

        for kwargs in [
            {"eval_str": True},
            {"format": annotationlib.Format.VALUE, "eval_str": True},
        ]:
            with self.subTest(**kwargs):
                self.assertEqual(
                    annotationlib.get_annotations(isa, **kwargs), {"a": int, "b": str}
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.MyClass, **kwargs),
                    {"a": int, "b": str},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function, **kwargs),
                    {"a": int, "b": str, "return": isa.MyClass},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function2, **kwargs),
                    {"a": int, "b": "str", "c": isa.MyClass, "return": isa.MyClass},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.function3, **kwargs),
                    {"a": "int", "b": "str", "c": "MyClass"},
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.UnannotatedClass, **kwargs), {}
                )
                self.assertEqual(
                    annotationlib.get_annotations(isa.unannotated_function, **kwargs),
                    {},
                )

    def test_stringized_annotations_in_empty_module(self):
        isa2 = inspect_stringized_annotations_2
        self.assertEqual(annotationlib.get_annotations(isa2), {})
        self.assertEqual(annotationlib.get_annotations(isa2, eval_str=True), {})
        self.assertEqual(annotationlib.get_annotations(isa2, eval_str=False), {})

    def test_stringized_annotations_on_wrapper(self):
        isa = inspect_stringized_annotations
        wrapped = times_three(isa.function)
        self.assertEqual(wrapped(1, "x"), isa.MyClass(3, "xxx"))
        self.assertIsNot(wrapped.__globals__, isa.function.__globals__)
        self.assertEqual(
            annotationlib.get_annotations(wrapped),
            {"a": "int", "b": "str", "return": "MyClass"},
        )
        self.assertEqual(
            annotationlib.get_annotations(wrapped, eval_str=True),
            {"a": int, "b": str, "return": isa.MyClass},
        )
        self.assertEqual(
            annotationlib.get_annotations(wrapped, eval_str=False),
            {"a": "int", "b": "str", "return": "MyClass"},
        )

    def test_stringized_annotations_on_class(self):
        isa = inspect_stringized_annotations
        # test that local namespace lookups work
        self.assertEqual(
            annotationlib.get_annotations(isa.MyClassWithLocalAnnotations),
            {"x": "mytype"},
        )
        self.assertEqual(
            annotationlib.get_annotations(
                isa.MyClassWithLocalAnnotations, eval_str=True
            ),
            {"x": int},
        )

    def test_modify_annotations(self):
        def f(x: int):
            pass

        self.assertEqual(annotationlib.get_annotations(f), {"x": int})
        self.assertEqual(
            annotationlib.get_annotations(f, format=annotationlib.Format.FORWARDREF),
            {"x": int},
        )

        f.__annotations__["x"] = str
        # The modification is reflected in VALUE (the default)
        self.assertEqual(annotationlib.get_annotations(f), {"x": str})
        # ... but not in FORWARDREF, which uses __annotate__
        self.assertEqual(
            annotationlib.get_annotations(f, format=annotationlib.Format.FORWARDREF),
            {"x": int},
        )

    def test_pep695_generic_class_with_future_annotations(self):
        ann_module695 = inspect_stringized_annotations_pep695
        A_annotations = annotationlib.get_annotations(ann_module695.A, eval_str=True)
        A_type_params = ann_module695.A.__type_params__
        self.assertIs(A_annotations["x"], A_type_params[0])
        self.assertEqual(A_annotations["y"].__args__[0], Unpack[A_type_params[1]])
        self.assertIs(A_annotations["z"].__args__[0], A_type_params[2])

    def test_pep695_generic_class_with_future_annotations_and_local_shadowing(self):
        B_annotations = annotationlib.get_annotations(
            inspect_stringized_annotations_pep695.B, eval_str=True
        )
        self.assertEqual(B_annotations, {"x": int, "y": str, "z": bytes})

    def test_pep695_generic_class_with_future_annotations_name_clash_with_global_vars(
        self,
    ):
        ann_module695 = inspect_stringized_annotations_pep695
        C_annotations = annotationlib.get_annotations(ann_module695.C, eval_str=True)
        self.assertEqual(
            set(C_annotations.values()), set(ann_module695.C.__type_params__)
        )

    def test_pep_695_generic_function_with_future_annotations(self):
        ann_module695 = inspect_stringized_annotations_pep695
        generic_func_annotations = annotationlib.get_annotations(
            ann_module695.generic_function, eval_str=True
        )
        func_t_params = ann_module695.generic_function.__type_params__
        self.assertEqual(
            generic_func_annotations.keys(), {"x", "y", "z", "zz", "return"}
        )
        self.assertIs(generic_func_annotations["x"], func_t_params[0])
        self.assertEqual(generic_func_annotations["y"], Unpack[func_t_params[1]])
        self.assertIs(generic_func_annotations["z"].__origin__, func_t_params[2])
        self.assertIs(generic_func_annotations["zz"].__origin__, func_t_params[2])

    def test_pep_695_generic_function_with_future_annotations_name_clash_with_global_vars(
        self,
    ):
        self.assertEqual(
            set(
                annotationlib.get_annotations(
                    inspect_stringized_annotations_pep695.generic_function_2,
                    eval_str=True,
                ).values()
            ),
            set(
                inspect_stringized_annotations_pep695.generic_function_2.__type_params__
            ),
        )

    def test_pep_695_generic_method_with_future_annotations(self):
        ann_module695 = inspect_stringized_annotations_pep695
        generic_method_annotations = annotationlib.get_annotations(
            ann_module695.D.generic_method, eval_str=True
        )
        params = {
            param.__name__: param
            for param in ann_module695.D.generic_method.__type_params__
        }
        self.assertEqual(
            generic_method_annotations,
            {"x": params["Foo"], "y": params["Bar"], "return": None},
        )

    def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_vars(
        self,
    ):
        self.assertEqual(
            set(
                annotationlib.get_annotations(
                    inspect_stringized_annotations_pep695.D.generic_method_2,
                    eval_str=True,
                ).values()
            ),
            set(
                inspect_stringized_annotations_pep695.D.generic_method_2.__type_params__
            ),
        )

    def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_and_local_vars(
        self,
    ):
        self.assertEqual(
            annotationlib.get_annotations(
                inspect_stringized_annotations_pep695.E, eval_str=True
            ),
            {"x": str},
        )

    def test_pep_695_generics_with_future_annotations_nested_in_function(self):
        results = inspect_stringized_annotations_pep695.nested()

        self.assertEqual(
            set(results.F_annotations.values()), set(results.F.__type_params__)
        )
        self.assertEqual(
            set(results.F_meth_annotations.values()),
            set(results.F.generic_method.__type_params__),
        )
        self.assertNotEqual(
            set(results.F_meth_annotations.values()), set(results.F.__type_params__)
        )
        self.assertEqual(
            set(results.F_meth_annotations.values()).intersection(
                results.F.__type_params__
            ),
            set(),
        )

        self.assertEqual(results.G_annotations, {"x": str})

        self.assertEqual(
            set(results.generic_func_annotations.values()),
            set(results.generic_func.__type_params__),
        )


class TestCallEvaluateFunction(unittest.TestCase):
    def test_evaluation(self):
        def evaluate(format, exc=NotImplementedError):
            if format != 1:
                raise exc
            return undefined

        with self.assertRaises(NameError):
            annotationlib.call_evaluate_function(evaluate, annotationlib.Format.VALUE)
        self.assertEqual(
            annotationlib.call_evaluate_function(
                evaluate, annotationlib.Format.FORWARDREF
            ),
            annotationlib.ForwardRef("undefined"),
        )
        self.assertEqual(
            annotationlib.call_evaluate_function(evaluate, annotationlib.Format.SOURCE),
            "undefined",
        )


class MetaclassTests(unittest.TestCase):
    def test_annotated_meta(self):
        class Meta(type):
            a: int

        class X(metaclass=Meta):
            pass

        class Y(metaclass=Meta):
            b: float

        self.assertEqual(get_annotations(Meta), {"a": int})
        self.assertEqual(get_annotate_function(Meta)(Format.VALUE), {"a": int})

        self.assertEqual(get_annotations(X), {})
        self.assertIs(get_annotate_function(X), None)

        self.assertEqual(get_annotations(Y), {"b": float})
        self.assertEqual(get_annotate_function(Y)(Format.VALUE), {"b": float})

    def test_unannotated_meta(self):
        class Meta(type):
            pass

        class X(metaclass=Meta):
            a: str

        class Y(X):
            pass

        self.assertEqual(get_annotations(Meta), {})
        self.assertIs(get_annotate_function(Meta), None)

        self.assertEqual(get_annotations(Y), {})
        self.assertIs(get_annotate_function(Y), None)

        self.assertEqual(get_annotations(X), {"a": str})
        self.assertEqual(get_annotate_function(X)(Format.VALUE), {"a": str})

    def test_ordering(self):
        # Based on a sample by David Ellis
        # https://discuss.python.org/t/pep-749-implementing-pep-649/54974/38

        def make_classes():
            class Meta(type):
                a: int
                expected_annotations = {"a": int}

            class A(type, metaclass=Meta):
                b: float
                expected_annotations = {"b": float}

            class B(metaclass=A):
                c: str
                expected_annotations = {"c": str}

            class C(B):
                expected_annotations = {}

            class D(metaclass=Meta):
                expected_annotations = {}

            return Meta, A, B, C, D

        classes = make_classes()
        class_count = len(classes)
        for order in itertools.permutations(range(class_count), class_count):
            names = ", ".join(classes[i].__name__ for i in order)
            with self.subTest(names=names):
                classes = make_classes()  # Regenerate classes
                for i in order:
                    get_annotations(classes[i])
                for c in classes:
                    with self.subTest(c=c):
                        self.assertEqual(get_annotations(c), c.expected_annotations)
                        annotate_func = get_annotate_function(c)
                        if c.expected_annotations:
                            self.assertEqual(
                                annotate_func(Format.VALUE), c.expected_annotations
                            )
                        else:
                            self.assertIs(annotate_func, None)


class TestAnnotationLib(unittest.TestCase):
    def test__all__(self):
        support.check__all__(self, annotationlib)
