I agree that adding a new lexical scope is fraught with problems. It mostly works, but there are enough problematic edge cases that I think it's not feasible. I've played with the idea of using an implicit `del`, but that doesn't work either. The problem is that TypeVars are often referenced inside a generic function body or the body of methods defined within a class. That means the TypeVar must have a lifetime that extends beyond the evaluation of the `def` or `class` statement. It needs to be part of the closure for inner scopes. I'm still optimistic that some solution exists here, but the scoping logic in the CPython compiler is quite baroque, and I'm still wrapping my head around it.
Hm, this is a big conundrum. The 'del' solution clearly doesn't work, and the same argument also means that just assigning typevars in the containing scope doesn't work either. And I think that the same argument *also* rules out the alternative (IIRC favored by Sebastian) of using a with-statement, since with-statements don't introduce scopes. In all cases, a runtime reference to a typevar from a function or method body could be overwritten by a later redefinition of the same type variable. (The current situation also has that problem, but it is solved by making typevars explicit globals.)
Maybe we need to adjust the scope rules so that we can introduce the extra scope holding the typevars without changing the semantics of assignment expressions (the walrus operator)? There's a precedent in PEP 572 (which introduces the walrus operator): a walrus in a comprehension never stores into the function scope used for the comprehension, it stores in the nearest containing "real" function scope. So we could change the rules so that a walrus in an annotation or a class definition argument still writes into the nearest containing explicit scope -- only the typevars are stored in the special scope introduced by the new syntax.