1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
from __future__ import annotations
from typing import Callable, Unpack
class A[T, *Ts, **P]:
x: T
y: tuple[*Ts]
z: Callable[P, str]
class B[T, *Ts, **P]:
T = int
Ts = str
P = bytes
x: T
y: Ts
z: P
Eggs = int
Spam = str
class C[Eggs, **Spam]:
x: Eggs
y: Spam
def generic_function[T, *Ts, **P](
x: T, *y: Unpack[Ts], z: P.args, zz: P.kwargs
) -> None: ...
def generic_function_2[Eggs, **Spam](x: Eggs, y: Spam): pass
class D:
Foo = int
Bar = str
def generic_method[Foo, **Bar](
self, x: Foo, y: Bar
) -> None: ...
def generic_method_2[Eggs, **Spam](self, x: Eggs, y: Spam): pass
# Eggs is `int` in globals, a TypeVar in type_params, and `str` in locals:
class E[Eggs]:
Eggs = str
x: Eggs
def nested():
from types import SimpleNamespace
from inspect import get_annotations
Eggs = bytes
Spam = memoryview
class F[Eggs, **Spam]:
x: Eggs
y: Spam
def generic_method[Eggs, **Spam](self, x: Eggs, y: Spam): pass
def generic_function[Eggs, **Spam](x: Eggs, y: Spam): pass
# Eggs is `int` in globals, `bytes` in the function scope,
# a TypeVar in the type_params, and `str` in locals:
class G[Eggs]:
Eggs = str
x: Eggs
return SimpleNamespace(
F=F,
F_annotations=get_annotations(F, eval_str=True),
F_meth_annotations=get_annotations(F.generic_method, eval_str=True),
G_annotations=get_annotations(G, eval_str=True),
generic_func=generic_function,
generic_func_annotations=get_annotations(generic_function, eval_str=True)
)
|