[Python-Dev] Postponed annotations break inspection of dataclasses
The new postponed annotations have an unexpected interaction with dataclasses. Namely, you cannot get the type hints of any of the data classes methods. For example, I have some code that inspects the type parameters of a class's `__init__` method. (The real use case is to provide a default serializer for the class, but that is not important here.) ``` from dataclasses import dataclass from typing import get_type_hints class Foo: pass @dataclass class Bar: foo: Foo print(get_type_hints(Bar.__init__)) ``` In Python 3.6 and 3.7, this does what is expected; it prints `{'foo': , 'return': }`. However, if in Python 3.7, I add `from __future__ import annotations`, then this fails with an error: ``` NameError: name 'Foo' is not defined ``` I know why this is happening. The `__init__` method is defined in the `dataclasses` module which does not have the `Foo` object in its environment, and the `Foo` annotation is being passed to `dataclass` and attached to `__init__` as the string `"Foo"` rather than as the original object `Foo`, but `get_type_hints` for the new annotations only does a name lookup in the module where `__init__` is defined not where the annotation is defined. I know that the use of lambdas to implement PEP 563 was rejected for performance reasons. I could be wrong, but I think this was motivated by variable annotations because the lambda would have to be constructed each time the function body ran. I was wondering if I could motivate storing the annotations as lambdas in class bodies and function signatures, in which the environment is already being captured and is code that usually only runs once. ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Postponed annotations break inspection of dataclasses
On Sat, Sep 22, 2018 at 3:11 PM Guido van Rossum wrote: > Still, I wonder if there's a tweak possible of the globals and locals used when exec()'ing the function definitions in dataclasses.py, so that get_type_hints() gets the right globals for this use case. On Sat, Sep 22, 2018 at 4:38 PM Yury Selivanov wrote: > If it's possible to fix exec() to accept any Mapping (not just dicts), > then we can create a proxy mapping for "Dataclass.__init__.__module__" > module and everything would work as expected. Another possible solution is that `__annotations__` are *permitted* to be lambdas, but not created as such by default, and `get_type_hints` is aware of this. Operations that are known to break type hints (such as when data classes copy the type hints from the class body to the `__init__` method) could covert the type hint from a string to a lambda before moving it. It does not even have to be a lambda; an instance of some `TypeHint` class, which stores the string and pointers to the original `globals` and `locals` (or just the original object whose `globals` and `locals` are relevant), but that's essentially what a lambda is anyway. ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Postponed annotations break inspection of dataclasses
On Sat, Sep 22, 2018 at 12:41 PM Guido van Rossum wrote: > Probably a bugs.python.org issue is a better place to dive into the details than python-dev. Issue tracker issue created: https://bugs.python.org/issue34776 ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com