@@ -362,9 +362,71 @@ class AlreadyHasCustomDunderLt:
362362 return False
363363```
364364
365- ### ` unsafe_hash `
365+ ### ` __hash__ ` and ` unsafe_hash `
366366
367- To do
367+ If ` eq ` and ` frozen ` are both ` True ` , a ` __hash__ ` method is generated by default:
368+
369+ ``` py
370+ from dataclasses import dataclass
371+
372+ @dataclass (eq = True , frozen = True )
373+ class WithHash :
374+ x: int
375+
376+ reveal_type(WithHash.__hash__ ) # revealed: (self: WithHash) -> int
377+ ```
378+
379+ If ` eq ` is set to ` True ` and ` frozen ` is set to ` False ` , ` __hash__ ` will be set to ` None ` , to mark
380+ is unhashable (because it is mutable):
381+
382+ ``` py
383+ from dataclasses import dataclass
384+
385+ @dataclass (eq = True , frozen = False )
386+ class WithoutHash :
387+ x: int
388+
389+ reveal_type(WithoutHash.__hash__ ) # revealed: None
390+ ```
391+
392+ If ` eq ` is set to ` False ` , ` __hash__ ` will inherit from the parent class (which could be ` object ` ).
393+ Note that we see a revealed type of ` def … ` here, because ` __hash__ ` refers to an actual function,
394+ not a synthetic method like in the first example.
395+
396+ ``` py
397+ from dataclasses import dataclass
398+ from typing import Any
399+
400+ @dataclass (eq = False , frozen = False )
401+ class InheritHash :
402+ x: int
403+
404+ reveal_type(InheritHash.__hash__ ) # revealed: def __hash__(self) -> int
405+
406+ class Base :
407+ # Type the `self` parameter as `Any` to distinguish it from `object.__hash__`
408+ def __hash__ (self : Any) -> int :
409+ return 42
410+
411+ @dataclass (eq = False , frozen = False )
412+ class InheritHash (Base ):
413+ x: int
414+
415+ reveal_type(InheritHash.__hash__ ) # revealed: def __hash__(self: Any) -> int
416+ ```
417+
418+ If ` unsafe_hash ` is set to ` True ` , a ` __hash__ ` method will be generated even if the dataclass is
419+ mutable:
420+
421+ ``` py
422+ from dataclasses import dataclass
423+
424+ @dataclass (eq = True , frozen = False , unsafe_hash = True )
425+ class WithUnsafeHash :
426+ x: int
427+
428+ reveal_type(WithUnsafeHash.__hash__ ) # revealed: (self: WithUnsafeHash) -> int
429+ ```
368430
369431### ` frozen `
370432
0 commit comments