mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-19 20:24:27 +00:00
[ty] Dataclasses: __hash__ semantics and unsafe_hash (#21470)
Some checks are pending
CI / test scripts (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (${{ github.repository == 'astral-sh/ruff' && 'depot-windows-2022-16' || 'windows-latest' }}) (push) Blocked by required conditions
CI / cargo test (macos-latest) (push) Blocked by required conditions
CI / pre-commit (push) Waiting to run
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / ty completion evaluation (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks instrumented (ruff) (push) Blocked by required conditions
CI / benchmarks instrumented (ty) (push) Blocked by required conditions
CI / benchmarks walltime (medium|multithreaded) (push) Blocked by required conditions
CI / benchmarks walltime (small|large) (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
Some checks are pending
CI / test scripts (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (${{ github.repository == 'astral-sh/ruff' && 'depot-windows-2022-16' || 'windows-latest' }}) (push) Blocked by required conditions
CI / cargo test (macos-latest) (push) Blocked by required conditions
CI / pre-commit (push) Waiting to run
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / ty completion evaluation (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks instrumented (ruff) (push) Blocked by required conditions
CI / benchmarks instrumented (ty) (push) Blocked by required conditions
CI / benchmarks walltime (medium|multithreaded) (push) Blocked by required conditions
CI / benchmarks walltime (small|large) (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
## Summary Implement the semantics of `__hash__` for dataclasses and add support for `unsafe_hash` ## Test Plan New Markdown tests.
This commit is contained in:
parent
dbd72480a9
commit
f5fb5c388a
2 changed files with 86 additions and 2 deletions
|
|
@ -362,9 +362,71 @@ class AlreadyHasCustomDunderLt:
|
|||
return False
|
||||
```
|
||||
|
||||
### `unsafe_hash`
|
||||
### `__hash__` and `unsafe_hash`
|
||||
|
||||
To do
|
||||
If `eq` and `frozen` are both `True`, a `__hash__` method is generated by default:
|
||||
|
||||
```py
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass(eq=True, frozen=True)
|
||||
class WithHash:
|
||||
x: int
|
||||
|
||||
reveal_type(WithHash.__hash__) # revealed: (self: WithHash) -> int
|
||||
```
|
||||
|
||||
If `eq` is set to `True` and `frozen` is set to `False`, `__hash__` will be set to `None`, to mark
|
||||
is unhashable (because it is mutable):
|
||||
|
||||
```py
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass(eq=True, frozen=False)
|
||||
class WithoutHash:
|
||||
x: int
|
||||
|
||||
reveal_type(WithoutHash.__hash__) # revealed: None
|
||||
```
|
||||
|
||||
If `eq` is set to `False`, `__hash__` will inherit from the parent class (which could be `object`).
|
||||
Note that we see a revealed type of `def …` here, because `__hash__` refers to an actual function,
|
||||
not a synthetic method like in the first example.
|
||||
|
||||
```py
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
@dataclass(eq=False, frozen=False)
|
||||
class InheritHash:
|
||||
x: int
|
||||
|
||||
reveal_type(InheritHash.__hash__) # revealed: def __hash__(self) -> int
|
||||
|
||||
class Base:
|
||||
# Type the `self` parameter as `Any` to distinguish it from `object.__hash__`
|
||||
def __hash__(self: Any) -> int:
|
||||
return 42
|
||||
|
||||
@dataclass(eq=False, frozen=False)
|
||||
class InheritHash(Base):
|
||||
x: int
|
||||
|
||||
reveal_type(InheritHash.__hash__) # revealed: def __hash__(self: Any) -> int
|
||||
```
|
||||
|
||||
If `unsafe_hash` is set to `True`, a `__hash__` method will be generated even if the dataclass is
|
||||
mutable:
|
||||
|
||||
```py
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass(eq=True, frozen=False, unsafe_hash=True)
|
||||
class WithUnsafeHash:
|
||||
x: int
|
||||
|
||||
reveal_type(WithUnsafeHash.__hash__) # revealed: (self: WithUnsafeHash) -> int
|
||||
```
|
||||
|
||||
### `frozen`
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue