Ken Jin <kenjin4...@gmail.com> added the comment:
@larry > Is this "surprising, but required" behavior due specifically to this being a > backwards-incompatible change? Yes. That's the main factor. I've since learnt that there's sadly more to it though :( (see below). > Does that mean I don't have the problem you're solving by reversing the order > of namespace lookup, and I can just pass globals and locals in like normal? I think it depends on the ergonomics of the function you're trying to achieve. I admit I haven't been fully keeping up with the inspect.get_annotations issue (sorry!), but here's what I learnt from get_type_hints: (Partly copied over from PR 25632) Example: from typing import TypeVar, Generic T = TypeVar('T') class A(Generic[T]): __annotations__ = dict( some_b='B' ) class B(Generic[T]): class A(Generic[T]): pass __annotations__ = dict( my_inner_a1='B.A', my_inner_a2=A, my_outer_a='A' # unless somebody calls get_type_hints with localns=B.__dict__ ) >>> get_type_hints(B) Currently (globalns then localns): {'my_inner_a1': <class '__main__.B.A'>, 'my_inner_a2': <class '__main__.B.A'>, 'my_outer_a': <class '__main__.A'>} Swapped (localns then globalns): {'my_inner_a1': <class '__main__.B.A'>, 'my_inner_a2': <class '__main__.B.A'>, 'my_outer_a': <class '__main__.B.A'>} I realized that looking into globalns then localns is a necessary evil: doing the converse (looking into localns first then globalns) would mean there is no way to point to the shadowed global `A`: it would always point to the local `B.A`. Unless of course you pass in localns=module.__dict__ or localns=globals(). Ultimately I think it's a sacrifice of ergonomics either way; looking into localns then globalns will require passing in the module's __dict__ to refer to a global being shadowed, while the converse (globalns then localns) introduces surprising eval behavior. Both are kind of tacky, but globalns then localns is slightly less so IMO. If the user wants to specify the inner class, they can just annotate 'B.A', if they want the outer, it's 'A'. But the localns then globalns approach will always point to `B.A`, the only way to access the shadowed global `A` is to pass in the strange looking argument localns=module.__dict__. Phew, my head's spinning with localns and globalns now. Thanks for reading! I think it's your call. I'm inexperienced with elegant function design :P. ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue42904> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com