(original) (raw)



On Fri, Dec 29, 2017 at 2:45 AM, Antoine Pitrou <solipsis@pitrou.net> wrote:
On Fri, 29 Dec 2017 02:23:56 -0800
Ethan Smith <ethan@ethanhs.me> wrote:
\>
\> In a few cases I want to override the repr of the AST nodes. I wrote a
\> \_\_repr\_\_ and ran the code but lo and behold I got a type error. I couldn't
\> override it. I quickly learned that one needs to pass a keyword to the
\> dataclass decorator to tell it \*not\* to auto generate methods you override.
\>
\> I have two usability concerns with the current implementation. I emailed
\> Eric about the first, and he said I should ask for thoughts here. The
\> second I found after a couple of days sitting on this message.
\>
\> The first is that needing both a keyword and method is duplicative and
\> unnecessary. Eric agreed it was a hassle, but felt it was justified
\> considering someone may accidentally override a dataclass method. I
\> disagree with this point of view as dataclasses are billed as providing
\> automatic methods. Overriding via method definition is very natural and
\> idiomatic.

Agreed. We shouldn't take magic too far just for the sake of
protecting users against their own (alleged) mistakes. And I'm not
sure how you "accidentally" override a dataclass method (if I'm
implementing a \_\_repr\_\_ I'm doing so deliberately :-)).

My thinking exactly.

\> The second concern, which I came across more recently, is if I have a base
\> class, and dataclasses inherit from this base class, inherited \_\_repr\_\_ &
\> co are silently overridden by dataclass. This is both unexpected, and also
\> means I need to pass a repr=False to each subclass' decorator to get
\> correct behavior, which somewhat defeats the utility of subclassing. Im not
\> as sure a whole lot can be done about this though.

Agreed as well. If I make the effort of having a dataclass inherit
from a base class, I probably don't want the base class' methods to be
silently overriden by machine-generated methods. Of course, that can
be worked around by using multiple inheritance, you just need to be
careful and add a small amount of class definition boilerplate.

I am not sure exactly what you mean by "worked around by using multiple inheritance". Do you mean you think
the dataclass decorator should be made into a dataclass base class for a dataclass class, or that it should look
at the MRO?

I would expect dataclass parameters such as \`repr\` to be tri-state:

\* repr=None (the default): only provide a machine-generated
implementation if none is already defined (either on a base class or
in the dataclass namespace... ignoring runtime-provided defaults such
as object.\_\_repr\_\_)
\* repr=False: never provide a machine-generated implementation
\* repr=True: always provide a machine-generated implementation, even
overriding a previous user-defined implementation

This is sensible to me.


Thanks for your thoughts!

\~>Ethan Smith


Regards

Antoine.


\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/ethan%40ethanhs.me