![](https://secure.gravatar.com/avatar/53c166c5e1f0eef9ff4eb4d0b6ec9371.jpg?s=120&d=mm&r=g)
On 1/11/21 1:16 PM, Larry Hastings wrote:
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.
Whoops! Let me walk that back a little. I'd been assuming that PEP 563 used the terms "annotations" and "type hints" to mean the exact same thing. But careful reading of PEP 484 suggests that they're distinct concepts; all "type hints" are annotations, but not all annotations are "type hints". So: if you're using annotations for something besides "type hints", such that you have a use for a non-None localns, I guess you have two options with my PEP: either a) use strings for your annotations where you need localns to work for you, or b) skip using annotations syntax and instead write your own custom __co_annotations__ function. Or, you could mix and match, using annotations syntax where it was convenient, and overriding only the troublesome spots in your custom __co_annotations__ function: def foo(a:int=3, b): ... foo_static_annotations = foo.__annotations__ def foo_dynamic_closure_annotations(): annotations = dict(foo_static_annotations) annotations['b'] = MyExcitingLocallyDefinedClosureTypeThing return annotations foo.__co_annotations = foo_dynamic_closure_annotations Cheers, //arry/