[Python-Dev] Second post: PEP 557, Data Classes

Eric V. Smith eric at trueblade.com
Tue Nov 28 13:31:39 EST 2017


On 11/28/17 7:02 AM, Nick Coghlan wrote:
> On 28 November 2017 at 17:41, Eric V. Smith <eric at trueblade.com> wrote:
>> One thing this doesn't let you do is compare instances of two different
>> subclasses of a base type:
>>
>> @dataclass
>> class B:
>>     i: int
>>
>> @dataclass
>> class C1(B): pass
>>
>> @dataclass
>> class C2(B): pass
>>
>> You can't compare C1(0) and C2(0), because neither one is an instance of the
>> other's type. The test to get this case to work would be expensive: find the
>> common ancestor, and then make sure no fields have been added since then.
>> And I haven't thought through multiple inheritance.
>>
>> I suggest we don't try to support this case.
>
> That gets you onto problematic ground as far as transitivity is
> concerned, since you'd end up with the following:

Excellent point, thanks for raising it.

>     >>> b = B(0); c1 = C1(0); c2 = C2(0)
>     >>> c1 == b
>     True
>     >>> b == c2
>     True
>     >>> c1 == c2
>     False
>
> However, I think you can fix this by injecting the first base in the
> MRO that defines a data field as a "__field_layout__" class attribute,
> and then have the comparison methods check for "other.__field_layout__
> is self.__field_layout__", rather than checking the runtime class
> directly.
>
> So in the above example, you would have:
>
>    >>> B.__field_layout__ is B
>    True
>    >>> C1.__field_layout__ is B
>    True
>    >>> C2.__field_layout__ is B
>    True
>
> It would then be up to the dataclass decorator to set
> `__field_layout__` correctly, using the follow rules:
>
> 1. Use the just-defined class if the class defines any fields
> 2. Use the just-defined class if it inherits from multiple base
> classes that define fields and don't already share an MRO
> 3. Use a base class if that's either the only base class that defines
> fields, or if all other base classes that define fields are already in
> the MRO of that base class

That seems like a lot of complication for a feature that will be rarely 
used. I'll give it some thought, especially the MI logic.

I think what you're laying out is an optimization for "do the classes 
have identical fields, inherited through a common base class or 
classes", right?

Eric.



More information about the Python-Dev mailing list