[Python-Dev] Postponed annotations break inspection of dataclasses (original) (raw)
Eric V. Smith eric at trueblade.com
Sat Sep 22 14:29:21 EDT 2018
- Previous message (by thread): [Python-Dev] Postponed annotations break inspection of dataclasses
- Next message (by thread): [Python-Dev] Postponed annotations break inspection of dataclasses
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 9/22/2018 12:41 PM, Guido van Rossum wrote:
This is a good catch -- thanks for bringing it up. I'm adding Eric Smith (author of dataclasses) and Ivan Levkivskyi (co-author of typing) as well as Łukasz Langa (author of PEP 563) to the thread to see if they have further insights.
I don't see Ivan and Łukasz cc'd, so I'm adding them here.
Personally I don't think it's feasible to change PEP 563 to use lambdas (if it were even advisable, which would be a long discussion), but I do think we might be able to make small improvements to the dataclasses and/or typing modules to make sure your use case works.
Probably a bugs.python.org <http://bugs.python.org> issue is a better place to dive into the details than python-dev.
Agreed that opening a bug would be good.
And then I'll ruin that suggestion by answering here, too:
I think this problem is endemic to get_type_hints(). I've never understood how you're supposed to use the globals and locals arguments to it, but this works:
print(get_type_hints(Bar.init, globals()))
as does:
print(get_type_hints(Bar.init, Bar.module))
But that seems like you'd have to know a lot about how a class were declared in order to call get_type_hints on it. I'm not sure module is always correct (but again, I haven't really thought about it).
The docs for get_type_hints() says: "In addition, forward references encoded as string literals are handled by evaluating them in globals and locals namespaces."
Every once in a while someone will bring up the idea of delayed evaluation, and the answer is always "use a lambda". If we ever wanted to do something more with delayed evaluation, this is a good use case for it.
Eric
Thanks again, --Guido (top-poster in chief) On Sat, Sep 22, 2018 at 8:32 AM David Hagen <david at drhagen.com_ _<mailto:david at drhagen.com>> wrote: 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 gettypehints_ _class Foo:_ _pass_ _@dataclass_ _class Bar:_ _foo: Foo_ _print(gettypehints(Bar._init_))_ _
In Python 3.6 and 3.7, this does what is expected; it prints{'foo': <class '_main_.Foo'>, 'return': <class 'NoneType'>}
. However, if in Python 3.7, I addfrom _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 thedataclasses
module which does not have theFoo
object in its environment, and theFoo
annotation is being passed todataclass
and attached to_init_
as the string"Foo"
rather than as the original objectFoo
, butgettypehints
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 at python.org <mailto:Python-Dev at python.org> https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (python.org/~guido <http://python.org/%7Eguido>)
Python-Dev mailing list Python-Dev at python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/eric%2Ba-python-dev%40trueblade.com
- Previous message (by thread): [Python-Dev] Postponed annotations break inspection of dataclasses
- Next message (by thread): [Python-Dev] Postponed annotations break inspection of dataclasses
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]