(original) (raw)

I think this is a good candidate for fine-tuning during the beta period.

Though honestly Python's own rules for when a class is hashable or not are the root cause for the complexity here -- since we decided to implicitly set \_\_hash\_\_ = None when you define \_\_eq\_\_, it's hardly surprising that dataclasses are having a hard time making natural rules.

On Sun, Jan 28, 2018 at 5:07 PM, Raymond Hettinger <raymond.hettinger@gmail.com> wrote:

\>>> 2) Change the default value for "hash" from "None" to "False". This might take a little effort because there is currently an oddity where setting hash=False causes it to be hashable. I'm pretty sure this wasn't intended ;-)
\>> I haven't looked at this yet.
\>
\> I think the hashing logic explained in https://bugs.python.org/issue32513#msg310830 is correct. It uses hash=None as the default, so that frozen=True objects are hashable, which they would not be if hash=False were the default.

Wouldn't it be simpler to make the options orthogonal? Frozen need not imply hashable. I would think if a user wants frozen and hashable, they could just write frozen=True and hashable=True. That would more explicit and clear than just having frozen=True imply that hashability gets turned-on implicitly whether you want it or not.

\> If there's some case there that you disagree with, I'd be interested in hearing about it.
\>
\> That logic is what is currently scheduled to go in to 3.7 beta 1\. I have not updated the PEP yet, mostly because it's so difficult to explain.

That might be a strong hint that this part of the API needs to be simplified :-)

"If the implementation is hard to explain, it's a bad idea." -- Zen

If for some reason, dataclasses really do need tri-state logic, it may be better off with enum values (NOT\_HASHABLE, VALUE\_HASHABLE, IDENTITY\_HASHABLE, HASHABLE\_IF\_FROZEN or some such) rather than with None, True, and False which don't communicate enough information to understand what the decorator is doing.

\> What's the case where setting hash=False causes it to be hashable? I don't think that was ever the case, and I hope it's not the case now.

Python 3.7.0a4+ (heads/master:631fd38dbf, Jan 28 2018, 16:20:11)
\[GCC 7.2.0\] on darwin
Type "copyright", "credits" or "license()" for more information.

\>>> from dataclasses import dataclass
\>>> @dataclass(hash=False)
class A:
x: int

\>>> hash(A(1))
285969507


I'm hoping that this part of the API gets thought through before it gets set in stone. Since dataclasses code never got a chance to live in the wild (on PyPI or some such), it behooves us to think through all the usability issues. To me at least, the tri-state hashability was entirely unexpected and hard to debug -- I had to do a close reading of the source to figure-out what was happening.


Raymond


\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
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/guido%40python.org



--
--Guido van Rossum (python.org/\~guido)