Adding a Proxy type to typing/typing_extensions

I spent the weekend thinking about this, and overall I think I like this idea! I just want to clarify a little bit about how AttrSpec would/should work:

class MyProxy(Generic[A]):
    # is this right?
    def __getitem__(self, xyz: A.name) -> A.value: ...
    # or this
    def __getitem__(self, xyz: A.xyz) -> A.value: ...

    # what happens if you use A.name/A.value in non-dunder methods?
    # type error? Or do these just have to match the signature
    # of the method on A?
    def dtype(self) -> A.value: ...
    def compute_something(self, other: A.name) -> A.value: ...

I would also like to suggest maybe the ability to put a bound on the type of items that can be proxied - that would allow for type errors if you did something like:

class Foo: ...

A = AttrSpec("A", bound=Foo)
class FooProxy(Generic[A]):
    def __init__(self, proxy: A) -> None:
        self.proxied = proxy

    def __getattr__(self, name: A.name) -> A.value:
        # do some stuff assuming A is a subtype of Foo
        ...

FooProxy(3)  # type error

What do you think?