> Here we want to know what the 'C' refers to in g's annotations. But g's closures are no help (unless g's body were to also reference C, which is not likely in typical code).
I understand the limitation. I was proposing changing https://github.com/python/cpython/blob/3.9/Lib/typing.py#L1431-L1433 to use the `nonlocal_vars` instead of `globalns` for the default localns (or possibly a chainmap of the two). I agree that it may only work on a small fraction of code but the performance cost seems pretty minimal especially for a function like `get_type_hints`, so why not? But I trust judgement, if you think that creating an apparent inconsistency around when `get_type_hints` will work and when it won't is not worth being able to resolve a few extra cases it probably isn't. - Caleb Donovick On Wed, Feb 3, 2021 at 8:55 AM Guido van Rossum <gu...@python.org> wrote: > Sadly this won't work, because the annotations are "evaluated" (or not) in > the surrounding scope, not in the function's scope. Example: > ``` > >>> def f(a: int): > ... class C: pass > ... def g(b: C): pass > ... return g > ... > >>> g = f(1) > >>> g.__annotations__ > {'b': 'C'} > >>> g.__closure__ > >>> > ``` > Here we want to know what the 'C' refers to in g's annotations. But g's > closures are no help (unless g's body were to also reference C, which is > not likely in typical code). > > --Guido > > On Tue, Feb 2, 2021 at 6:10 PM Caleb Donovick <donov...@cs.stanford.edu> > wrote: > >> The discussion around PEP 649 got me thinking about what I believe is the >> largest downside to PEP 563: the inability to evaluate annotations created >> with closures. While this is in general unavoidable, if the type is ever >> referenced in an annotated function (including as an annotation) it should >> be resolvable via `__closure__`. >> >> For example: >> ``` >> from __future__ import annotations >> import typing >> def gen(T): >> def f(x: T): >> y: T = ... >> return f >> >> f = gen(int) >> nonlocal_vars = { >> var : cell.cell_contents >> for var, cell in zip(f.__code__.co_freevars, f.__closure__) >> } >> assert typing.get_type_hints(f, localns=nonlocal_vars) == {'x': int} >> ``` >> >> I would just open a PR to have `get_type_hints` attempt to resolve >> closure variables by default. However, this would require an update to PEP >> 563 and I don't know what the protocol is there. >> >> - Caleb Donovick >> _______________________________________________ >> Python-Dev mailing list -- python-dev@python.org >> To unsubscribe send an email to python-dev-le...@python.org >> https://mail.python.org/mailman3/lists/python-dev.python.org/ >> Message archived at >> https://mail.python.org/archives/list/python-dev@python.org/message/L2XH2EIFCEPT5DQRPRFR6WYEM6M2LM2V/ >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > > > -- > --Guido van Rossum (python.org/~guido) > *Pronouns: he/him **(why is my pronoun here?)* > <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> >
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/T7AYBEUPKPZ7QLI3WRPLMSBU6BPPHOMQ/ Code of Conduct: http://python.org/psf/codeofconduct/