With PEP 563 behavior going mainstream in Python 3.10, I see some ramifications, especially for runtime validation of type hints:
1. PEP 563 is changing the scope of evaluation of type hints, and in some cases it is not feasible to move that scope to the annotated object's globals. (I appreciate the reality that such cases would evade static type checkers.) 2. The typing.get_type_hints function causes annotation(s) to be evaluated from strings for every call, incurring a potentially significant runtime penalty depending on how often type hints are evaluated at runtime. To address both of these issues, I'm proposing that a new function be added to typing: affix_type_hints. I'm thinking something like this: def affix_type_hints(obj, globalns=None, localns=None): """ Affixes an object's type hints to the object. Type hints are affixed by first being resolved through get_type_hints, then by storing the result in the object's __annotations__ attribute. If the object is a class, this function will affix annotations from all superclasses. """ if hints := typing.get_type_hints(obj, globalns, localns, include_extras=True): obj.__annotations__ = hints Advantages: 1. The time and scope of type hint affixation are under the control of the caller. Future references can be realized before type hints are affixed. If there is a novel local scope required to resolve the type hint, it can be supplied in-context; future calls to get_type_hints inherit the benefit of such pre-resolution. 2. Annotations will not be re-evaluated on repeated calls to get_type_hints. 3. It doesn't require a change to the behavior of the get_type_hints function. Disadvantages: 1. Subclasses inheriting superclass annotations may be undesirable. 2. Monkey-patching __annotations__ may be considered an anti-pattern. 3. Maybe allowing re-evaluation on every get_type_hints call is desirable? (I'd rather avoid the potential for side-effects.) 4. The cited example is a 2-line function; perhaps its triviality makes it unjustified to add to the stdlib. Alternatives: 1. A caching version of get_type_hints. It looks like ForwardRef.__forward_value__ could actually deliver if annotations were encoded as ForwardRef objects instead of string literals. Am I missing a way for ForwardRef to cache evaluated values when get_type_hints is called? 2. Something I haven't considered? Please let me know. Paul
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/GZ7QGEABF624C6SKHUG7CWQAJ3XTJLIO/ Code of Conduct: http://python.org/psf/codeofconduct/