On Wed, Jan 22, 2020 at 9:17 AM Andrew Barnert <abarn...@yahoo.com> wrote: > > On Jan 21, 2020, at 12:29, Chris Angelico <ros...@gmail.com> wrote: > > > > For non-dataclass classes, it would be extremely helpful to have an > > easy helper function available: > > > > class Spam: > > def __repr__(self): > > return reprlib.kwargs(self, ["quality", "recipe", "ham"]) > > > > The implementation for this function would be very similar to what > > dataclasses already do: > > > > # in reprlib.py > > def kwargs(obj, attrs): > > attrs = [f"{a}={getattr(obj, a)!r}" for a in attrs] > > return f"{obj.__class__.__qualname__}({", ".join(attrs)})" > > > > A similar function for positional args would be equally easy. > > I like this, but I think it’s still more complex than it needs to be for 80% > of the cases (see below)
IMO that's not a problem. The implementation of reprlib.kwargs() is allowed to be complex, since it's buried away as, well, implementation details. As long as it's easy to call, that's all that matters. > while for the other 20%, I think it might make it too easy to get things > wrong. Hmm. I kept it completely explicit - it will generate a repr that shows the exact attributes listed (and personally, I'd often write it as "quality recipe ham".split()), and left the idea of automatic detection as a bikesheddable option. > > Bikeshedding opportunity: Should it be legal to omit the attrs > > parameter, and have it use __slots__ or fall back to dir(obj) ? > > This makes things even more dangerous. It’s very common for classes to have > attributes that aren’t part of the constructor call, or constructor params > that aren’t attributes, and this would give you the wrong answer. > > It would be nice if there were a safe way to get the constructor-call-style > repr. And I think there might be for 80% of the types—and the rest can > specify it manually and take the risk of getting it wrong, probably. > > One option is the pickle/copy protocol. If the type uses one of the newargs > methods, you can use that to get the constructor arguments; if it uses one of > the other pickling methods (or can’t be pickled), this just doesn’t work. > > You could also look at the inspect.signature of __init__ and/or __new__. If > every param has an attribute with the same name, use that; otherwise, this > doesn’t work. > > And if none of the automatic ways worked and you tried to use them anyway, > you get an error. This is definitely getting into the realm of magic. The question is, is it worth the convenience? I'd be +0.25 for the magic. Also, that can always be added in the future. If the explicit-list-of-attributes form is useful but too fiddly, it would be possible to add a stated default of "figure it out by magic", and then the exact magic can be redefined at will. > But it would be nice if this error were at class-defining time rather than at > repr-calling time, so maybe a decorator is actually a better solution? > > @reprlib.defaultrepr > class Spam: > Also a definite possibility. ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/V4NAISJVOCEQFGH4ZDZTQGUR7B4Q7W5M/ Code of Conduct: http://python.org/psf/codeofconduct/