[issue33453] from __future__ import annotations breaks dataclasses ClassVar and InitVar handling

Łukasz Langa report at bugs.python.org
Wed May 9 23:07:34 EDT 2018


Łukasz Langa <lukasz at langa.pl> added the comment:

Well, this is a rather big deal and I'd like to see it solved for 3.7.0. Ned, this is after the last beta but as far as I understand, we're still 



Note that this isn't specific to the `annotations` future import. If a user actually writes:

  field: "ClassVar[SomeTypeReferencedLater]" = get_some_type_object()

the effect is the same.


There are two ways to solve it, the right way and the fast way.

The right way is to call `get_type_hints()` on the class which forces evaluation of all type annotations (including in base classes, if any). That way you can keep using your existing hack to check if a thing is a ClassVar. However, it's slow because it:

- forces evaluation of all type annotations at import time, which is even slower than without the `annotations` future import because now you're tokenizing, creating the AST and the code objects, too; and

- you force an import of typing for all users, regardless whether they use any annotations or not.


This is why attrs went with the fast way which covers most (but not all) bases in this case. If the annotation is a string, just check if it starts with "typing.ClassVar", "t.ClassVar", or just "ClassVar". That's a fast check and doesn't ever require importing typing.  On the flip side, the 0.001% of users [1]_ who import ClassVar differently, will not have their class variables recognized.

So, Eric, unless you really want to do the right thing here and make dataclasses forever slower to start up than attrs, I would be happy to provide you with a patch for this during sprints.



[1] .. Figure made up on the spot.

----------
nosy: +ned.deily

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue33453>
_______________________________________


More information about the Python-bugs-list mailing list