On Fri, 29 Dec 2017 02:23:56 -0800
Ethan Smith <et...@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 :-)).
> 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 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
Regards
Antoine.
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
On 12/29/2017 02:23 AM, Ethan Smith wrote:
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. I don't really see how someone could accidentally override a dataclass method if methods were not generated
by the dataclass decorator that are already defined in the class at definition time.
Accidental or not, the decorator should not be replacing methods defined by the class.
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.
It is possible to determine whether an existing __repr__ is from 'object' or not, and only provide one if that is the case. I think that should be the default, with 'repr = True' for those cases where a new, auto-generated, __repr__ is desired.
--
~Ethan~
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
I still think it should overrides anything that's just inherited but nothing that's defined in the class being decorated.
On Dec 29, 2017 5:43 PM, "Nathaniel Smith" <n...@pobox.com> wrote:On Fri, Dec 29, 2017 at 12:30 PM, Ethan Furman <et...@stoneleaf.us> wrote:
> Good point. So auto-generate a new __repr__ if:
>
> - one is not provided, and
> - existing __repr__ is either:
> - object.__repr__, or
> - a previous dataclass __repr__
>
> And if the auto default doesn't work for one's use-case, use the keyword
> parameter to specify what you want.
What does attrs do here?
-n
--
Nathaniel J. Smith -- https://vorpus.org
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/guido%40python.org
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
On Fri, Dec 29, 2017 at 4:52 PM, Guido van Rossum <gu...@python.org> wrote:I still think it should overrides anything that's just inherited but nothing that's defined in the class being decorated.Could you explain why you are of this opinion? Is it a concern about complexity of implementation?
--
Eric.
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/eric%2Ba-python-dev%40trueblade.com
Just use the simple rule that a new
__repr__ is generated unless provided in the dataclass.
dataclasses from dataclasses
On Sat, Dec 30, 2017 at 7:27 AM, Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:Just use the simple rule that a new
__repr__ is generated unless provided in the dataclass.are we only talking about __repr__ here ???I interpretted Guido's proposal as being about all methods -- we _may_ want something special for __repr__, but I hope not.But +1 for Guido's proposal, not only because it's easy to explain, but because it more naturally follows the usual inheritance logic:The decorator's entire point is to auto-generate boilerplate code for you. Once it's done that it shouldn't, in the end, behave any differently than if you hand wrote that code. If you hand wrote the methods that the decorator creates for you, they would override any base class versions. So that's what it should do.And the fact that you can optionally tell it not to in some particular case keeps full flexibility.-CHB
> I grant that there may be many reasons why one would be derivingdataclasses from dataclassesWill you get the "right" __repr__ now if you derive a datacalss from a dataclass? That would be a nice feature.
---CHB
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris....@noaa.gov
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
Will you get the "right" __repr__ now if you derive a datacalss from a dataclass? That would be a nice feature.The __repr__ will be generated by the child dataclass unless the user overrides it. So I believe this is the "right" __repr__.
~>Ethan Smith---CHB
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris....@noaa.gov
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/ethan%40ethanhs.me
On Mon, Jan 1, 2018 at 5:03 PM, Chris Barker <chris....@noaa.gov> wrote:
On Sat, Dec 30, 2017 at 7:27 AM, Stephen J. Turnbull <turnbull....@u.tsukuba.ac.jp> wrote:
Just use the simple rule that a new
__repr__ is generated unless provided in the dataclass.are we only talking about __repr__ here ???
I interpreted Guido's proposal as being about all methods -- we _may_ want something special for __repr__, but I hope not.
[...]
I interpreted this to be for all methods as well, which makes sense. Special casing just __repr__ doesn't make sense to me, but I will wait for Guido to clarify.
On Mon, Jan 1, 2018 at 7:50 PM, Ethan Smith <et...@ethanhs.me> wrote:
Will you get the "right" __repr__ now if you derive a dataclass from a dataclass? That would be a nice feature.
The __repr__ will be generated by the child dataclass unless the user overrides it. So I believe this is the "right" __repr__.what I was wondering is if the child will know about all the fields in the parent -- so it could make a full __repr__.
--
Eric.
> _______________________________________________
> Python-Dev mailing list
> Pytho...@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/eric%2Ba-python-dev%40trueblade.com
I think that's covered in this section:
https://www.python.org/dev/peps/pep-0557/#inheritance
Eric.
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/dev-python%2Bgarchive-30976%40googlegroups.com
On 1/2/2018 12:01 AM, Guido van Rossum wrote:Yes, there's a class variable (__dataclass_fields__) that identifies the parent fields. The PEP doesn't mention this or the fact that special methods (like __repr__ and __init__) can tell whether a base class is a dataclass. It probably should though. (@Eric)
I think that's covered in this section: https://www.python.org/dev/peps/pep-0557/#inheritance
I'm trying to track down the original discussion. We got bogged down on
whether it worked for classes or instances or both, then we got tied up
in naming it (surprise!), then it looks like we decided to just not
include it since you could make those decisions for yourself.
I think the discussion is buried in this thread:
https://mail.python.org/pipermail/python-dev/2017-November/150966.html
Which references:
https://github.com/ericvsmith/dataclasses/issues/99
So, ignoring the naming issue, I think if we want to revive it, the
question is: should isdataclass() return True on just instances, just
classes, or both? And should it ever raise an exception, or just return
False?
> I still worry a bit about ClassVar and InitVar being potentially useful
> but I concede I have no use case so I'll drop it.
IIRC, we decided that we could add a parameter to dataclasses.fields()
if we ever wanted to return pseudo-fields. But no one came up with a use
case.
Eric.
>
> On Fri, Jan 5, 2018 at 8:43 AM, Eric V. Smith <er...@trueblade.com
> <mailto:er...@trueblade.com>> wrote:
>
> On 1/5/2018 11:24 AM, Guido van Rossum wrote:
>
> On Fri, Jan 5, 2018 at 5:08 AM, Eric V. Smith
> <er...@trueblade.com <mailto:er...@trueblade.com>
> Pytho...@python.org <mailto:Pytho...@python.org>
> https://mail.python.org/mailman/listinfo/python-dev
> <https://mail.python.org/mailman/listinfo/python-dev>
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/guido%40python.org <https://mail.python.org/mailman/options/python-dev/guido%40python.org>
>
>
>
>
> --
> --Guido van Rossum (python.org/~guido <http://python.org/%7Eguido>)
>
>
> _______________________________________________
> Python-Dev mailing list
> Pytho...@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/eric%2Ba-python-dev%40trueblade.com
>
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/dev-python%2Bgarchive-30976%40googlegroups.com
Sounds good. I'll open a bpo issue.
Eric.
> <mailto:Pytho...@python.org <mailto:Pytho...@python.org>>
> https://mail.python.org/mailman/listinfo/python-dev
> <https://mail.python.org/mailman/listinfo/python-dev>
> <https://mail.python.org/mailman/listinfo/python-dev
> <https://mail.python.org/mailman/listinfo/python-dev>>
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/guido%40python.org
> <https://mail.python.org/mailman/options/python-dev/guido%40python.org>
> <https://mail.python.org/mailman/options/python-dev/guido%40python.org
> <https://mail.python.org/mailman/options/python-dev/guido%40python.org>>
>
>
>
>
> --
> --Guido van Rossum (python.org/~guido
> <http://python.org/%7Eguido> <http://python.org/%7Eguido>)
>
>
> _______________________________________________
> Python-Dev mailing list
> Pytho...@python.org <mailto:Pytho...@python.org>
> https://mail.python.org/mailman/listinfo/python-dev
> <https://mail.python.org/mailman/listinfo/python-dev>
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/eric%2Ba-python-dev%40trueblade.com
> <https://mail.python.org/mailman/options/python-dev/eric%2Ba-python-dev%40trueblade.com>
>
>
>
>
>
> --
> --Guido van Rossum (python.org/~guido <http://python.org/%7Eguido>)
_______________________________________________
Python-Dev mailing list
Pytho...@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/dev-python%2Bgarchive-30976%40googlegroups.com
https://bugs.python.org/issue32513
I need to think though how __eq__ and __ne__ work, as well as the
ordering operators.
My specific concern with __ne__ is that there's one flag to control
their generation, but python will use "not __eq__" if you don't provide
__ne__. I need to think through what happens if the user only provides
__eq__: does dataclasses do nothing, does it add __ne__, and how does
this interact with a base class that does provide __ne__.
Eric.
On 1/3/2018 1:17 PM, Eric V. Smith wrote:
I’ll open an issue after I have time to read this thread and comment on it.
https://bugs.python.org/issue32513
I need to think though how __eq__ and __ne__ work, as well as the ordering operators.
My specific concern with __ne__ is that there's one flag to control their generation, but python will use "not __eq__" if you don't provide __ne__. I need to think through what happens if the user only provides __eq__: does dataclasses do nothing, does it add __ne__, and how does this interact with a base class that does provide __ne__.
I've added my proposal on issue 32513:
https://bugs.python.org/issue32513#msg310392
It's long, so I won't repeat it here. The only really confusing part is
__hash__ and its interaction with __eq__.