
Some more questions... "Binding"," bound" and "unbound" code objects: Is your use of "binding" terminology in the PEP identical to the binding of a function to an object instance as a method during object creation? Function Annotations:
When binding an unbound annotation code object, a function will use its own __globals__ as the new function's globals. I'm having trouble parsing this. Does this mean the newly bound __co_annotations__ function will inherit __globals__ from the function it's annotating?
Exceptions: It's quite possible for a __co_annotation__ function call to raise an exception (e.g. NameError). When accessing __annotations__, if such an exception is raised during the call to __co_annotations__, what is the expected behavior? s/__co_//?: I'm probably naive, but is there a reason that one could not just store a callable in __annotations__, and use the descriptor to resolve it to a dictionary and store it when it is accessed? It would be one less dunder in the Python data model. On Mon, 2021-01-11 at 15:46 -0800, Larry Hastings wrote:
On 1/11/21 3:02 PM, Paul Bryan wrote:
PEP 563 does go on to state:
For code which uses annotations for other purposes, a regular eval(ann, globals, locals) call is enough to resolve the annotation.
And I believe this would no longer be true under PEP 649; further, localns (and maybe globalns) parameters in get_type_hints would become meaningless.
[...] And, would get_type_hints continue evaluate [string] annotations in that case? I don't work on typing.get_type_hints() so someone else will have to answer this question. All I can say is, with PEP 649 semantics, if you set an annotation to a string, you'll get a string back. And in 3.9 (and my out-of-date 3.10) I observe that typing.get_type_hints() will eval() string annotations for you, and localns is significant.
This passage in PEP 563 appears not true in Python 3.9 with __future__ annotations, emphasis mine:
The get_type_hints() function automatically resolves the correct value of globalns for functions and classes. It also automatically provides the correct localns for classes.
If this passage was true, I believe the issue that resulted in my affixing type hints could have been averted. As you've discovered, this is one of the places where PEP 563 seems to be out-of-date with respect to its implementation. I sifted through the source code to typing.get_type_hints() twice, and near as I can figure out, localns is literally only ever set to None unless you override it with the parameter.
OK, would string representations of type hints continue be supported under PEP 649 if strings are used as annotations? PEP 649 is itself totally agnostic as to what value you use as an annotation. It disallows a couple funky things (yield, walrus operator), but beyond that it doesn't care. Any Python expression or value is fine.
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":
I wasn't thinking the function local state of that being annotated (agree, this would be prohibitive), but rather the scope in which the annotated function, class, module, etc. are being defined.
That's what PEP 563 is referring to. If you read the thread from November 2017 where the idea was discussed, they were talking about referring to e.g. "class-level definitions", as in, things defined inside class scope. Which is prohibitive. (If I understand you correctly, you thought it was referring to the scope inside the function when it runs? Because I can't imagine how that would ever work. What if the function hasn't been called yet? What if it's been called a thousand times? What if it's running right now in various stages of completeness in five threads and you inspect the annotation from a sixth thread?)
Cheers,
/arry