
Thanks for your feedback! I'll reply piecemeal. On 1/11/21 12:32 PM, Paul Bryan wrote:
*1. Backwards Compatibility*
PEP 563 <https://www.python.org/dev/peps/pep-0563> changed the semantics of annotations. When its semantics are active, annotations must assume they will be evaluated in /module-level/ scope. They may no longer refer directly to local variables or class attributes.
Given get_type_hints can be provided localns argument, this statement is not exactly true.
PEP 563 states: For code that uses type hints, the typing.get_type_hints(obj, globalns=None, localns=None) function correctly evaluates expressions back from its string form. So, if you are passing in a localns argument that isn't None, okay, but you're not using them "correctly" according to the language. Also, this usage won't be compatible with static type checkers.
Under PEP 649, when __co_annotations__ is called (presumably by calling get_type_hints), would localns effectively be ignored?
Yes. You can experiment with this in Python 3.9--just turn off annotation stringizing. It seems that you can still use strings as annotations and typing.get_type_hints() will evaluate them--and I assume it'll use localns at that point, just as it does today.
*2. __co_annotations__ scope?*
I'm wondering why __co_annotations__ function could not be scoped (within a closure?) such that it can access the values where the function, method, class or module are being declared? I acknowledge that I'm railing against PEP 563 again, trying to reclaim lost ground.
This is addressed in PEP 563, when it rejected the idea of using "function local state when defining annotations": This would be prohibitively expensive for highly annotated code as the frames would keep all their objects alive. That includes predominantly objects that won't ever be accessed again. https://www.python.org/dev/peps/pep-0563/#keeping-the-ability-to-use-functio... Doing this automatically would indeed incur a sizeable runtime cost, for a feature that is already rarely used at runtime. I guess it would be remotely possible? to add this as an optional feature? But this gets crazy quickly--what if it's defined inside a function inside another function inside a class inside another function?--and the use cases seem few, and TOOWTDI. I've never understood how closures work in Python, so I'm not the guy to ask how possible / hard this would be. Then again, the implementation of closures is obscure enough that I've never been able to understand them, so that seems to establish at least a base level of difficulty. Anyway, one of the concepts my PEP is built on is that "annotations are always evaluated at module-level scope". I'd be against changing that unless it could be achieved without runtime cost--which AFAIK is impossible. Cheers, //arry/