On 29 January 2018 at 12:08, Guido van Rossum <gu...@python.org> wrote: > 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.
In Raymond's example, the problem is the opposite: data classes are currently interpreting "hash=False" as "Don't add a __hash__ implementation" rather than "Make this unhashable". That interpretation isn't equivalent due to object.__hash__ existing by default. (Reviewing Eric's table again, I believe this problem still exists in the 3.7b1 variant as well - I just missed it the first time I read that) I'd say the major argument in favour of Raymond's suggestion (i.e. always requiring an explicit "hash=True" in the dataclass decorator call if you want the result to be hashable) is that even if we *do* come up with a completely consistent derivation rule that the decorator can follow, most *readers* aren't going to know that rule. It would become a Python gotcha question for tech interviews: ============= Which of the following class definitions are hashable and what is their hash based on?: @dataclass class A: field: int @dataclass(eq=False) class B: field: int @dataclass(frozen=True) class C: field: int @dataclass(eq=False, frozen=True) class D: field: int @dataclass(eq=True, frozen=True) class E: field: int @dataclass(hash=True) class F: field: int @dataclass(frozen=True, hash=True) class G: field: int @dataclass(eq=True, frozen=True, hash=True) class H: field: int ============= Currently the answers are: - A: not hashable - B: hashable (by identity) # Wat? - C: hashable (by field hash) - D: hashable (by identity) # Wat? - E: hashable (by field hash) - F: hashable (by field hash) - G: hashable (by field hash) - H: hashable (by field hash) If we instead make the default "hash=False" (and interpret that as meaning "Inject __hash__=None"), then you end up with the following much simpler outcome that can be mapped directly to the decorator "hash" parameter: - A: not hashable - B: not hashable - C: not hashable - D: not hashable - E: not hashable - F: hashable (by field hash) - G: hashable (by field hash) - H: hashable (by field hash) Inheritance of __hash__ could then be made explicitly opt-in by way of a "dataclasses.INHERIT" constant. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ 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/archive%40mail-archive.com