Thanks for the tips, Daniel. Those were really helpful.
As Guido said, I don't think we can construct type variables at compile time because we need to evaluate bound expressions at runtime.
I incorporated your other suggestions, and this allowed me to eliminate the two pointers in the frame object! I still require a new pointer in the function object, but it's optional and will be NULL most of the time.
My latest implementation can be found here: https://github.com/erictraut/cpython/tree/type_param_syntax2
This implementation makes use of a local variable named "__type_variables__". This name will show up in the locals if you call "get_locals()", which is an unfortunate leakage of an implementation detail. I looked for ways to make this variable completely anonymous, but I didn't see a way of doing this without significant changes to the compiler. Of course, we could allocate a dedicated pointer within the frame like I was doing previously, but I was trying to avoid this.