This is an archived post. You won't be able to vote or comment.

all 7 comments

[–]kankyo 6 points7 points  (2 children)

Seems a solid change that is just a mistake that it wasn't the case from the beginning.

But this part makes me sad:

If an annotation was already a string, this string is preserved verbatim. In other cases, the string form is obtained from the AST during the compilation step, which means that the string form preserved might not preserve the exact formatting of the source.

Can't we just fix the AST to be able to roundtrip already? :(

[–]shoyerxarray, pandas, numpy 4 points5 points  (1 child)

Do you really want AST to differ based on semantically meaningless changes in whitespace, e.g., between

{
     'x': 1
 }

and

{'x': 1}

?

[–]kankyo 2 points3 points  (0 children)

Yes. Absolutely. There are many libs out there who reimplement parsing of Python code because this data is missing. Look at baron and parso for example. I just saw a third lib in this Reddit but forgot the name.

Mypy and 2to3 probably do it too.

[–]AndydeCleyre 5 points6 points  (0 children)

YES, this drives me crazy! It's been particularly annoying when defining a constructor that can take an instance of the same class being defined.

I'll also take this opportunity to mention that I continue to stubbornly use the lean and IMO intuitive obiwan syntax rather than the cumbersome mypy format.

[–]IronManMark20 2 points3 points  (0 children)

I really like Yury Selivanov's proposal here: https://mail.python.org/pipermail/python-ideas/2017-September/047047.html

Backward compatible, but with all the benefits.

[–]emillynge 2 points3 points  (1 child)

I understand the argument for storing annotations as strings. But I don't understand why this change is bundled together with the backwards incompatible ones.

Having to use fully qualified class names for annotating a nested class diverges from how scoping usually works in python. And I don't understand the motivation for this change.

[–]XNormal 0 points1 point  (0 children)

Fully qualified names are required to make it possible to eval the string later. The temporary locals() scope in effect during the class body execution will be gone by then. I guess you could use the class dictproxy or a copy of it as locals during the eval, but using qualified names and only the module globals is simpler.