A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://mail.python.org/pipermail/python-dev/2018-February/152062.html below:

[Python-Dev] Dataclasses and correct hashability

[Python-Dev] Dataclasses and correct hashabilityEric V. Smith eric at trueblade.com
Fri Feb 2 10:51:11 EST 2018
On 2/2/2018 10:38 AM, Elvis Pranskevichus wrote:
> On Friday, February 2, 2018 10:08:43 AM EST Eric V. Smith wrote:
>> However, I don't feel very strongly about this. As I've said, I expect
>> the use cases for hash=True to be very, very rare.
> 
> Why do you think that the requirement to make a dataclass hashable is a
> "very, very rare" requirement?  The moment you want to use a dataclass a
> a dict key, or put it in a set, you need it to be hashable.

I was specifically talking about the case of a non-frozen, hashable 
class. If you want to make a class frozen and hashable, then:

@dataclass(frozen=True)

will do just that.

The case you brought up initially is the non-frozen, hashable class. 
It's that case that I think is very rare. I'll ask again: what's your 
use case for wanting a non-frozen, hashable class? I'm genuinely interested.

You seem to think that hash=True means "make the class hashable". That's 
not true. It means "add a __hash__" to this class". There are other, 
better ways to make the class hashable, specifically frozen=True. You 
might want to read all of https://bugs.python.org/issue32513 for the 
background on the current behavior.

> Just put yourself in the shoes of an average Python developer.  You try
> to put a dataclass in a set, you get a TypeError.  Your immediate
> reaction is to add "hash=True".  Things appear to work.  Then, you, or
> someone else, decides to mutate the dataclass object and then you are
> looking at a very frustrating debug session.

I will be documented that the correct way to do this is frozen=True.

>> In all, I think we're better off documenting best practices and making
>> them the default, like attrs does, and leave it to the programmer to
>> follow them. I realize we're handing out footguns
> 
> I don't think attrs doing the same thing is a valid justification.  This
> is a major footgun that is very easy to trigger, and there's really no
> precedent in standard data types.
> 
>> the alternatives seem even more complex and are limiting.
> 
> The alternative is simple and follows the design of other standard
> containers: immutable containers are hashable, mutable containers are
> not.  @dataclass(frozen=False) gives you a SimpleNamespace-like and
> @dataclass(frozen=True) gives you a namedtuple-like.  If you _really_
> know what you are doing, then you can always declare an explicit
> __hash__.

I'm not sure what you're arguing for here. This is how dataclasses work.

>> The problem with dropping hash=True is: how would you write __hash__
>> yourself?
> 
> Is "def __hash__(self): return hash((self.field1, self.field2))" that
> hard?  It is explicit, and you made a concious choice, i.e you
> understand how __hash__ works.

I didn't say it was hard, I said it needed to be kept up to date as you 
add fields. That is, you'd have to duplicate the field list. dataclasses 
is trying to prevent you from repeating the field list anywhere.

> IMO, the danger of
> "@dataclass(hash=True)" far overweighs whatever convenience it might
> provide.

We'll just have to disagree about this. As I said, I don't feel very 
strongly about it, but I lean toward leaving it in and documenting it 
for what it is and does.

Eric
More information about the Python-Dev mailing list

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4