On 4/17/2021 6:44 PM, Christopher Barker wrote:
On Sat, Apr 17, 2021 at 6:12 AM Eric V. Smith <eric@trueblade.com> wrote:
I wonder if anyone has considered the impact of PEP 563 on dataclasses ?
I have!

Thanks Eric. 
 
In retrospect, that field probably should have been named "annotation". Regardless, the intent was always "store what's in __annotations__[field_name]", or what the user specified in field(..., type=whatever, ...).

intent is all well and good, but what was the intent of __annotations__ In the first place. Static typing was certainly one of the intents, but as it DID store a value, not a string from the beginning, we can only assume that there was some intent that the value might be used.
Yes, but wouldn't that say that PEP 563 could never be implemented then, since it would break that intent? We already knew it broke all code that was expecting a type object in __annotations__. I'm just saying my expectation is 563 will break any code expecting a type object in __annotations__, or anything that's derived from __annotations__ (specifically in my case, dataclass users looking at Field.type). My probably unarticulated intent was that Field.type agree with __annotations__[field_name].

As for dataclasses -- why store it at all? It seems that dataclasses use the fact that a class attribute has an annotation to determine what to add to the field -- which is a nifty use of teh syntax. But presumably the intent of storing the annotation in the Field object, and providing a public attribute for it, was so that it could be used.

I didn't want to predict what someone was using dataclasses for. Especially someone using field(..., metadata=something) might want access to any of the field() values, including .type. I supposed I could have said "for defaults, default_factory, repr, etc., look at the Field object, but for the type look at __annotations__[field_name]", but I decided it would be easier if everything about a field would be in the Field object. Not that it makes much difference: I believe that Field.type always agrees with __annotations__[field_name].

This allows someone to say (where some_dataclass_field_object is a Field):

process_field(some_dataclass_field_object)

instead of this, if the .type field weren't present:

process_field(some_dataclass_field_object, SomeDataclass.__annotations__[some_dataclass_field_object.name])


I suppose your point is that the type attribute stored the annotation, and PEP 653 changes what the annotation will be so there's nothing specific at all about dataclasses here. Which is true. But users of dataclasses may have been less aware of all the implications as they didn't write that annotation etrating code themselves. I know I wasn't.

In any event, all of this mess is one reason I'd like to see PEP 649 get accepted: 

Indeed -- that is the title of this thread, after all :-)

Well, not everyone is not in support of the subject!

Eric


And see others' notes, there seems to be two other places in the stdlib that will be affected.

-CHB


--
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
-- 
Eric V. Smith