Agree that implementation I propose is trivial. I'm not sure what the benefit of overwriting a string literal in __annotations__ with the ForwardRef would be when it can be overwritten with the already evaluated value, hence why I was proposing the latter.
On Thu, 2020-12-10 at 23:00 -0800, Guido van Rossum wrote: > That looks like a two-line convenience function using no private > APIs, so you can easily include that in your own toolbox if you need > it. > > If your concern is that get_type_hints() is too slow, submit a PR > that makes it faster. There's a cache built into ForwardRef, but it > appears to be ineffective because a new ForwardRef instance is > created each time when get_type_hints() encounters a string value. > Maybe the ForwardRef instance should be stored back into > `__annotations__`? > > On Thu, Dec 10, 2020 at 10:43 PM Paul Bryan <pbr...@anode.ca> wrote: > > 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/ > >
_______________________________________________ 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/XULTMMAOQKQEOQRQTZBMIPDDUCNGHRNM/ Code of Conduct: http://python.org/psf/codeofconduct/