Thanks -- good to get this written down!
Question: it strikes me that the use case of  for type hints is logically quite different than for indexing. So do they need to use the same syntax / dunder?
How would we differentiate what the caller means by the subscript invocation?
Put another way: would the distinction be:
A) between 1. objects of the type `type` (class objects), and 2. non-type objects...?
B) between WHERE the innovation occurs in the code?
To explain further, A) looks like:
...because dict is a class object, but:
d = dict(0
x, y ) )
...because d is not a class object?
Or B), so that for either of these:
d: dict[x, y]
def f() -> dict[
...the type checker calls (no effect at runtime):
...but this would still call __getitem__ at runtime:
class C: ...
x, y ]
...because the C[x,y] invocation occurs outside of a type hint location...?
B) at least seems like it isn't an option, since it's probably impossible to determine what things are type hints and what things aren't simply based on where they appear in code:
>>> MyType = C[x,y] # this will be a type hint
>>> my_value = C[x,y] # looking up a key on object C
"I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler